mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
Merging origin/master
Conflicts: gst/gstbin.c gst/gstbus.c gst/gstdebugutils.c gst/gstpad.c libs/gst/base/gstbaseparse.c libs/gst/base/gstbasesrc.c
This commit is contained in:
commit
df6044f7eb
9 changed files with 255 additions and 88 deletions
|
@ -13,7 +13,7 @@ GST_BUILT_SOURCES := \
|
|||
gst/parse/grammar.tab.h \
|
||||
gst/parse/grammar.tab.c \
|
||||
gst/parse/grammar.output \
|
||||
gst/parse/lex._gst_parse_yy.c \
|
||||
gst/parse/lex.priv_gst_parse_yy.c \
|
||||
pkgconfig/gstreamer-0.10.pc \
|
||||
pkgconfig/gstreamer-base-0.10.pc \
|
||||
pkgconfig/gstreamer-controller-0.10.pc \
|
||||
|
|
|
@ -2689,7 +2689,8 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
|
|||
|
||||
gst_event_ref (event);
|
||||
res &= gst_element_send_event (child, event);
|
||||
g_value_reset (&data);
|
||||
GST_LOG_OBJECT (child, "After handling %s event: %d",
|
||||
GST_EVENT_TYPE_NAME (event), res);
|
||||
break;
|
||||
}
|
||||
case GST_ITERATOR_RESYNC:
|
||||
|
|
13
gst/gstbus.c
13
gst/gstbus.c
|
@ -481,8 +481,9 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
|
|||
while ((message = gst_atomic_queue_pop (bus->queue))) {
|
||||
if (bus->priv->poll)
|
||||
gst_poll_read_control (bus->priv->poll);
|
||||
GST_DEBUG_OBJECT (bus, "got message %p, %s, type mask is %u",
|
||||
message, GST_MESSAGE_TYPE_NAME (message), (guint) types);
|
||||
GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u",
|
||||
message, GST_MESSAGE_TYPE_NAME (message),
|
||||
GST_OBJECT_NAME (GST_MESSAGE_SRC (message)), (guint) types);
|
||||
if ((GST_MESSAGE_TYPE (message) & types) != 0) {
|
||||
/* exit the loop, we have a message */
|
||||
goto beach;
|
||||
|
@ -731,7 +732,8 @@ gst_bus_source_dispatch (GSource * source, GSourceFunc callback,
|
|||
if (!handler)
|
||||
goto no_handler;
|
||||
|
||||
GST_DEBUG_OBJECT (bus, "source %p calling dispatch with %p", source, message);
|
||||
GST_DEBUG_OBJECT (bus, "source %p calling dispatch with %" GST_PTR_FORMAT,
|
||||
source, message);
|
||||
|
||||
keep = handler (bus, message, user_data);
|
||||
gst_message_unref (message);
|
||||
|
@ -795,6 +797,11 @@ gst_bus_create_watch (GstBus * bus)
|
|||
|
||||
source = (GstBusSource *) g_source_new (&gst_bus_source_funcs,
|
||||
sizeof (GstBusSource));
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,26,0)
|
||||
g_source_set_name ((GSource *) source, "GStreamer message bus watch");
|
||||
#endif
|
||||
|
||||
source->bus = gst_object_ref (bus);
|
||||
g_source_add_poll ((GSource *) source, &bus->priv->pollfd);
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ const gchar spaces[] = {
|
|||
extern GstClockTime _priv_gst_info_start_time;
|
||||
|
||||
static gchar *
|
||||
debug_dump_make_object_name (GstObject * element)
|
||||
debug_dump_make_object_name (GstObject * obj)
|
||||
{
|
||||
return g_strcanon (g_strdup_printf ("%s_%p", GST_OBJECT_NAME (element),
|
||||
element), G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_", '_');
|
||||
return g_strcanon (g_strdup_printf ("%s_%p", GST_OBJECT_NAME (obj), obj),
|
||||
G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_", '_');
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -205,6 +205,9 @@ debug_dump_element_pad (GstPad * pad, GstElement * element,
|
|||
/* output target-pad so that it belongs to this element */
|
||||
if ((tmp_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)))) {
|
||||
if ((target_pad = gst_pad_get_peer (tmp_pad))) {
|
||||
gchar *pad_name, *target_pad_name;
|
||||
const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)];
|
||||
|
||||
if ((target_element = gst_pad_get_parent_element (target_pad))) {
|
||||
target_element_name =
|
||||
debug_dump_make_object_name (GST_OBJECT (target_element));
|
||||
|
@ -213,10 +216,22 @@ debug_dump_element_pad (GstPad * pad, GstElement * element,
|
|||
}
|
||||
debug_dump_pad (target_pad, color_name, target_element_name, details,
|
||||
out, indent);
|
||||
/* src ghostpad relationship */
|
||||
pad_name = debug_dump_make_object_name (GST_OBJECT (pad));
|
||||
target_pad_name = debug_dump_make_object_name (GST_OBJECT (target_pad));
|
||||
if (dir == GST_PAD_SRC) {
|
||||
fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc,
|
||||
target_element_name, target_pad_name, element_name, pad_name);
|
||||
} else {
|
||||
fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc,
|
||||
element_name, pad_name, target_element_name, target_pad_name);
|
||||
}
|
||||
g_free (target_pad_name);
|
||||
g_free (target_element_name);
|
||||
if (target_element)
|
||||
gst_object_unref (target_element);
|
||||
gst_object_unref (target_pad);
|
||||
g_free (pad_name);
|
||||
}
|
||||
gst_object_unref (tmp_pad);
|
||||
}
|
||||
|
@ -319,14 +334,13 @@ static void
|
|||
debug_dump_element_pad_link (GstPad * pad, GstElement * element,
|
||||
GstDebugGraphDetails details, FILE * out, const gint indent)
|
||||
{
|
||||
GstElement *peer_element, *target_element;
|
||||
GstPad *peer_pad, *target_pad, *tmp_pad;
|
||||
GstElement *peer_element;
|
||||
GstPad *peer_pad;
|
||||
GstCaps *caps, *peer_caps;
|
||||
gchar *media = NULL;
|
||||
gchar *media_src = NULL, *media_sink = NULL;
|
||||
gchar *pad_name, *element_name;
|
||||
gchar *peer_pad_name, *peer_element_name;
|
||||
gchar *target_pad_name, *target_element_name;
|
||||
const gchar *spc = &spaces[MAX (sizeof (spaces) - (1 + indent * 2), 0)];
|
||||
|
||||
if ((peer_pad = gst_pad_get_peer (pad))) {
|
||||
|
@ -373,63 +387,6 @@ debug_dump_element_pad_link (GstPad * pad, GstElement * element,
|
|||
peer_element_name = g_strdup ("");
|
||||
}
|
||||
|
||||
if (GST_IS_GHOST_PAD (pad)) {
|
||||
if ((tmp_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (pad)))) {
|
||||
if ((target_pad = gst_pad_get_peer (tmp_pad))) {
|
||||
target_pad_name =
|
||||
debug_dump_make_object_name (GST_OBJECT (target_pad));
|
||||
if ((target_element = gst_pad_get_parent_element (target_pad))) {
|
||||
target_element_name =
|
||||
debug_dump_make_object_name (GST_OBJECT (target_element));
|
||||
} else {
|
||||
target_element_name = g_strdup ("");
|
||||
}
|
||||
/* src ghostpad relationship */
|
||||
fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc,
|
||||
target_element_name, target_pad_name, element_name, pad_name);
|
||||
|
||||
g_free (target_pad_name);
|
||||
g_free (target_element_name);
|
||||
if (target_element)
|
||||
gst_object_unref (target_element);
|
||||
gst_object_unref (target_pad);
|
||||
}
|
||||
gst_object_unref (tmp_pad);
|
||||
}
|
||||
}
|
||||
if (GST_IS_GHOST_PAD (peer_pad)) {
|
||||
if ((tmp_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (peer_pad)))) {
|
||||
if ((target_pad = gst_pad_get_peer (tmp_pad))) {
|
||||
target_pad_name =
|
||||
debug_dump_make_object_name (GST_OBJECT (target_pad));
|
||||
if ((target_element = gst_pad_get_parent_element (target_pad))) {
|
||||
target_element_name =
|
||||
debug_dump_make_object_name (GST_OBJECT (target_element));
|
||||
} else {
|
||||
target_element_name = g_strdup ("");
|
||||
}
|
||||
/* sink ghostpad relationship */
|
||||
fprintf (out, "%s%s_%s -> %s_%s [style=dashed, minlen=0]\n", spc,
|
||||
peer_element_name, peer_pad_name,
|
||||
target_element_name, target_pad_name);
|
||||
/* FIXME: we are missing links from the proxy pad
|
||||
* theoretically we need to:
|
||||
* pad=gst_object_ref(target_pad);
|
||||
* goto line 280: if ((peer_pad = gst_pad_get_peer (pad)))
|
||||
* as this would be ugly we need to refactor ...
|
||||
*/
|
||||
debug_dump_element_pad_link (target_pad, target_element, details, out,
|
||||
indent);
|
||||
g_free (target_pad_name);
|
||||
g_free (target_element_name);
|
||||
if (target_element)
|
||||
gst_object_unref (target_element);
|
||||
gst_object_unref (target_pad);
|
||||
}
|
||||
gst_object_unref (tmp_pad);
|
||||
}
|
||||
}
|
||||
|
||||
/* pad link */
|
||||
if (media) {
|
||||
fprintf (out, "%s%s_%s -> %s_%s [label=\"%s\"]\n", spc,
|
||||
|
@ -583,10 +540,22 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
|
|||
switch (gst_iterator_next (pad_iter, &item2)) {
|
||||
case GST_ITERATOR_OK:
|
||||
pad = g_value_get_object (&item2);
|
||||
if (gst_pad_is_linked (pad)
|
||||
&& gst_pad_get_direction (pad) == GST_PAD_SRC) {
|
||||
debug_dump_element_pad_link (pad, element, details, out,
|
||||
indent);
|
||||
if (gst_pad_is_linked (pad)) {
|
||||
if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
|
||||
debug_dump_element_pad_link (pad, element, details, out,
|
||||
indent);
|
||||
} else {
|
||||
GstPad *peer_pad = gst_pad_get_peer (pad);
|
||||
|
||||
if (peer_pad) {
|
||||
if (!GST_IS_GHOST_PAD (peer_pad)
|
||||
&& GST_IS_PROXY_PAD (peer_pad)) {
|
||||
debug_dump_element_pad_link (peer_pad, NULL, details,
|
||||
out, indent);
|
||||
}
|
||||
gst_object_unref (peer_pad);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_value_reset (&item2);
|
||||
break;
|
||||
|
@ -613,6 +582,7 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_value_unset (&item);
|
||||
gst_iterator_free (element_iter);
|
||||
}
|
||||
|
@ -703,8 +673,8 @@ _gst_debug_bin_to_dot_file (GstBin * bin, GstDebugGraphDetails details,
|
|||
* to the filename, so that it can be used to take multiple snapshots.
|
||||
*/
|
||||
void
|
||||
_gst_debug_bin_to_dot_file_with_ts (GstBin * bin, GstDebugGraphDetails details,
|
||||
const gchar * file_name)
|
||||
_gst_debug_bin_to_dot_file_with_ts (GstBin * bin,
|
||||
GstDebugGraphDetails details, const gchar * file_name)
|
||||
{
|
||||
gchar *ts_file_name = NULL;
|
||||
GstClockTime elapsed;
|
||||
|
|
|
@ -177,7 +177,8 @@ _gst_message_free (GstMessage * message)
|
|||
|
||||
g_return_if_fail (message != NULL);
|
||||
|
||||
GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p", message);
|
||||
GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p, %s from %s", message,
|
||||
GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message));
|
||||
|
||||
if (GST_MESSAGE_SRC (message)) {
|
||||
gst_object_unref (GST_MESSAGE_SRC (message));
|
||||
|
@ -205,7 +206,9 @@ _gst_message_copy (GstMessage * message)
|
|||
GstMessageImpl *copy;
|
||||
GstStructure *structure;
|
||||
|
||||
GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p", message);
|
||||
GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p, %s from %s", message,
|
||||
GST_MESSAGE_TYPE_NAME (message),
|
||||
GST_OBJECT_NAME (GST_MESSAGE_SRC (message)));
|
||||
|
||||
copy = g_slice_new0 (GstMessageImpl);
|
||||
|
||||
|
|
40
gst/gstpad.c
40
gst/gstpad.c
|
@ -1065,6 +1065,19 @@ gst_pad_add_probe (GstPad * pad, GstProbeType mask,
|
|||
g_return_val_if_fail (mask != 0, 0);
|
||||
|
||||
GST_OBJECT_LOCK (pad);
|
||||
|
||||
/* FIXME : I'm not checking for != GST_ACTIVATE_correct_direction
|
||||
* because the pad might not be activated yet.
|
||||
* This means that _add_probe() might return a valid probeid ...
|
||||
* which will potentially never be called if the pad
|
||||
* is activated in the wrong direction */
|
||||
if (G_UNLIKELY ((mask & GST_PROBE_TYPE_PUSH) &&
|
||||
(GST_PAD_ACTIVATE_MODE (pad) == GST_ACTIVATE_PULL)))
|
||||
goto wrong_direction;
|
||||
if (G_UNLIKELY ((mask & GST_PROBE_TYPE_PULL) &&
|
||||
(GST_PAD_ACTIVATE_MODE (pad) == GST_ACTIVATE_PUSH)))
|
||||
goto wrong_direction;
|
||||
|
||||
/* make a new probe */
|
||||
hook = g_hook_alloc (&pad->probes);
|
||||
|
||||
|
@ -1127,6 +1140,15 @@ gst_pad_add_probe (GstPad * pad, GstProbeType mask,
|
|||
GST_OBJECT_UNLOCK (pad);
|
||||
}
|
||||
return res;
|
||||
|
||||
wrong_direction:
|
||||
{
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pad block on the wrong pad, "
|
||||
"block src pads in push mode and sink pads in pull mode.");
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4221,10 +4243,11 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
|
|||
|
||||
/* Remove sticky EOS events */
|
||||
GST_LOG_OBJECT (pad, "Removing pending EOS events");
|
||||
gst_event_replace (&pad->priv->
|
||||
events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].pending, NULL);
|
||||
gst_event_replace (&pad->priv->
|
||||
events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].event, NULL);
|
||||
gst_event_replace (&pad->
|
||||
priv->events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].pending,
|
||||
NULL);
|
||||
gst_event_replace (&pad->
|
||||
priv->events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].event, NULL);
|
||||
|
||||
if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
|
||||
GST_LOG_OBJECT (pad, "Pad is blocked, not forwarding flush-stop");
|
||||
|
@ -4432,10 +4455,11 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
|
|||
}
|
||||
/* Remove pending EOS events */
|
||||
GST_LOG_OBJECT (pad, "Removing pending EOS events");
|
||||
gst_event_replace (&pad->priv->
|
||||
events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].pending, NULL);
|
||||
gst_event_replace (&pad->priv->
|
||||
events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].event, NULL);
|
||||
gst_event_replace (&pad->
|
||||
priv->events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].pending,
|
||||
NULL);
|
||||
gst_event_replace (&pad->
|
||||
priv->events[GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_EOS)].event, NULL);
|
||||
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
/* grab stream lock */
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* Copyright (C) 2008 Nokia Corporation. All rights reserved.
|
||||
* Contact: Stefan Kost <stefan.kost@nokia.com>
|
||||
* Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
|
||||
* Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
|
||||
* Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -315,6 +317,12 @@ struct _GstBaseParsePrivate
|
|||
|
||||
/* push mode helper frame */
|
||||
GstBaseParseFrame frame;
|
||||
|
||||
/* TRUE if we're still detecting the format, i.e.
|
||||
* if ::detect() is still called for future buffers */
|
||||
gboolean detecting;
|
||||
GList *detect_buffers;
|
||||
guint detect_buffers_size;
|
||||
};
|
||||
|
||||
typedef struct _GstBaseParseSeek
|
||||
|
@ -378,6 +386,7 @@ static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
|
|||
static gboolean gst_base_parse_src_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_base_parse_sink_event (GstPad * pad, GstEvent * event);
|
||||
static gboolean gst_base_parse_query (GstPad * pad, GstQuery * query);
|
||||
static GstCaps *gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter);
|
||||
static const GstQueryType *gst_base_parse_get_querytypes (GstPad * pad);
|
||||
|
||||
static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstBuffer * buffer);
|
||||
|
@ -422,6 +431,11 @@ gst_base_parse_clear_queues (GstBaseParse * parse)
|
|||
g_slist_foreach (parse->priv->buffers_send, (GFunc) gst_buffer_unref, NULL);
|
||||
g_slist_free (parse->priv->buffers_send);
|
||||
parse->priv->buffers_send = NULL;
|
||||
|
||||
g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref, NULL);
|
||||
g_list_free (parse->priv->detect_buffers);
|
||||
parse->priv->detect_buffers = NULL;
|
||||
parse->priv->detect_buffers_size = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -509,6 +523,8 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
|
|||
parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
gst_pad_set_event_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
|
||||
gst_pad_set_getcaps_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_sink_getcaps));
|
||||
gst_pad_set_chain_function (parse->sinkpad,
|
||||
GST_DEBUG_FUNCPTR (gst_base_parse_chain));
|
||||
gst_pad_set_activate_function (parse->sinkpad,
|
||||
|
@ -735,6 +751,11 @@ gst_base_parse_reset (GstBaseParse * parse)
|
|||
parse->priv->frame._private_flags |=
|
||||
GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC;
|
||||
gst_base_parse_frame_free (&parse->priv->frame);
|
||||
|
||||
g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref, NULL);
|
||||
g_list_free (parse->priv->detect_buffers);
|
||||
parse->priv->detect_buffers = NULL;
|
||||
parse->priv->detect_buffers_size = 0;
|
||||
GST_OBJECT_UNLOCK (parse);
|
||||
}
|
||||
|
||||
|
@ -1739,7 +1760,6 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
|
|||
|
||||
while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
|
||||
gst_base_parse_push_frame (parse, queued_frame);
|
||||
gst_base_parse_frame_free (queued_frame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2204,6 +2224,82 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
parse = GST_BASE_PARSE (GST_OBJECT_PARENT (pad));
|
||||
bclass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||
|
||||
if (parse->priv->detecting) {
|
||||
GstBuffer *detect_buf;
|
||||
|
||||
if (parse->priv->detect_buffers_size == 0) {
|
||||
detect_buf = gst_buffer_ref (buffer);
|
||||
} else {
|
||||
GList *l;
|
||||
guint offset = 0;
|
||||
|
||||
detect_buf = gst_buffer_new ();
|
||||
|
||||
for (l = parse->priv->detect_buffers; l; l = l->next) {
|
||||
gsize tmpsize = gst_buffer_get_size (l->data);
|
||||
|
||||
gst_buffer_copy_into (detect_buf, GST_BUFFER_CAST (l->data),
|
||||
GST_BUFFER_COPY_MEMORY, offset, tmpsize);
|
||||
offset += tmpsize;
|
||||
}
|
||||
if (buffer)
|
||||
gst_buffer_copy_into (detect_buf, buffer, GST_BUFFER_COPY_MEMORY,
|
||||
offset, gst_buffer_get_size (buffer));
|
||||
}
|
||||
|
||||
ret = bclass->detect (parse, detect_buf);
|
||||
gst_buffer_unref (detect_buf);
|
||||
|
||||
if (ret == GST_FLOW_OK) {
|
||||
GList *l;
|
||||
|
||||
/* Detected something */
|
||||
parse->priv->detecting = FALSE;
|
||||
|
||||
for (l = parse->priv->detect_buffers; l; l = l->next) {
|
||||
if (ret == GST_FLOW_OK && !parse->priv->flushing)
|
||||
ret =
|
||||
gst_base_parse_chain (GST_BASE_PARSE_SINK_PAD (parse),
|
||||
GST_BUFFER_CAST (l->data));
|
||||
else
|
||||
gst_buffer_unref (GST_BUFFER_CAST (l->data));
|
||||
}
|
||||
g_list_free (parse->priv->detect_buffers);
|
||||
parse->priv->detect_buffers = NULL;
|
||||
parse->priv->detect_buffers_size = 0;
|
||||
|
||||
if (ret != GST_FLOW_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Handle the current buffer */
|
||||
} else if (ret == GST_FLOW_NOT_NEGOTIATED) {
|
||||
/* Still detecting, append buffer or error out if draining */
|
||||
|
||||
if (parse->priv->drain) {
|
||||
GST_DEBUG_OBJECT (parse, "Draining but did not detect format yet");
|
||||
return GST_FLOW_ERROR;
|
||||
} else if (parse->priv->flushing) {
|
||||
g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref,
|
||||
NULL);
|
||||
g_list_free (parse->priv->detect_buffers);
|
||||
parse->priv->detect_buffers = NULL;
|
||||
parse->priv->detect_buffers_size = 0;
|
||||
} else {
|
||||
parse->priv->detect_buffers =
|
||||
g_list_append (parse->priv->detect_buffers, buffer);
|
||||
parse->priv->detect_buffers_size += gst_buffer_get_size (buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
} else {
|
||||
/* Something went wrong, subclass responsible for error reporting */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* And now handle the current buffer if detection worked */
|
||||
}
|
||||
|
||||
frame = &parse->priv->frame;
|
||||
|
||||
if (G_LIKELY (buffer)) {
|
||||
|
@ -2584,6 +2680,30 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
|
|||
if (gst_buffer_get_size (buffer) < min_size)
|
||||
parse->priv->drain = TRUE;
|
||||
|
||||
if (parse->priv->detecting) {
|
||||
ret = klass->detect (parse, buffer);
|
||||
if (ret == GST_FLOW_NOT_NEGOTIATED) {
|
||||
/* If draining we error out, otherwise request a buffer
|
||||
* with 64kb more */
|
||||
if (parse->priv->drain) {
|
||||
gst_buffer_unref (buffer);
|
||||
GST_ERROR_OBJECT (parse, "Failed to detect format but draining");
|
||||
return GST_FLOW_ERROR;
|
||||
} else {
|
||||
fsize += 64 * 1024;
|
||||
gst_buffer_unref (buffer);
|
||||
continue;
|
||||
}
|
||||
} else if (ret != GST_FLOW_OK) {
|
||||
gst_buffer_unref (buffer);
|
||||
GST_ERROR_OBJECT (parse, "detect() returned %s",
|
||||
gst_flow_get_name (ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Else handle this buffer normally */
|
||||
}
|
||||
|
||||
skip = -1;
|
||||
gst_base_parse_frame_update (parse, frame, buffer);
|
||||
res = klass->check_valid_frame (parse, frame, &fsize, &skip);
|
||||
|
@ -2821,6 +2941,10 @@ gst_base_parse_activate (GstBaseParse * parse, gboolean active)
|
|||
if (active) {
|
||||
if (parse->priv->pad_mode == GST_ACTIVATE_NONE && klass->start)
|
||||
result = klass->start (parse);
|
||||
|
||||
/* If the subclass implements ::detect we want to
|
||||
* call it for the first buffers now */
|
||||
parse->priv->detecting = (klass->detect != NULL);
|
||||
} else {
|
||||
/* We must make sure streaming has finished before resetting things
|
||||
* and calling the ::stop vfunc */
|
||||
|
@ -3842,6 +3966,29 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
|
|||
}
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
gst_base_parse_sink_getcaps (GstPad * pad, GstCaps * filter)
|
||||
{
|
||||
GstBaseParse *parse;
|
||||
GstBaseParseClass *klass;
|
||||
GstCaps *caps;
|
||||
|
||||
parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
|
||||
klass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||
g_assert (pad == GST_BASE_PARSE_SINK_PAD (parse));
|
||||
|
||||
if (klass->get_sink_caps)
|
||||
caps = klass->get_sink_caps (parse, filter);
|
||||
else
|
||||
caps = gst_pad_proxy_getcaps (pad, filter);
|
||||
gst_object_unref (parse);
|
||||
|
||||
GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
return caps;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gst_base_parse_set_index (GstElement * element, GstIndex * index)
|
||||
{
|
||||
|
|
|
@ -191,6 +191,7 @@ struct _GstBaseParse {
|
|||
* Called when the element stops processing.
|
||||
* Allows closing external resources.
|
||||
* @set_sink_caps: allows the subclass to be notified of the actual caps set.
|
||||
* @get_sink_caps: allows the subclass to do its own sink get caps if needed.
|
||||
* @check_valid_frame: Check if the given piece of data contains a valid
|
||||
* frame.
|
||||
* @parse_frame: Parse the already checked frame. Subclass need to
|
||||
|
@ -211,6 +212,10 @@ struct _GstBaseParse {
|
|||
* additional actions at this time (e.g. tag sending) or to
|
||||
* decide whether this buffer should be dropped or not
|
||||
* (e.g. custom segment clipping).
|
||||
* @detect: Optional.
|
||||
* Called until it doesn't return GST_FLOW_OK anymore for
|
||||
* the first buffers. Can be used by the subclass to detect
|
||||
* the stream format. Since: 0.10.36
|
||||
*
|
||||
* Subclasses can override any of the available virtual methods or not, as
|
||||
* needed. At minimum @check_valid_frame and @parse_frame needs to be
|
||||
|
@ -252,8 +257,14 @@ struct _GstBaseParseClass {
|
|||
gboolean (*src_event) (GstBaseParse * parse,
|
||||
GstEvent * event);
|
||||
|
||||
GstCaps * (*get_sink_caps) (GstBaseParse * parse,
|
||||
GstCaps * filter);
|
||||
|
||||
GstFlowReturn (*detect) (GstBaseParse * parse,
|
||||
GstBuffer * buffer);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE];
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE - 2];
|
||||
};
|
||||
|
||||
GType gst_base_parse_get_type (void);
|
||||
|
|
|
@ -2057,8 +2057,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
|
|||
/* FIXME: Casting to GstClockEntry only works because the types
|
||||
* are the same */
|
||||
if (G_LIKELY (sink->priv->cached_clock_id != NULL
|
||||
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->
|
||||
priv->cached_clock_id) == clock)) {
|
||||
&& GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
|
||||
cached_clock_id) == clock)) {
|
||||
if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
|
||||
time)) {
|
||||
gst_clock_id_unref (sink->priv->cached_clock_id);
|
||||
|
@ -4431,6 +4431,10 @@ gst_base_sink_send_event (GstElement * element, GstEvent * event)
|
|||
}
|
||||
|
||||
gst_object_unref (pad);
|
||||
|
||||
GST_DEBUG_OBJECT (basesink, "handled event %p %" GST_PTR_FORMAT ": %d", event,
|
||||
event, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue