appsrc: Add duration property for providing a duration in TIME format
authorSebastian Dröge <sebastian@centricular.com>
Tue, 10 May 2016 13:44:04 +0000 (16:44 +0300)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 10 May 2016 13:50:32 +0000 (16:50 +0300)
https://bugzilla.gnome.org/show_bug.cgi?id=766229

docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/app/gstappsrc.c
gst-libs/gst/app/gstappsrc.h
win32/common/libgstapp.def

index f357f26..71623e1 100644 (file)
@@ -49,6 +49,8 @@ gst_app_src_get_latency
 gst_app_src_set_latency
 gst_app_src_set_size
 gst_app_src_get_size
+gst_app_src_set_duration
+gst_app_src_get_duration
 gst_app_src_set_stream_type
 gst_app_src_get_stream_type
 gst_app_src_set_max_bytes
index c13f8ad..4804032 100644 (file)
@@ -111,6 +111,7 @@ struct _GstAppSrcPrivate
   GstCaps *current_caps;
 
   gint64 size;
+  GstClockTime duration;
   GstAppStreamType stream_type;
   guint64 max_bytes;
   GstFormat format;
@@ -163,6 +164,7 @@ enum
 #define DEFAULT_PROP_EMIT_SIGNALS  TRUE
 #define DEFAULT_PROP_MIN_PERCENT   0
 #define DEFAULT_PROP_CURRENT_LEVEL_BYTES   0
+#define DEFAULT_PROP_DURATION      GST_CLOCK_TIME_NONE
 
 enum
 {
@@ -179,6 +181,7 @@ enum
   PROP_EMIT_SIGNALS,
   PROP_MIN_PERCENT,
   PROP_CURRENT_LEVEL_BYTES,
+  PROP_DURATION,
   PROP_LAST
 };
 
@@ -402,6 +405,19 @@ gst_app_src_class_init (GstAppSrcClass * klass)
           0, G_MAXUINT64, DEFAULT_PROP_CURRENT_LEVEL_BYTES,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstAppSrc::duration:
