mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
matroskamux: make index size configurable.
Added the 'min-index-interval' property to matroskamux, which determines how much time (nanoseconds) is left between keyframes stored in the index. Fixes #583985.
This commit is contained in:
parent
1f6b06ce66
commit
ca41ddda75
2 changed files with 43 additions and 28 deletions
|
@ -61,11 +61,13 @@ enum
|
||||||
{
|
{
|
||||||
ARG_0,
|
ARG_0,
|
||||||
ARG_WRITING_APP,
|
ARG_WRITING_APP,
|
||||||
ARG_MATROSKA_VERSION
|
ARG_MATROSKA_VERSION,
|
||||||
|
ARG_MIN_INDEX_INTERVAL
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_MATROSKA_VERSION 1
|
#define DEFAULT_MATROSKA_VERSION 1
|
||||||
#define DEFAULT_WRITING_APP "GStreamer Matroska muxer"
|
#define DEFAULT_WRITING_APP "GStreamer Matroska muxer"
|
||||||
|
#define DEFAULT_MIN_INDEX_INTERVAL 0
|
||||||
|
|
||||||
static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
|
static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
|
@ -293,6 +295,10 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
|
||||||
g_param_spec_int ("version", "Matroska version",
|
g_param_spec_int ("version", "Matroska version",
|
||||||
"This parameter determines what matroska features can be used.",
|
"This parameter determines what matroska features can be used.",
|
||||||
1, 2, DEFAULT_MATROSKA_VERSION, G_PARAM_READWRITE));
|
1, 2, DEFAULT_MATROSKA_VERSION, G_PARAM_READWRITE));
|
||||||
|
g_object_class_install_property (gobject_class, ARG_MIN_INDEX_INTERVAL,
|
||||||
|
g_param_spec_int64 ("min-index-interval", "Minimum time between index "
|
||||||
|
"entries", "An index entry is created every so many nanoseconds.",
|
||||||
|
0, G_MAXINT64, DEFAULT_MIN_INDEX_INTERVAL, G_PARAM_READWRITE));
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state);
|
GST_DEBUG_FUNCPTR (gst_matroska_mux_change_state);
|
||||||
|
@ -327,6 +333,7 @@ gst_matroska_mux_init (GstMatroskaMux * mux, GstMatroskaMuxClass * g_class)
|
||||||
/* property defaults */
|
/* property defaults */
|
||||||
mux->matroska_version = DEFAULT_MATROSKA_VERSION;
|
mux->matroska_version = DEFAULT_MATROSKA_VERSION;
|
||||||
mux->writing_app = g_strdup (DEFAULT_WRITING_APP);
|
mux->writing_app = g_strdup (DEFAULT_WRITING_APP);
|
||||||
|
mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
|
||||||
|
|
||||||
/* initialize internal variables */
|
/* initialize internal variables */
|
||||||
mux->index = NULL;
|
mux->index = NULL;
|
||||||
|
@ -2514,16 +2521,29 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (buf))
|
if (GST_BUFFER_DURATION_IS_VALID (buf))
|
||||||
collect_pad->duration += GST_BUFFER_DURATION (buf);
|
collect_pad->duration += GST_BUFFER_DURATION (buf);
|
||||||
|
|
||||||
/* We currently write an index entry for each keyframe in a
|
/* We currently write index entries for all video tracks or for the audio
|
||||||
* video track or one entry for each cluster in an audio track
|
* track in a single-track audio file. This could be improved by keeping the
|
||||||
* for audio only files. This can be largely improved, such as doing
|
* index only for the *first* video track. */
|
||||||
* one for each keyframe or each second (for all-keyframe
|
|
||||||
* streams), only the *first* video track. But that'll come later... */
|
|
||||||
|
|
||||||
/* TODO: index is useful for every track, should contain the number of
|
/* TODO: index is useful for every track, should contain the number of
|
||||||
* the block in the cluster which contains the timestamp
|
* the block in the cluster which contains the timestamp, should also work
|
||||||
|
* for files with multiple audio tracks.
|
||||||
*/
|
*/
|
||||||
if (is_video_keyframe) {
|
if (is_video_keyframe ||
|
||||||
|
((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
|
||||||
|
(mux->num_streams == 1))) {
|
||||||
|
gint last_idx = -1;
|
||||||
|
|
||||||
|
if (mux->min_index_interval != 0) {
|
||||||
|
for (last_idx = mux->num_indexes - 1; last_idx >= 0; last_idx--) {
|
||||||
|
if (mux->index[last_idx].track == collect_pad->track->num)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_idx < 0 || mux->min_index_interval == 0 ||
|
||||||
|
(GST_CLOCK_DIFF (mux->index[last_idx].time, GST_BUFFER_TIMESTAMP (buf))
|
||||||
|
>= mux->min_index_interval)) {
|
||||||
GstMatroskaIndex *idx;
|
GstMatroskaIndex *idx;
|
||||||
|
|
||||||
if (mux->num_indexes % 32 == 0) {
|
if (mux->num_indexes % 32 == 0) {
|
||||||
|
@ -2535,19 +2555,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
|
||||||
idx->pos = mux->cluster_pos;
|
idx->pos = mux->cluster_pos;
|
||||||
idx->time = GST_BUFFER_TIMESTAMP (buf);
|
idx->time = GST_BUFFER_TIMESTAMP (buf);
|
||||||
idx->track = collect_pad->track->num;
|
idx->track = collect_pad->track->num;
|
||||||
} else if ((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
|
|
||||||
(mux->num_streams == 1)) {
|
|
||||||
GstMatroskaIndex *idx;
|
|
||||||
|
|
||||||
if (mux->num_indexes % 32 == 0) {
|
|
||||||
mux->index = g_renew (GstMatroskaIndex, mux->index,
|
|
||||||
mux->num_indexes + 32);
|
|
||||||
}
|
}
|
||||||
idx = &mux->index[mux->num_indexes++];
|
|
||||||
|
|
||||||
idx->pos = mux->cluster_pos;
|
|
||||||
idx->time = GST_BUFFER_TIMESTAMP (buf);
|
|
||||||
idx->track = collect_pad->track->num;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the duration differs from the default duration. */
|
/* Check if the duration differs from the default duration. */
|
||||||
|
@ -2746,6 +2754,9 @@ gst_matroska_mux_set_property (GObject * object,
|
||||||
case ARG_MATROSKA_VERSION:
|
case ARG_MATROSKA_VERSION:
|
||||||
mux->matroska_version = g_value_get_int (value);
|
mux->matroska_version = g_value_get_int (value);
|
||||||
break;
|
break;
|
||||||
|
case ARG_MIN_INDEX_INTERVAL:
|
||||||
|
mux->min_index_interval = g_value_get_int64 (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;
|
||||||
|
@ -2768,6 +2779,9 @@ gst_matroska_mux_get_property (GObject * object,
|
||||||
case ARG_MATROSKA_VERSION:
|
case ARG_MATROSKA_VERSION:
|
||||||
g_value_set_int (value, mux->matroska_version);
|
g_value_set_int (value, mux->matroska_version);
|
||||||
break;
|
break;
|
||||||
|
case ARG_MIN_INDEX_INTERVAL:
|
||||||
|
g_value_set_int64 (value, mux->min_index_interval);
|
||||||
|
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;
|
||||||
|
|
|
@ -110,6 +110,7 @@ typedef struct _GstMatroskaMux {
|
||||||
/* a cue (index) table */
|
/* a cue (index) table */
|
||||||
GstMatroskaIndex *index;
|
GstMatroskaIndex *index;
|
||||||
guint num_indexes;
|
guint num_indexes;
|
||||||
|
GstClockTimeDiff min_index_interval;
|
||||||
|
|
||||||
/* timescale in the file */
|
/* timescale in the file */
|
||||||
guint64 time_scale;
|
guint64 time_scale;
|
||||||
|
|
Loading…
Reference in a new issue