diff options
author | Vincent Penquerc'h <vincent.penquerch@collabora.co.uk> | 2010-12-23 18:18:50 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim.muller@collabora.co.uk> | 2010-12-26 21:47:53 +0000 |
commit | 857e3dda46bc7c6e3ca6dd4b2f1413f517219f7c (patch) | |
tree | 22a27057d2e717e778a6603e337424621bcaac6c /ext | |
parent | 18e69fb72e27a81012041fe70c6b2bf2f028510c (diff) | |
download | gstreamer-plugins-bad-857e3dda46bc7c6e3ca6dd4b2f1413f517219f7c.tar.gz |
tiger: fallback on headers in caps to initialize if headers are absent
When Totem switches streams, tiger will be reset, and start receiving
buffers from the middle of the stream, without being sent headers.
If this happens, try to get headers from the caps.
https://bugzilla.gnome.org/show_bug.cgi?id=638004
Diffstat (limited to 'ext')
-rw-r--r-- | ext/kate/gstkatetiger.c | 47 | ||||
-rw-r--r-- | ext/kate/gstkatetiger.h | 1 |
2 files changed, 48 insertions, 0 deletions
diff --git a/ext/kate/gstkatetiger.c b/ext/kate/gstkatetiger.c index d5a2faf3a..67d046aaa 100644 --- a/ext/kate/gstkatetiger.c +++ b/ext/kate/gstkatetiger.c @@ -355,6 +355,8 @@ gst_kate_tiger_init (GstKateTiger * tiger, GstKateTigerClass * gclass) tiger->video_width = 0; tiger->video_height = 0; + + tiger->seen_header = FALSE; } static void @@ -565,6 +567,50 @@ gst_kate_tiger_kate_chain (GstPad * pad, GstBuffer * buf) GST_LOG_OBJECT (tiger, "Got kate buffer, caps %s", gst_caps_to_string (GST_BUFFER_CAPS (buf))); + /* Unfortunately, it can happen that the start of the stream is not sent, + for instance if there's a stream selector upstream, which is switched + from another Kate stream. If this happens, then we can fallback on the + headers stored in the caps (if any). */ + if (!tiger->seen_header) { + if (GST_BUFFER_SIZE (buf) == 0 || (GST_BUFFER_DATA (buf)[0] & 0x80) == 0) { + /* Not a header, try to fall back on caps */ + GstStructure *s; + const GValue *streamheader; + + GST_INFO_OBJECT (tiger, "Headers not seen, start of stream is cut off"); + s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); + streamheader = gst_structure_get_value (s, "streamheader"); + if (streamheader && G_VALUE_TYPE (streamheader) == GST_TYPE_ARRAY) { + GstPad *tagpad = gst_pad_get_peer (pad); + GArray *array; + gint i; + + GST_INFO_OBJECT (tiger, "Falling back on caps to initialize decoder"); + array = g_value_peek_pointer (streamheader); + for (i = 0; i < array->len; i++) { + GValue *value = &g_array_index (array, GValue, i); + if (G_VALUE_TYPE (value) == GST_TYPE_BUFFER) { + GstBuffer *hbuf = g_value_peek_pointer (value); + gst_buffer_ref (hbuf); + rflow = + gst_kate_util_decoder_base_chain_kate_packet (&tiger->decoder, + GST_ELEMENT_CAST (tiger), pad, hbuf, tiger->srcpad, tagpad, + NULL, NULL); + } else { + GST_WARNING_OBJECT (tiger, + "Streamheader index %d does not hold a buffer", i); + } + } + gst_object_unref (tagpad); + tiger->seen_header = TRUE; + } else { + GST_WARNING_OBJECT (tiger, "No headers seen, and no headers on caps"); + } + } else { + tiger->seen_header = TRUE; + } + } + if (gst_kate_util_decoder_base_update_segment (&tiger->decoder, GST_ELEMENT_CAST (tiger), buf)) { GstPad *tagpad = gst_pad_get_peer (pad); @@ -750,6 +796,7 @@ gst_kate_tiger_change_state (GstElement * element, GstStateChange transition) } gst_segment_init (&tiger->video_segment, GST_FORMAT_UNDEFINED); tiger->video_flushing = FALSE; + tiger->seen_header = FALSE; GST_KATE_TIGER_MUTEX_UNLOCK (tiger); break; default: diff --git a/ext/kate/gstkatetiger.h b/ext/kate/gstkatetiger.h index 353f9f79e..48884b1c2 100644 --- a/ext/kate/gstkatetiger.h +++ b/ext/kate/gstkatetiger.h @@ -97,6 +97,7 @@ struct _GstKateTiger GstSegment video_segment; gboolean video_flushing; + gboolean seen_header; }; struct _GstKateTigerClass |