diff -r 71e347f905f2 -r 4a7fac7dd34a gst_plugins_base/gst-libs/gst/tag/gsttagdemux.c --- a/gst_plugins_base/gst-libs/gst/tag/gsttagdemux.c Fri Mar 19 09:35:09 2010 +0200 +++ b/gst_plugins_base/gst-libs/gst/tag/gsttagdemux.c Fri Apr 16 15:15:52 2010 +0300 @@ -75,11 +75,7 @@ #include "gsttagdemux.h" #include -#ifndef __SYMBIAN32__ #include -#else -#include "gst/gst-i18n-plugin.h" -#endif #include typedef enum @@ -115,6 +111,8 @@ GstSegment segment; gboolean need_newseg; gboolean newseg_update; + + GList *pending_events; }; /* Require at least 8kB of data before we attempt typefind. @@ -166,6 +164,27 @@ static void gst_tag_demux_init (GstTagDemux * obj, GstTagDemuxClass * klass); static gpointer parent_class; /* NULL */ +#ifdef __SYMBIAN32__ +EXPORT_C +#endif + + +GType +gst_tag_demux_result_get_type (void) +{ + static GType etype = 0; + if (etype == 0) { + static const GEnumValue values[] = { + {GST_TAG_DEMUX_RESULT_BROKEN_TAG, "GST_TAG_DEMUX_RESULT_BROKEN_TAG", + "broken-tag"}, + {GST_TAG_DEMUX_RESULT_AGAIN, "GST_TAG_DEMUX_RESULT_AGAIN", "again"}, + {GST_TAG_DEMUX_RESULT_OK, "GST_TAG_DEMUX_RESULT_OK", "ok"}, + {0, NULL, NULL} + }; + etype = g_enum_register_static ("GstTagDemuxResult", values); + } + return etype; +} /* Cannot use boilerplate macros here because we want the abstract flag */ #ifdef __SYMBIAN32__ @@ -258,6 +277,11 @@ gst_segment_init (&tagdemux->priv->segment, GST_FORMAT_UNDEFINED); tagdemux->priv->need_newseg = TRUE; tagdemux->priv->newseg_update = FALSE; + + g_list_foreach (tagdemux->priv->pending_events, + (GFunc) gst_mini_object_unref, NULL); + g_list_free (tagdemux->priv->pending_events); + tagdemux->priv->pending_events = NULL; } static void @@ -423,8 +447,6 @@ need_sub = TRUE; } - g_assert (out_size > 0); - if (need_sub == TRUE) { if (out_size != GST_BUFFER_SIZE (buf) || !gst_buffer_is_writable (buf)) { GstBuffer *sub; @@ -656,6 +678,8 @@ return GST_FLOW_UNEXPECTED; } if (outbuf) { + GList *events; + if (G_UNLIKELY (demux->priv->srcpad == NULL)) { gst_buffer_unref (outbuf); return GST_FLOW_ERROR; @@ -670,7 +694,20 @@ demux->priv->need_newseg = FALSE; } - /* Send pending tag event */ + /* send any pending events we cached */ + GST_OBJECT_LOCK (demux); + events = demux->priv->pending_events; + demux->priv->pending_events = NULL; + GST_OBJECT_UNLOCK (demux); + + while (events != NULL) { + GST_DEBUG_OBJECT (demux->priv->srcpad, "sending cached %s event: %" + GST_PTR_FORMAT, GST_EVENT_TYPE_NAME (events->data), events->data); + gst_pad_push_event (demux->priv->srcpad, GST_EVENT (events->data)); + events = g_list_delete_link (events, events); + } + + /* Send our own pending tag event */ if (demux->priv->send_tag_event) { gst_tag_demux_send_tag_event (demux); demux->priv->send_tag_event = FALSE; @@ -728,7 +765,18 @@ break; } default: - ret = gst_pad_event_default (pad, event); + if (demux->priv->need_newseg) { + /* Cache all events if we have a pending segment, so they don't get + * lost (esp. tag events) */ + GST_INFO_OBJECT (demux, "caching event: %" GST_PTR_FORMAT, event); + GST_OBJECT_LOCK (demux); + demux->priv->pending_events = + g_list_append (demux->priv->pending_events, event); + GST_OBJECT_UNLOCK (demux); + ret = TRUE; + } else { + ret = gst_pad_event_default (pad, event); + } break; } @@ -829,12 +877,14 @@ break; } default: - /* FIXME: shouldn't we pass unknown and unhandled events upstream? */ + res = gst_pad_push_event (tagdemux->priv->sinkpad, event); + event = NULL; break; } gst_object_unref (tagdemux); - gst_event_unref (event); + if (event) + gst_event_unref (event); return res; } @@ -1159,6 +1209,13 @@ demux->priv->send_tag_event = TRUE; } + if (demux->priv->upstream_size <= + demux->priv->strip_start + demux->priv->strip_end) { + /* There was no data (probably due to a truncated file) */ + GST_DEBUG_OBJECT (demux, "No data in file"); + return FALSE; + } + /* 3 - Do typefinding on data */ caps = gst_type_find_helper_get_range (GST_OBJECT (demux), (GstTypeFindHelperGetRangeFunction) gst_tag_demux_read_range, @@ -1269,7 +1326,7 @@ { GST_DEBUG_OBJECT (demux, "attempted read beyond end of file"); if (*buffer != NULL) { - gst_buffer_unref (buffer); + gst_buffer_unref (*buffer); *buffer = NULL; } return GST_FLOW_UNEXPECTED;