summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArwed v. Merkatz <v.merkatz@gmx.net>2004-08-26 11:10:16 +0000
committerArwed v. Merkatz <v.merkatz@gmx.net>2004-08-26 11:10:16 +0000
commit356279a65b463071244ff9d46d014de8446d605d (patch)
treeba508b3271e32546f8ecb646e22303e9407f0a0e
parent80badd5a94710428ce0f6950a5c0c0d5ad51130f (diff)
Fix byte order reversion for writing ebml floats.
Original commit message from CVS: Fix byte order reversion for writing ebml floats. Write segment duration and muxing application in matroska. Added TTA codec to the list of supported codecs to mux into matroska.
-rw-r--r--ChangeLog16
-rw-r--r--gst/matroska/ebml-write.c5
-rw-r--r--gst/matroska/matroska-mux.c71
-rw-r--r--gst/matroska/matroska-mux.h1
4 files changed, 81 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 55d3a9eb..086b0525 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2004-08-26 Arwed v. Merkatz <v.merkatz@gmx.net>
+
+ * gst/matroska/ebml-write.c: (gst_ebml_write_float),
+ fix byte order reversion on little endian machines.
+ * gst/matroska/matroska-mux.c: (audiosink_templ),
+ (gst_matroska_mux_audio_pad_link):
+ add TTA codec to the list of supported codecs.
+ * gst/matroska/matroska-mux.c: (gst_matroska_mux_init),
+ (gst_matroska_mux_start), (gst_matroska_mux_finish),
+ (gst_matroska_mux_write_data):
+ * gst/matroska/matroska-mux.h:
+ write segment duration correctly, write muxing app string, fixes bugs
+ #140897 and #140898.
+ * gst/matroska/matroska-mux.c: (gst_matroska_mux_loop),
+ wait for all pads to be negotiated before starting to mux.
+
2004-08-26 Zaheer Abbas Merali <zaheerabbas at merali dot org>
* ext/lame/gstlame.c: (gst_lame_init), (gst_lame_chain):
diff --git a/gst/matroska/ebml-write.c b/gst/matroska/ebml-write.c
index e59c5a49..30a9c420 100644
--- a/gst/matroska/ebml-write.c
+++ b/gst/matroska/ebml-write.c
@@ -402,9 +402,10 @@ gst_ebml_write_float (GstEbmlWrite * ebml, guint32 id, gdouble num)
gst_ebml_write_element_id (buf, id);
gst_ebml_write_element_size (buf, 8);
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
- for (n = 0; n < 8; n++)
+ for (n = 0; n < 8; n++) {
GST_BUFFER_DATA (buf)[GST_BUFFER_SIZE (buf)] = ((guint8 *) & num)[7 - n];
- GST_BUFFER_SIZE (buf) += 8;
+ GST_BUFFER_SIZE (buf) += 1;
+ }
#else
gst_ebml_write_element_data (buf, (guint8 *) & num, 8);
#endif
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index 736a9aa6..4ddc4aea 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -101,7 +101,11 @@ static GstStaticPadTemplate audiosink_templ =
"width = (int) { 8, 16, 24 }, "
"depth = (int) { 8, 16, 24 }, "
"endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
- "signed = (boolean) { true, false }, " COMMON_AUDIO_CAPS)
+ "signed = (boolean) { true, false }, "
+ COMMON_AUDIO_CAPS ";"
+ "audio/x-raw-tta, "
+ "width = (int) { 8, 16, 24 }, "
+ "channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]")
);
static GstStaticPadTemplate subtitlesink_templ =
@@ -230,6 +234,7 @@ gst_matroska_mux_init (GstMatroskaMux * mux)
for (i = 0; i < GST_MATROSKA_MUX_MAX_STREAMS; i++) {
mux->sink[i].buffer = NULL;
mux->sink[i].track = NULL;
+ mux->sink[i].duration = 0;
}
mux->index = NULL;
@@ -494,6 +499,14 @@ gst_matroska_mux_audio_pad_link (GstPad * pad, const GstCaps * caps)
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_AC3);
return GST_PAD_LINK_OK;
+ } else if (!strcmp (mimetype, "audio/x-raw-tta")) {
+ gint width;
+
+ gst_structure_get_int (structure, "width", &width);
+ audiocontext->bitdepth = width;
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_TTA);
+
+ return GST_PAD_LINK_OK;
}
return GST_PAD_LINK_REFUSED;
@@ -655,6 +668,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
guint64 master, child;
gint i;
guint tracknum = 1;
+ gdouble duration = 0;
/* we start with a EBML header */
gst_ebml_write_header (ebml, "matroska", 1);
@@ -683,10 +697,24 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_INFO);
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
mux->duration_pos = ebml->pos;
- gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION, 0);
- gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP, "GStreamer");
- if (mux->metadata &&
- gst_structure_has_field (gst_caps_get_structure (mux->metadata, 0),
+ /* get duration */
+ for (i = 0; i < mux->num_streams; i++) {
+ gint64 trackduration;
+ GstFormat format = GST_FORMAT_TIME;
+
+ if (gst_pad_query (GST_PAD_PEER (mux->sink[i].track->pad), GST_QUERY_TOTAL,
+ &format, &trackduration)) {
+ if ((gdouble) trackduration > duration) {
+ duration = (gdouble) trackduration;
+ }
+ }
+ }
+ gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
+ duration / mux->time_scale);
+ gst_ebml_write_utf8 (ebml, GST_MATROSKA_ID_MUXINGAPP,
+ "GStreamer plugin version " GST_PLUGINS_VERSION);
+ if (mux->metadata
+ && gst_structure_has_field (gst_caps_get_structure (mux->metadata, 0),
"application")) {
const gchar *app;
@@ -722,6 +750,8 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
{
GstEbmlWrite *ebml = GST_EBML_WRITE (mux);
guint64 pos;
+ guint64 duration = 0;
+ gint i;
/* cues */
if (mux->index != NULL) {
@@ -785,11 +815,18 @@ gst_matroska_mux_finish (GstMatroskaMux * mux)
#endif
/* update duration */
- pos = GST_EBML_WRITE (mux)->pos;
- gst_ebml_write_seek (ebml, mux->duration_pos);
- gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
- mux->duration / mux->time_scale);
- gst_ebml_write_seek (ebml, pos);
+ /* first get the overall duration */
+ for (i = 0; i < mux->num_streams; i++) {
+ if (mux->sink[i].duration > duration)
+ duration = mux->sink[i].duration;
+ }
+ if (duration != 0) {
+ pos = GST_EBML_WRITE (mux)->pos;
+ gst_ebml_write_seek (ebml, mux->duration_pos);
+ gst_ebml_write_float (ebml, GST_MATROSKA_ID_DURATION,
+ (gdouble) duration / mux->time_scale);
+ gst_ebml_write_seek (ebml, pos);
+ }
/* finish segment - this also writes element length */
gst_ebml_write_master_finish (ebml, mux->segment_pos);
@@ -849,6 +886,10 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux)
buf = mux->sink[i].buffer;
mux->sink[i].buffer = NULL;
+ /* update duration of this track */
+ if (GST_BUFFER_DURATION_IS_VALID (buf))
+ mux->sink[i].duration += GST_BUFFER_DURATION (buf);
+
/* We currently write an index entry for each keyframe in a
* video track. This can be largely improved, such as doing
* one for each keyframe or each second (for all-keyframe
@@ -895,9 +936,19 @@ static void
gst_matroska_mux_loop (GstElement * element)
{
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
+ guint i;
/* start with a header */
if (mux->state == GST_MATROSKA_MUX_STATE_START) {
+ if (mux->num_streams == 0) {
+ return;
+ }
+ for (i = 0; i < mux->num_streams; i++) {
+ if (!gst_pad_is_negotiated (mux->sink[i].track->pad)) {
+ return;
+ } else {
+ }
+ }
mux->state = GST_MATROSKA_MUX_STATE_HEADER;
gst_matroska_mux_start (mux);
mux->state = GST_MATROSKA_MUX_STATE_DATA;
diff --git a/gst/matroska/matroska-mux.h b/gst/matroska/matroska-mux.h
index 119237c9..78f31faf 100644
--- a/gst/matroska/matroska-mux.h
+++ b/gst/matroska/matroska-mux.h
@@ -57,6 +57,7 @@ typedef struct _GstMatroskaMux {
GstMatroskaTrackContext *track;
GstBuffer *buffer;
gboolean eos;
+ guint64 duration;
} sink[GST_MATROSKA_MUX_MAX_STREAMS];
guint num_streams,
num_v_streams, num_a_streams, num_t_streams;