flvdemux: If there's no audio stream after 6 seconds of video signal no-more-pads
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 2 Oct 2009 12:37:54 +0000 (14:37 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Sat, 3 Oct 2009 10:21:34 +0000 (12:21 +0200)
...and the other way around. Also ignore any audio/video streams that appear
after no-more-pads.

Fixes bug #597091.

gst/flv/gstflvdemux.c
gst/flv/gstflvdemux.h
gst/flv/gstflvparse.c

index 37dd614b6246b68141c2a8beb51572bd0b51f8e5..4492d30bea6a82fee8085d3930364de43e5139e6 100644 (file)
@@ -112,6 +112,8 @@ gst_flv_demux_cleanup (GstFLVDemux * demux)
   demux->push_tags = FALSE;
   demux->got_par = FALSE;
 
+  demux->audio_start = demux->video_start = GST_CLOCK_TIME_NONE;
+
   demux->no_more_pads = FALSE;
 
   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
index 806ab1365df7515d26d77836954269250f6182d4..6c130d0552d7580363c1fa68a3696c19cf07dcf6 100644 (file)
@@ -93,6 +93,7 @@ struct _GstFLVDemux
   gboolean audio_need_segment;
   gboolean audio_linked;
   GstBuffer * audio_codec_data;
+  GstClockTime audio_start;
 
   /* Video infos */
   guint32 w;
@@ -106,6 +107,7 @@ struct _GstFLVDemux
   gboolean video_linked;
   gboolean got_par;
   GstBuffer * video_codec_data;
+  GstClockTime video_start;
 
   gboolean random_access;
   gboolean need_header;
index 21772daf68b2b3d26217bf398811272d475556ef..a6d18b72e69e9fb4d2cc6d77cca0561620ca87b8 100644 (file)
@@ -553,6 +553,12 @@ gst_flv_parse_tag_audio (GstFLVDemux * demux, GstBuffer * buffer)
 
   GST_LOG_OBJECT (demux, "parsing an audio tag");
 
+  if (demux->no_more_pads && !demux->audio_pad) {
+    GST_WARNING_OBJECT (demux,
+        "Signaled no-more-pads already but had no audio pad -- ignoring");
+    goto beach;
+  }
+
   g_return_val_if_fail (GST_BUFFER_SIZE (buffer) == demux->tag_size,
       GST_FLOW_ERROR);
 
@@ -784,6 +790,20 @@ gst_flv_parse_tag_audio (GstFLVDemux * demux, GstBuffer * buffer)
       GST_BUFFER_SIZE (outbuf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf));
 
+  if (!GST_CLOCK_TIME_IS_VALID (demux->audio_start)) {
+    demux->audio_start = GST_BUFFER_TIMESTAMP (outbuf);
+  }
+
+  if (G_UNLIKELY (!demux->no_more_pads
+          && GST_CLOCK_DIFF (demux->audio_start,
+              GST_BUFFER_TIMESTAMP (outbuf) > 6 * GST_SECOND))) {
+    GST_DEBUG_OBJECT (demux,
+        "Signalling no-more-pads because no video stream was found"
+        " after 6 seconds of audio");
+    gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
+    demux->no_more_pads = TRUE;
+  }
+
   /* Push downstream */
   ret = gst_pad_push (demux->audio_pad, outbuf);
   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
@@ -889,9 +909,16 @@ gst_flv_parse_tag_video (GstFLVDemux * demux, GstBuffer * buffer)
 
   GST_LOG_OBJECT (demux, "parsing a video tag");
 
+
   GST_LOG_OBJECT (demux, "pts bytes %02X %02X %02X %02X", data[0], data[1],
       data[2], data[3]);
 
+  if (demux->no_more_pads && !demux->video_pad) {
+    GST_WARNING_OBJECT (demux,
+        "Signaled no-more-pads already but had no audio pad -- ignoring");
+    goto beach;
+  }
+
   /* Grab information about video tag */
   pts = GST_READ_UINT24_BE (data);
   /* read the pts extension to 32 bits integer */
@@ -1114,6 +1141,20 @@ gst_flv_parse_tag_video (GstFLVDemux * demux, GstBuffer * buffer)
       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)), GST_BUFFER_OFFSET (outbuf),
       keyframe);
 
+  if (!GST_CLOCK_TIME_IS_VALID (demux->video_start)) {
+    demux->video_start = GST_BUFFER_TIMESTAMP (outbuf);
+  }
+
+  if (G_UNLIKELY (!demux->no_more_pads
+          && GST_CLOCK_DIFF (demux->video_start,
+              GST_BUFFER_TIMESTAMP (outbuf) > 6 * GST_SECOND))) {
+    GST_DEBUG_OBJECT (demux,
+        "Signalling no-more-pads because no audio stream was found"
+        " after 6 seconds of video");
+    gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
+    demux->no_more_pads = TRUE;
+  }
+
   /* Push downstream */
   ret = gst_pad_push (demux->video_pad, outbuf);