+   *
+   * The total duration in nanoseconds of the data stream. If the total duration is known, it
+   * is recommended to configure it with this property.
+   *
+   * Since: 1.10
+   */
+  g_object_class_install_property (gobject_class, PROP_DURATION,
+      g_param_spec_uint64 ("duration", "Duration",
+          "The duration of the data stream in nanoseconds (GST_CLOCK_TIME_NONE if unknown)",
+          0, G_MAXUINT64, DEFAULT_PROP_DURATION,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
    * GstAppSrc::need-data:
@@ -551,6 +567,7 @@ gst_app_src_init (GstAppSrc * appsrc)
   priv->queue = g_queue_new ();
 
   priv->size = DEFAULT_PROP_SIZE;
+  priv->duration = DEFAULT_PROP_DURATION;
   priv->stream_type = DEFAULT_PROP_STREAM_TYPE;
   priv->max_bytes = DEFAULT_PROP_MAX_BYTES;
   priv->format = DEFAULT_PROP_FORMAT;
@@ -703,6 +720,9 @@ gst_app_src_set_property (GObject * object, guint prop_id,
     case PROP_MIN_PERCENT:
       priv->min_percent = g_value_get_uint (value);
       break;
+    case PROP_DURATION:
+      gst_app_src_set_duration (appsrc, g_value_get_uint64 (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -763,6 +783,9 @@ gst_app_src_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_CURRENT_LEVEL_BYTES:
       g_value_set_uint64 (value, gst_app_src_get_current_level_bytes (appsrc));
       break;
+    case PROP_DURATION:
+      g_value_set_uint64 (value, gst_app_src_get_duration (appsrc));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -935,6 +958,9 @@ gst_app_src_query (GstBaseSrc * src, GstQuery * query)
       if (format == GST_FORMAT_BYTES) {
         gst_query_set_duration (query, format, priv->size);
         res = TRUE;
+      } else if (format == GST_FORMAT_TIME) {
+        gst_query_set_duration (query, format, priv->duration);
+        res = TRUE;
       } else {
         res = FALSE;
       }
@@ -1100,6 +1126,16 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
 
     gst_element_post_message (GST_ELEMENT (appsrc),
         gst_message_new_duration_changed (GST_OBJECT (appsrc)));
+  } else if (G_UNLIKELY (priv->duration != bsrc->segment.duration &&
+          bsrc->segment.format == GST_FORMAT_TIME)) {
+    GST_DEBUG_OBJECT (appsrc,
+        "Duration changed from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (bsrc->segment.duration), GST_TIME_ARGS (priv->duration));
+    bsrc->segment.duration = priv->duration;
+    GST_OBJECT_UNLOCK (appsrc);
+
+    gst_element_post_message (GST_ELEMENT (appsrc),
+        gst_message_new_duration_changed (GST_OBJECT (appsrc)));
   } else {
     GST_OBJECT_UNLOCK (appsrc);
   }
@@ -1357,6 +1393,62 @@ gst_app_src_get_size (GstAppSrc * appsrc)
 }
 
 /**
+ * gst_app_src_set_duration:
+ * @appsrc: a #GstAppSrc
+ * @duration: the duration to set
+ *
+ * Set the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+ * not known.
+ *
+ * Since: 1.10
+ */
+void
+gst_app_src_set_duration (GstAppSrc * appsrc, GstClockTime duration)
+{
+  GstAppSrcPrivate *priv;
+
+  g_return_if_fail (GST_IS_APP_SRC (appsrc));
+
+  priv = appsrc->priv;
+
+  GST_OBJECT_LOCK (appsrc);
+  GST_DEBUG_OBJECT (appsrc, "setting duration of %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (duration));
+  priv->duration = duration;
+  GST_OBJECT_UNLOCK (appsrc);
+}
+
+/**
+ * gst_app_src_get_duration:
+ * @appsrc: a #GstAppSrc
+ *
+ * Get the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+ * not known.
+ *
+ * Returns: the duration of the stream previously set with gst_app_src_set_duration();
+ *
+ * Since: 1.10
+ */
+GstClockTime
+gst_app_src_get_duration (GstAppSrc * appsrc)
+{
+  GstClockTime duration;
+  GstAppSrcPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_APP_SRC (appsrc), GST_CLOCK_TIME_NONE);
+
+  priv = appsrc->priv;
+
+  GST_OBJECT_LOCK (appsrc);
+  duration = priv->duration;
+  GST_DEBUG_OBJECT (appsrc, "getting duration of %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (duration));
+  GST_OBJECT_UNLOCK (appsrc);
+
+  return duration;
+}
+
+/**
  * gst_app_src_set_stream_type:
  * @appsrc: a #GstAppSrc
  * @type: the new state
index d37edae..c9d1738 100644 (file)
@@ -127,6 +127,9 @@ GstCaps*         gst_app_src_get_caps                (GstAppSrc *appsrc);
 void             gst_app_src_set_size                (GstAppSrc *appsrc, gint64 size);
 gint64           gst_app_src_get_size                (GstAppSrc *appsrc);
 
+void             gst_app_src_set_duration            (GstAppSrc *appsrc, GstClockTime duration);
+GstClockTime     gst_app_src_get_duration            (GstAppSrc *appsrc);
+
 void             gst_app_src_set_stream_type         (GstAppSrc *appsrc, GstAppStreamType type);
 GstAppStreamType gst_app_src_get_stream_type         (GstAppSrc *appsrc);
 
index de8fdb4..de99f19 100644 (file)
@@ -17,6 +17,7 @@ EXPORTS
        gst_app_src_end_of_stream
        gst_app_src_get_caps
        gst_app_src_get_current_level_bytes
+       gst_app_src_get_duration
        gst_app_src_get_emit_signals
        gst_app_src_get_latency
        gst_app_src_get_max_bytes
@@ -27,6 +28,7 @@ EXPORTS
        gst_app_src_push_sample
        gst_app_src_set_callbacks
        gst_app_src_set_caps
+       gst_app_src_set_duration
        gst_app_src_set_emit_signals
        gst_app_src_set_latency
        gst_app_src_set_max_bytes