diff options
author | Nicola Murino <nicola.murino@gmail.com> | 2017-07-18 00:26:11 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2017-07-18 10:08:33 +0300 |
commit | 1bbdfa8738da6ecfe73cbead4af74e3d4172b389 (patch) | |
tree | e5d837100c513cac463dc0f2d6ac79942340f971 /gst/matroska/matroska-mux.c | |
parent | a6d224521e47a17da9e267b50b4b95e1f6fb2f2b (diff) |
matroskamux: add properties to control cluster duration
https://bugzilla.gnome.org/show_bug.cgi?id=784971
Diffstat (limited to 'gst/matroska/matroska-mux.c')
-rw-r--r-- | gst/matroska/matroska-mux.c | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index 2a0bdcc8c..fdabe5b63 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -70,7 +70,9 @@ enum PROP_DOCTYPE_VERSION, PROP_MIN_INDEX_INTERVAL, PROP_STREAMABLE, - PROP_TIMECODESCALE + PROP_TIMECODESCALE, + PROP_MIN_CLUSTER_DURATION, + PROP_MAX_CLUSTER_DURATION }; #define DEFAULT_DOCTYPE_VERSION 2 @@ -78,6 +80,8 @@ enum #define DEFAULT_MIN_INDEX_INTERVAL 0 #define DEFAULT_STREAMABLE FALSE #define DEFAULT_TIMECODESCALE GST_MSECOND +#define DEFAULT_MIN_CLUSTER_DURATION 500 * GST_MSECOND +#define DEFAULT_MAX_CLUSTER_DURATION 65535 * GST_MSECOND /* WAVEFORMATEX is gst_riff_strf_auds + an extra guint16 extension size */ #define WAVEFORMATEX_SIZE (2 + sizeof (gst_riff_strf_auds)) @@ -344,6 +348,20 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass) "TimecodeScale used to calculate the Raw Timecode of a Block", 1, GST_SECOND, DEFAULT_TIMECODESCALE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MIN_CLUSTER_DURATION, + g_param_spec_int64 ("min-cluster-duration", "Minimum cluster duration", + "Desidered cluster duration as nanoseconds. A new cluster will be " + "created irrespective of this property if a force key unit event " + "is received. 0 means create a new cluster for each video keyframe " + "or for each audio buffer in audio only streams.", 0, + G_MAXINT64, DEFAULT_MIN_CLUSTER_DURATION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_MAX_CLUSTER_DURATION, + g_param_spec_int64 ("max-cluster-duration", "Maximum cluster duration", + "A new cluster will be created if its duration exceeds this value. " + "0 means no maximum duration.", 0, + G_MAXINT64, DEFAULT_MAX_CLUSTER_DURATION, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state); @@ -471,6 +489,8 @@ gst_matroska_mux_init (GstMatroskaMux * mux, gpointer g_class) mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL; mux->ebml_write->streamable = DEFAULT_STREAMABLE; mux->time_scale = DEFAULT_TIMECODESCALE; + mux->min_cluster_duration = DEFAULT_MIN_CLUSTER_DURATION; + mux->max_cluster_duration = DEFAULT_MAX_CLUSTER_DURATION; /* initialize internal variables */ mux->index = NULL; @@ -664,7 +684,6 @@ gst_matroska_mux_reset (GstElement * element) mux->index = NULL; /* reset timers */ - mux->max_cluster_duration = G_MAXINT16 * mux->time_scale; mux->duration = 0; /* reset cluster */ @@ -3526,6 +3545,8 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad, gboolean is_video_keyframe = FALSE; gboolean is_video_invisible = FALSE; gboolean is_audio_only = FALSE; + gboolean is_min_duration_reached = FALSE; + gboolean is_max_duration_exceeded = FALSE; GstMatroskamuxPad *pad; gint flags = 0; GstClockTime buffer_timestamp; @@ -3602,13 +3623,20 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad, is_audio_only = (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) && (mux->num_streams == 1); + is_min_duration_reached = (mux->min_cluster_duration == 0 + || (buffer_timestamp > mux->cluster_time + && (buffer_timestamp - mux->cluster_time) >= + mux->min_cluster_duration)); + is_max_duration_exceeded = (mux->max_cluster_duration > 0 + && buffer_timestamp > mux->cluster_time + && (buffer_timestamp - mux->cluster_time) >= mux->max_cluster_duration); if (mux->cluster) { /* start a new cluster at every keyframe, at every GstForceKeyUnit event, * or when we may be reaching the limit of the relative timestamp */ - if (mux->cluster_time + - mux->max_cluster_duration < buffer_timestamp - || is_video_keyframe || mux->force_key_unit_event || is_audio_only) { + if (is_max_duration_exceeded || (is_video_keyframe + && is_min_duration_reached) || mux->force_key_unit_event + || (is_audio_only && is_min_duration_reached)) { if (!mux->ebml_write->streamable) gst_ebml_write_master_finish (ebml, mux->cluster); @@ -3940,6 +3968,12 @@ gst_matroska_mux_set_property (GObject * object, case PROP_TIMECODESCALE: mux->time_scale = g_value_get_int64 (value); break; + case PROP_MIN_CLUSTER_DURATION: + mux->min_cluster_duration = g_value_get_int64 (value); + break; + case PROP_MAX_CLUSTER_DURATION: + mux->max_cluster_duration = g_value_get_int64 (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3971,6 +4005,12 @@ gst_matroska_mux_get_property (GObject * object, case PROP_TIMECODESCALE: g_value_set_int64 (value, mux->time_scale); break; + case PROP_MIN_CLUSTER_DURATION: + g_value_set_int64 (value, mux->min_cluster_duration); + break; + case PROP_MAX_CLUSTER_DURATION: + g_value_set_int64 (value, mux->max_cluster_duration); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; |