diff options
author | Edward Hervey <edward.hervey@collabora.co.uk> | 2011-10-21 10:52:46 +0200 |
---|---|---|
committer | Edward Hervey <edward.hervey@collabora.co.uk> | 2011-10-21 10:52:46 +0200 |
commit | df6044f7ebdaf0c38217c95b7d9cc5340567d800 (patch) | |
tree | 0739ec3a69b104eed7aa97baa1cbc10ff7f5c769 | |
parent | 5800757369ae90b770cca3ca840c2c607b9b9f21 (diff) | |
parent | 905d1fea180dfa8c81486712689bba54639ef472 (diff) |
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
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | gst/gstbin.c | 3 | ||||
-rw-r--r-- | gst/gstbus.c | 13 | ||||
-rw-r--r-- | gst/gstdebugutils.c | 108 | ||||
-rw-r--r-- | gst/gstmessage.c | 7 | ||||
-rw-r--r-- | gst/gstpad.c | 40 | ||||
-rw-r--r-- | libs/gst/base/gstbaseparse.c | 149 | ||||
-rw-r--r-- | libs/gst/base/gstbaseparse.h | 13 | ||||
-rw-r--r-- | libs/gst/base/gstbasesink.c | 8 |
9 files changed, 255 insertions, 88 deletions
diff --git a/Android.mk b/Android.mk index d9868cab8..10b28a865 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/gst/gstbin.c b/gst/gstbin.c index 1168ee75b..815a33b88 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -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: diff --git a/gst/gstbus.c b/gst/gstbus.c index 00a361294..a1250511c 100644 --- a/gst/gstbus.c +++ b/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); diff --git a/gst/gstdebugutils.c b/gst/gstdebugutils.c index ce0647083..d70171904 100644 --- a/gst/gstdebugutils.c +++ b/gst/gstdebugutils.c @@ -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; diff --git a/gst/gstmessage.c b/gst/gstmessage.c index 41e7ccce5..7b481ac27 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -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); diff --git a/gst/gstpad.c b/gst/gstpad.c index 7f859549a..bee078d59 100644 --- a/gst/gstpad.c +++ b/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 */ diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 90407eae2..b9527e976 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -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) { diff --git a/libs/gst/base/gstbaseparse.h b/libs/gst/base/gstbaseparse.h index 655ad0e4a..72946a614 100644 --- a/libs/gst/base/gstbaseparse.h +++ b/libs/gst/base/gstbaseparse.h @@ -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); diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 1e5445a1e..75dabf90b 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -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; } |