matroskamux: Create a TIME segment when creating streamable output

Related to https://bugzilla.gnome.org/show_bug.cgi?id=754435 which
does the same for flvmux.
This commit is contained in:
Sebastian Dröge 2015-10-11 11:37:51 +01:00
parent 240b0ac9f6
commit ca9b6b55e6
4 changed files with 16 additions and 14 deletions

View file

@ -215,7 +215,8 @@ gst_ebml_writer_send_segment_event (GstEbmlWrite * ebml, guint64 new_pos)
GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos); GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);
gst_segment_init (&segment, GST_FORMAT_BYTES); gst_segment_init (&segment,
ebml->streamable ? GST_FORMAT_TIME : GST_FORMAT_BYTES);
segment.start = new_pos; segment.start = new_pos;
segment.stop = -1; segment.stop = -1;
segment.position = 0; segment.position = 0;

View file

@ -60,6 +60,8 @@ typedef struct _GstEbmlWrite {
guint64 streamheader_pos; guint64 streamheader_pos;
GstCaps *caps; GstCaps *caps;
gboolean streamable;
} GstEbmlWrite; } GstEbmlWrite;
typedef struct _GstEbmlWriteClass { typedef struct _GstEbmlWriteClass {

View file

@ -456,7 +456,7 @@ gst_matroska_mux_init (GstMatroskaMux * mux, gpointer g_class)
mux->doctype_version = DEFAULT_DOCTYPE_VERSION; mux->doctype_version = DEFAULT_DOCTYPE_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; mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
mux->streamable = DEFAULT_STREAMABLE; mux->ebml_write->streamable = DEFAULT_STREAMABLE;
/* initialize internal variables */ /* initialize internal variables */
mux->index = NULL; mux->index = NULL;
@ -2668,7 +2668,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
#endif #endif
/* if not streaming, check if downstream is seekable */ /* if not streaming, check if downstream is seekable */
if (!mux->streamable) { if (!mux->ebml_write->streamable) {
gboolean seekable; gboolean seekable;
GstQuery *query; GstQuery *query;
@ -2682,7 +2682,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
seekable = FALSE; seekable = FALSE;
} }
if (!seekable) { if (!seekable) {
mux->streamable = TRUE; mux->ebml_write->streamable = TRUE;
g_object_notify (G_OBJECT (mux), "streamable"); g_object_notify (G_OBJECT (mux), "streamable");
GST_WARNING_OBJECT (mux, "downstream is not seekable, but " GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
"streamable=false. Will ignore that and create streamable output " "streamable=false. Will ignore that and create streamable output "
@ -2718,7 +2718,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT); gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT);
mux->segment_master = ebml->pos; mux->segment_master = ebml->pos;
if (!mux->streamable) { if (!mux->ebml_write->streamable) {
/* seekhead (table of contents) - we set the positions later */ /* seekhead (table of contents) - we set the positions later */
mux->seekhead_pos = ebml->pos; mux->seekhead_pos = ebml->pos;
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD); master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
@ -2731,7 +2731,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
gst_ebml_write_master_finish (ebml, master); gst_ebml_write_master_finish (ebml, master);
} }
if (mux->streamable) { if (mux->ebml_write->streamable) {
const GstTagList *tags; const GstTagList *tags;
gboolean has_main_tags; gboolean has_main_tags;
@ -2772,7 +2772,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale); gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
mux->duration_pos = ebml->pos; mux->duration_pos = ebml->pos;
/* get duration */ /* get duration */
if (!mux->streamable) { if (!mux->ebml_write->streamable) {
for (collected = mux->collect->data; collected; for (collected = mux->collect->data; collected;
collected = g_slist_next (collected)) { collected = g_slist_next (collected)) {
GstMatroskaPad *collect_pad; GstMatroskaPad *collect_pad;
@ -2836,7 +2836,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
#if 0 #if 0
/* chapters */ /* chapters */
toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux)); toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
if (toc != NULL && !mux->streamable) { if (toc != NULL && !mux->ebml_write->streamable) {
guint64 master_chapters = 0; guint64 master_chapters = 0;
GstTocEntry *toc_entry; GstTocEntry *toc_entry;
GList *cur, *to_write = NULL; GList *cur, *to_write = NULL;
@ -3493,7 +3493,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
if (mux->cluster_time + if (mux->cluster_time +
mux->max_cluster_duration < buffer_timestamp mux->max_cluster_duration < buffer_timestamp
|| is_video_keyframe || mux->force_key_unit_event) { || is_video_keyframe || mux->force_key_unit_event) {
if (!mux->streamable) if (!mux->ebml_write->streamable)
gst_ebml_write_master_finish (ebml, mux->cluster); gst_ebml_write_master_finish (ebml, mux->cluster);
/* Forward the GstForceKeyUnit event after finishing the cluster */ /* Forward the GstForceKeyUnit event after finishing the cluster */
@ -3536,7 +3536,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
* the block in the cluster which contains the timestamp, should also work * the block in the cluster which contains the timestamp, should also work
* for files with multiple audio tracks. * for files with multiple audio tracks.
*/ */
if (!mux->streamable && if (!mux->ebml_write->streamable &&
(is_video_keyframe || (is_video_keyframe ||
((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) && ((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
(mux->num_streams == 1)))) { (mux->num_streams == 1)))) {
@ -3677,7 +3677,7 @@ gst_matroska_mux_handle_buffer (GstCollectPads * pads, GstCollectData * data,
/* if there is no best pad, we have reached EOS */ /* if there is no best pad, we have reached EOS */
if (best == NULL) { if (best == NULL) {
GST_DEBUG_OBJECT (mux, "No best pad. Finishing..."); GST_DEBUG_OBJECT (mux, "No best pad. Finishing...");
if (!mux->streamable) { if (!mux->ebml_write->streamable) {
gst_matroska_mux_finish (mux); gst_matroska_mux_finish (mux);
} else { } else {
GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish"); GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
@ -3796,7 +3796,7 @@ gst_matroska_mux_set_property (GObject * object,
mux->min_index_interval = g_value_get_int64 (value); mux->min_index_interval = g_value_get_int64 (value);
break; break;
case PROP_STREAMABLE: case PROP_STREAMABLE:
mux->streamable = g_value_get_boolean (value); mux->ebml_write->streamable = g_value_get_boolean (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -3824,7 +3824,7 @@ gst_matroska_mux_get_property (GObject * object,
g_value_set_int64 (value, mux->min_index_interval); g_value_set_int64 (value, mux->min_index_interval);
break; break;
case PROP_STREAMABLE: case PROP_STREAMABLE:
g_value_set_boolean (value, mux->streamable); g_value_set_boolean (value, mux->ebml_write->streamable);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);

View file

@ -104,7 +104,6 @@ struct _GstMatroskaMux {
GstMatroskaIndex *index; GstMatroskaIndex *index;
guint num_indexes; guint num_indexes;
GstClockTimeDiff min_index_interval; GstClockTimeDiff min_index_interval;
gboolean streamable;
/* timescale in the file */ /* timescale in the file */
guint64 time_scale; guint64 time_scale;