video{de,en}coder: delay input caps processing until processing data
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Thu, 26 Jul 2012 12:28:26 +0000 (14:28 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Thu, 26 Jul 2012 12:35:45 +0000 (14:35 +0200)
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=680614

gst-libs/gst/video/gstvideodecoder.c
gst-libs/gst/video/gstvideoencoder.c

index 9404508..e6fcb34 100644 (file)
@@ -332,6 +332,8 @@ struct _GstVideoDecoderPrivate
   gint max_errors;
   gint error_count;
 
+  gboolean do_caps;
+
   /* ... being tracked here;
    * only available during parsing */
   GstVideoCodecFrame *current_frame;
@@ -933,7 +935,8 @@ gst_video_decoder_sink_event_default (GstVideoDecoder * decoder,
       GstCaps *caps;
 
       gst_event_parse_caps (event, &caps);
-      ret = gst_video_decoder_setcaps (decoder, caps);
+      ret = TRUE;
+      decoder->priv->do_caps = TRUE;
       gst_event_unref (event);
       event = NULL;
       break;
@@ -1826,6 +1829,18 @@ gst_video_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
   decoder = GST_VIDEO_DECODER (parent);
 
+  if (G_UNLIKELY (decoder->priv->do_caps)) {
+    GstCaps *caps = gst_pad_get_current_caps (decoder->sinkpad);
+    if (caps) {
+      if (!gst_video_decoder_setcaps (decoder, caps)) {
+        gst_caps_unref (caps);
+        goto not_negotiated;
+      }
+      gst_caps_unref (caps);
+    }
+    decoder->priv->do_caps = FALSE;
+  }
+
   GST_LOG_OBJECT (decoder,
       "chain PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT " duration %"
       GST_TIME_FORMAT " size %" G_GSIZE_FORMAT,
@@ -1862,6 +1877,15 @@ gst_video_decoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
   GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
   return ret;
+
+  /* ERRORS */
+not_negotiated:
+  {
+    GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION, (NULL),
+        ("encoder not initialized"));
+    gst_buffer_unref (buf);
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 }
 
 static GstStateChangeReturn
index c3d17ab..455215b 100644 (file)
@@ -141,6 +141,7 @@ struct _GstVideoEncoderPrivate
   /* FIXME : (and introduce a context ?) */
   gboolean drained;
   gboolean at_eos;
+  gboolean do_caps;
 
   gint64 min_latency;
   gint64 max_latency;
@@ -852,7 +853,8 @@ gst_video_encoder_sink_event_default (GstVideoEncoder * encoder,
       GstCaps *caps;
 
       gst_event_parse_caps (event, &caps);
-      ret = gst_video_encoder_setcaps (encoder, caps);
+      ret = TRUE;
+      encoder->priv->do_caps = TRUE;
       gst_event_unref (event);
       event = NULL;
       break;
@@ -1150,6 +1152,17 @@ gst_video_encoder_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 
   g_return_val_if_fail (klass->handle_frame != NULL, GST_FLOW_ERROR);
 
+  if (G_UNLIKELY (encoder->priv->do_caps)) {
+    GstCaps *caps = gst_pad_get_current_caps (encoder->sinkpad);
+    if (!caps)
+      goto not_negotiated;
+    if (!gst_video_encoder_setcaps (encoder, caps)) {
+      gst_caps_unref (caps);
+      goto not_negotiated;
+    }
+    encoder->priv->do_caps = FALSE;
+  }
+
   GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
 
   pts = GST_BUFFER_PTS (buf);
@@ -1241,6 +1254,15 @@ done:
   GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
 
   return ret;
+
+  /* ERRORS */
+not_negotiated:
+  {
+    GST_ELEMENT_ERROR (encoder, CORE, NEGOTIATION, (NULL),
+        ("encoder not initialized"));
+    gst_buffer_unref (buf);
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 }
 
 static GstStateChangeReturn