appsrc: Add duration property for providing a duration in TIME format

https://bugzilla.gnome.org/show_bug.cgi?id=766229
This commit is contained in:
Sebastian Dröge 2016-05-10 16:44:04 +03:00
parent 5be3c5f6b2
commit dc8120f298
4 changed files with 99 additions and 0 deletions

View file

@ -49,6 +49,8 @@ gst_app_src_get_latency
gst_app_src_set_latency gst_app_src_set_latency
gst_app_src_set_size gst_app_src_set_size
gst_app_src_get_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_set_stream_type
gst_app_src_get_stream_type gst_app_src_get_stream_type
gst_app_src_set_max_bytes gst_app_src_set_max_bytes

View file

@ -111,6 +111,7 @@ struct _GstAppSrcPrivate
GstCaps *current_caps; GstCaps *current_caps;
gint64 size; gint64 size;
GstClockTime duration;
GstAppStreamType stream_type; GstAppStreamType stream_type;
guint64 max_bytes; guint64 max_bytes;
GstFormat format; GstFormat format;
@ -163,6 +164,7 @@ enum
#define DEFAULT_PROP_EMIT_SIGNALS TRUE #define DEFAULT_PROP_EMIT_SIGNALS TRUE
#define DEFAULT_PROP_MIN_PERCENT 0 #define DEFAULT_PROP_MIN_PERCENT 0
#define DEFAULT_PROP_CURRENT_LEVEL_BYTES 0 #define DEFAULT_PROP_CURRENT_LEVEL_BYTES 0
#define DEFAULT_PROP_DURATION GST_CLOCK_TIME_NONE
enum enum
{ {
@ -179,6 +181,7 @@ enum
PROP_EMIT_SIGNALS, PROP_EMIT_SIGNALS,
PROP_MIN_PERCENT, PROP_MIN_PERCENT,
PROP_CURRENT_LEVEL_BYTES, PROP_CURRENT_LEVEL_BYTES,
PROP_DURATION,
PROP_LAST PROP_LAST
}; };
@ -402,6 +405,19 @@ gst_app_src_class_init (GstAppSrcClass * klass)
0, G_MAXUINT64, DEFAULT_PROP_CURRENT_LEVEL_BYTES, 0, G_MAXUINT64, DEFAULT_PROP_CURRENT_LEVEL_BYTES,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); 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: * GstAppSrc::need-data:
@ -551,6 +567,7 @@ gst_app_src_init (GstAppSrc * appsrc)
priv->queue = g_queue_new (); priv->queue = g_queue_new ();
priv->size = DEFAULT_PROP_SIZE; priv->size = DEFAULT_PROP_SIZE;
priv->duration = DEFAULT_PROP_DURATION;
priv->stream_type = DEFAULT_PROP_STREAM_TYPE; priv->stream_type = DEFAULT_PROP_STREAM_TYPE;
priv->max_bytes = DEFAULT_PROP_MAX_BYTES; priv->max_bytes = DEFAULT_PROP_MAX_BYTES;
priv->format = DEFAULT_PROP_FORMAT; priv->format = DEFAULT_PROP_FORMAT;
@ -703,6 +720,9 @@ gst_app_src_set_property (GObject * object, guint prop_id,
case PROP_MIN_PERCENT: case PROP_MIN_PERCENT:
priv->min_percent = g_value_get_uint (value); priv->min_percent = g_value_get_uint (value);
break; break;
case PROP_DURATION:
gst_app_src_set_duration (appsrc, g_value_get_uint64 (value));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -763,6 +783,9 @@ gst_app_src_get_property (GObject * object, guint prop_id, GValue * value,
case PROP_CURRENT_LEVEL_BYTES: case PROP_CURRENT_LEVEL_BYTES:
g_value_set_uint64 (value, gst_app_src_get_current_level_bytes (appsrc)); g_value_set_uint64 (value, gst_app_src_get_current_level_bytes (appsrc));
break; break;
case PROP_DURATION:
g_value_set_uint64 (value, gst_app_src_get_duration (appsrc));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -935,6 +958,9 @@ gst_app_src_query (GstBaseSrc * src, GstQuery * query)
if (format == GST_FORMAT_BYTES) { if (format == GST_FORMAT_BYTES) {
gst_query_set_duration (query, format, priv->size); gst_query_set_duration (query, format, priv->size);
res = TRUE; res = TRUE;
} else if (format == GST_FORMAT_TIME) {
gst_query_set_duration (query, format, priv->duration);
res = TRUE;
} else { } else {
res = FALSE; res = FALSE;
} }
@ -1098,6 +1124,16 @@ gst_app_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
bsrc->segment.duration = priv->size; bsrc->segment.duration = priv->size;
GST_OBJECT_UNLOCK (appsrc); GST_OBJECT_UNLOCK (appsrc);
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_element_post_message (GST_ELEMENT (appsrc),
gst_message_new_duration_changed (GST_OBJECT (appsrc))); gst_message_new_duration_changed (GST_OBJECT (appsrc)));
} else { } else {
@ -1356,6 +1392,62 @@ gst_app_src_get_size (GstAppSrc * appsrc)
return size; return size;
} }
/**
* 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: * gst_app_src_set_stream_type:
* @appsrc: a #GstAppSrc * @appsrc: a #GstAppSrc

View file

@ -127,6 +127,9 @@ GstCaps* gst_app_src_get_caps (GstAppSrc *appsrc);
void gst_app_src_set_size (GstAppSrc *appsrc, gint64 size); void gst_app_src_set_size (GstAppSrc *appsrc, gint64 size);
gint64 gst_app_src_get_size (GstAppSrc *appsrc); 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); void gst_app_src_set_stream_type (GstAppSrc *appsrc, GstAppStreamType type);
GstAppStreamType gst_app_src_get_stream_type (GstAppSrc *appsrc); GstAppStreamType gst_app_src_get_stream_type (GstAppSrc *appsrc);

View file

@ -17,6 +17,7 @@ EXPORTS
gst_app_src_end_of_stream gst_app_src_end_of_stream
gst_app_src_get_caps gst_app_src_get_caps
gst_app_src_get_current_level_bytes gst_app_src_get_current_level_bytes
gst_app_src_get_duration
gst_app_src_get_emit_signals gst_app_src_get_emit_signals
gst_app_src_get_latency gst_app_src_get_latency
gst_app_src_get_max_bytes gst_app_src_get_max_bytes
@ -27,6 +28,7 @@ EXPORTS
gst_app_src_push_sample gst_app_src_push_sample
gst_app_src_set_callbacks gst_app_src_set_callbacks
gst_app_src_set_caps gst_app_src_set_caps
gst_app_src_set_duration
gst_app_src_set_emit_signals gst_app_src_set_emit_signals
gst_app_src_set_latency gst_app_src_set_latency
gst_app_src_set_max_bytes gst_app_src_set_max_bytes