summaryrefslogtreecommitdiff
path: root/gst/matroska/matroska-mux.c
diff options
context:
space:
mode:
authorNicola Murino <nicola.murino@gmail.com>2017-07-18 00:26:11 +0200
committerSebastian Dröge <sebastian@centricular.com>2017-07-18 10:08:33 +0300
commit1bbdfa8738da6ecfe73cbead4af74e3d4172b389 (patch)
treee5d837100c513cac463dc0f2d6ac79942340f971 /gst/matroska/matroska-mux.c
parenta6d224521e47a17da9e267b50b4b95e1f6fb2f2b (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.c50
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;