tagdemux: fix handling of very short files in push mode
authorTim-Philipp Müller <tim@centricular.com>
Thu, 30 Jun 2016 17:53:07 +0000 (18:53 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 30 Jun 2016 17:53:07 +0000 (18:53 +0100)
By default we'll wait for a certain amount of data before
attempting typefinding. However, if the stream is fairly
short, we might get EOS before we ever attempted any
typefinding, so at this point we should force typefinding
and output any pending data if we manage to detect the
type.

https://bugzilla.gnome.org//show_bug.cgi?id=768178

gst-libs/gst/tag/gsttagdemux.c

index d8296bb..cd94009 100644 (file)
@@ -626,13 +626,11 @@ gst_tag_demux_chain_parse_tag (GstTagDemux * demux)
 }
 
 static GstFlowReturn
-gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
+gst_tag_demux_chain_buffer (GstTagDemux * demux, GstBuffer * buf,
+    gboolean at_eos)
 {
-  GstTagDemux *demux;
   gsize size;
 
-  demux = GST_TAG_DEMUX (parent);
-
   size = gst_buffer_get_size (buf);
 
   /* Update our segment position info */
@@ -664,7 +662,7 @@ gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
       update_collected (demux);
 
-      if (demux->priv->collect_size <
+      if (!at_eos && demux->priv->collect_size <
           TYPE_FIND_MIN_SIZE + demux->priv->strip_start)
         break;                  /* Go get more data first */
 
@@ -745,7 +743,7 @@ gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
           demux->priv->send_tag_event = FALSE;
         }
 
-        GST_LOG_OBJECT (demux, "Pushing buffer %p", outbuf);
+        GST_LOG_OBJECT (demux, "Pushing buffer %" GST_PTR_FORMAT, outbuf);
 
         return gst_pad_push (demux->priv->srcpad, outbuf);
       }
@@ -754,6 +752,12 @@ gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
   return GST_FLOW_OK;
 }
 
+static GstFlowReturn
+gst_tag_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
+{
+  return gst_tag_demux_chain_buffer (GST_TAG_DEMUX (parent), buf, FALSE);
+}
+
 static gboolean
 gst_tag_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
@@ -765,8 +769,14 @@ gst_tag_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_EOS:
       if (!gst_pad_has_current_caps (demux->priv->srcpad)) {
-        GST_WARNING_OBJECT (demux, "EOS before we found a type");
-        GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
+        GST_INFO_OBJECT (demux, "EOS before we found a type");
+
+        /* push final buffer with eos indication to force typefinding */
+        gst_tag_demux_chain_buffer (demux, gst_buffer_new (), TRUE);
+
+        if (!gst_pad_has_current_caps (demux->priv->srcpad)) {
+          GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
+        }
       }
       ret = gst_pad_event_default (pad, parent, event);
       break;