videoaggregator: add "ignore-eos" property for input pads
authorNirbheek Chauhan <nirbheek@centricular.com>
Mon, 9 Feb 2015 19:19:35 +0000 (00:49 +0530)
committerTim-Philipp Müller <tim@centricular.com>
Fri, 12 Jun 2015 18:44:50 +0000 (19:44 +0100)
When set, it causes videoaggregator to repeatedly aggregate the last buffer on
an EOS pad instead of skipping it and outputting silence. This is useful, for
instance, while playing back files seamless one after the other, to avoid
videoaggregator ever outputting silence (the checkerboard pattern).

It is to be noted that if all the pads on videoaggregator have this property set
on them, the mixer will never forward EOS downstream for obvious reasons. Hence,
at least one pad with 'ignore-eos' set to FALSE must send EOS to the mixer
before it will be forwarded downstream.

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

gst-libs/gst/video/gstvideoaggregator.c
gst-libs/gst/video/gstvideoaggregatorpad.h

index 72d346def999b0a25f88d72e94567c3316cc9eca..7e4341b4479efbd38ded63629060ef609be0224a 100644 (file)
@@ -54,10 +54,12 @@ static void gst_videoaggregator_reset_qos (GstVideoAggregator * vagg);
  ****************************************/
 
 #define DEFAULT_PAD_ZORDER 0
+#define DEFAULT_PAD_IGNORE_EOS FALSE
 enum
 {
   PROP_PAD_0,
   PROP_PAD_ZORDER,
+  PROP_PAD_IGNORE_EOS,
 };
 
 
@@ -87,6 +89,9 @@ gst_videoaggregator_pad_get_property (GObject * object, guint prop_id,
     case PROP_PAD_ZORDER:
       g_value_set_uint (value, pad->zorder);
       break;
+    case PROP_PAD_IGNORE_EOS:
+      g_value_set_boolean (value, pad->ignore_eos);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -116,6 +121,9 @@ gst_videoaggregator_pad_set_property (GObject * object, guint prop_id,
           (GCompareFunc) pad_zorder_compare);
       GST_OBJECT_UNLOCK (vagg);
       break;
+    case PROP_PAD_IGNORE_EOS:
+      pad->ignore_eos = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -304,6 +312,11 @@ gst_videoaggregator_pad_class_init (GstVideoAggregatorPadClass * klass)
       g_param_spec_uint ("zorder", "Z-Order", "Z Order of the picture",
           0, 10000, DEFAULT_PAD_ZORDER,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_PAD_IGNORE_EOS,
+      g_param_spec_boolean ("ignore-eos", "Ignore EOS", "Aggregate the last "
+          "frame on pads that are EOS till they are released",
+          DEFAULT_PAD_IGNORE_EOS,
+          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
 
   g_type_class_add_private (klass, sizeof (GstVideoAggregatorPadPrivate));
 
@@ -322,6 +335,7 @@ gst_videoaggregator_pad_init (GstVideoAggregatorPad * vaggpad)
       GstVideoAggregatorPadPrivate);
 
   vaggpad->zorder = DEFAULT_PAD_ZORDER;
+  vaggpad->ignore_eos = DEFAULT_PAD_IGNORE_EOS;
   vaggpad->aggregated_frame = NULL;
   vaggpad->priv->converted_buffer = NULL;
 
@@ -1112,6 +1126,12 @@ gst_videoaggregator_fill_queues (GstVideoAggregator * vagg,
         continue;
       }
     } else {
+      if (is_eos && pad->ignore_eos) {
+        eos = FALSE;
+        GST_DEBUG_OBJECT (pad, "ignoring EOS and re-using previous buffer");
+        continue;
+      }
+
       if (pad->priv->end_time != -1) {
         if (pad->priv->end_time <= output_start_time) {
           pad->priv->start_time = pad->priv->end_time = -1;
index 1839740269ba66abd435f46f1ff55351931ba18b..4302aa309db9cdbf00b79c579025cef3029a1ae2 100644 (file)
@@ -73,6 +73,7 @@ struct _GstVideoAggregatorPad
 
   /* properties */
   guint zorder;
+  gboolean ignore_eos;
 
   /* < private > */
   GstVideoAggregatorPadPrivate *priv;