diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | gst/matroska/ebml-write.c | 5 | ||||
-rw-r--r-- | gst/matroska/matroska-mux.c | 71 | ||||
-rw-r--r-- | gst/matroska/matroska-mux.h | 1 |
4 files changed, 81 insertions, 12 deletions
@@ -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; |