mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
matroskamux: add properties to control cluster duration
https://bugzilla.gnome.org/show_bug.cgi?id=784971
This commit is contained in:
parent
a6d224521e
commit
1bbdfa8738
2 changed files with 47 additions and 6 deletions
|
@ -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;
|
||||
|
|
|
@ -107,8 +107,9 @@ struct _GstMatroskaMux {
|
|||
|
||||
/* timescale in the file */
|
||||
guint64 time_scale;
|
||||
/* based on timescale, limit of nanoseconds you can have in a cluster */
|
||||
/* minimum and maximum limit of nanoseconds you can have in a cluster */
|
||||
guint64 max_cluster_duration;
|
||||
guint64 min_cluster_duration;
|
||||
|
||||
/* length, position (time, ns) */
|
||||
guint64 duration;
|
||||
|
|
Loading…
Reference in a new issue