summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--gst/matroska/matroska-mux.c59
-rw-r--r--gst/matroska/matroska-mux.h12
3 files changed, 73 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 7ead79d1..4f9f0912 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,10 @@
2004-09-09 Arwed v. Merkatz <v.merkatz@gmx.net>
* gst/matroska/matroska-mux.h:
* gst/matroska/matroska-mux.c: (gst_matroska_mux_reset),
- (gst_matroska_mux_finish), (gst_matroska_mux_write_data):
+ (gst_matroska_mux_start), (gst_matroska_mux_finish),
+ (gst_matroska_mux_write_data):
Write multiple blocks/frames per cluster.
+ Write meta-seek information (seek heads).
2004-09-09 Scott Wheeler <wheeler@kde.org>
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index ba780de2..77907833 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -328,6 +328,11 @@ gst_matroska_mux_reset (GstElement * element)
mux->cluster = 0;
mux->cluster_time = 0;
mux->cluster_pos = 0;
+
+ /* reset meta-seek index */
+ mux->num_meta_indexes = 0;
+ g_free (mux->meta_index);
+ mux->meta_index = NULL;
}
static GstPadLinkReturn
@@ -734,6 +739,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
guint32 seekhead_id[] = { GST_MATROSKA_ID_INFO,
GST_MATROSKA_ID_TRACKS,
GST_MATROSKA_ID_CUES,
+ GST_MATROSKA_ID_SEEKHEAD,
#if 0
GST_MATROSKA_ID_TAGS,
#endif
@@ -870,6 +876,28 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
gst_ebml_write_flush_cache (ebml);
}
+ if (mux->meta_index != NULL) {
+ guint n;
+ guint64 master, seekentry_master;
+
+ mux->meta_pos = ebml->pos;
+ gst_ebml_write_set_cache (ebml, 12 + 28 * mux->num_meta_indexes);
+ master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
+
+ for (n = 0; n < mux->num_meta_indexes; n++) {
+ GstMatroskaMetaSeekIndex *idx = &mux->meta_index[n];
+
+ seekentry_master = gst_ebml_write_master_start (ebml,
+ GST_MATROSKA_ID_SEEKENTRY);
+ gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKID, idx->id);
+ gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPOSITION,
+ idx->pos - mux->segment_master);
+ gst_ebml_write_master_finish (ebml, seekentry_master);
+ }
+ gst_ebml_write_master_finish (ebml, master);
+ }
+ gst_ebml_write_flush_cache (ebml);
+
/* FIXME: tags */
/* update seekhead. We know that:
@@ -897,6 +925,17 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
gst_ebml_write_seek (ebml, my_pos);
}
+ if (mux->meta_index != NULL) {
+ gst_ebml_replace_uint (ebml, mux->seekhead_pos + 116,
+ mux->meta_pos - mux->segment_master);
+ } else {
+ /* void'ify */
+ guint64 my_pos = ebml->pos;
+
+ gst_ebml_write_seek (ebml, mux->seekhead_pos + 96);
+ gst_ebml_write_buffer_header (ebml, GST_EBML_ID_VOID, 26);
+ gst_ebml_write_seek (ebml, my_pos);
+ }
#if 0
gst_ebml_replace_uint (ebml, mux->seekhead_pos + 116,
mux->tags_pos - mux->segment_master);
@@ -977,6 +1016,8 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux)
if (mux->cluster) {
/* start a new cluster every two seconds */
if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf)) {
+ GstMatroskaMetaSeekIndex *idx;
+
gst_ebml_write_master_finish (ebml, mux->cluster);
mux->cluster_pos = ebml->pos;
mux->cluster =
@@ -984,14 +1025,32 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux)
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
+
+ if (mux->num_meta_indexes % 32 == 0) {
+ mux->meta_index = g_renew (GstMatroskaMetaSeekIndex, mux->meta_index,
+ mux->num_meta_indexes + 32);
+ }
+ idx = &mux->meta_index[mux->num_meta_indexes++];
+ idx->id = GST_MATROSKA_ID_CLUSTER;
+ idx->pos = mux->cluster_pos;
}
} else {
/* first cluster */
+ GstMatroskaMetaSeekIndex *idx;
+
mux->cluster_pos = ebml->pos;
mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE,
GST_BUFFER_TIMESTAMP (buf) / mux->time_scale);
mux->cluster_time = GST_BUFFER_TIMESTAMP (buf);
+
+ if (mux->num_meta_indexes % 32 == 0) {
+ mux->meta_index = g_renew (GstMatroskaMetaSeekIndex, mux->meta_index,
+ mux->num_meta_indexes + 32);
+ }
+ idx = &mux->meta_index[mux->num_meta_indexes++];
+ idx->id = GST_MATROSKA_ID_CLUSTER;
+ idx->pos = mux->cluster_pos;
}
cluster = mux->cluster;
diff --git a/gst/matroska/matroska-mux.h b/gst/matroska/matroska-mux.h
index 9e70750d..ce4c3275 100644
--- a/gst/matroska/matroska-mux.h
+++ b/gst/matroska/matroska-mux.h
@@ -62,6 +62,11 @@ typedef enum {
GST_MATROSKA_MUX_STATE_DATA,
} GstMatroskaMuxState;
+typedef struct _GstMatroskaMetaSeekIndex {
+ guint32 id;
+ guint64 pos;
+} GstMatroskaMetaSeekIndex;
+
typedef struct _GstMatroskaMux {
GstEbmlWrite parent;
@@ -101,13 +106,18 @@ typedef struct _GstMatroskaMux {
#endif
info_pos,
tracks_pos,
- duration_pos;
+ duration_pos,
+ meta_pos;
guint64 segment_master;
/* current cluster */
guint64 cluster,
cluster_time,
cluster_pos;
+
+ /* meta-seek info */
+ GstMatroskaMetaSeekIndex *meta_index;
+ guint num_meta_indexes;
} GstMatroskaMux;
typedef struct _GstMatroskaMuxClass {