From ff5c03555467d44f66c4112500f57011872a87c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 5 Nov 2008 14:42:35 +0000 Subject: [PATCH] gst/matroska/: Implement Dirac muxing into Matroska comforming to the spec, i.e. put all Dirac packages up to a pictu... Original commit message from CVS: * gst/matroska/matroska-ids.h: * gst/matroska/matroska-mux.c: (gst_matroska_pad_free), (gst_matroska_mux_handle_dirac_packet), (gst_matroska_mux_write_data): Implement Dirac muxing into Matroska comforming to the spec, i.e. put all Dirac packages up to a picture into a Matroska block. TODO: Implement writing of the ReferenceBlock Matroska elements, currently the Dirac muxing is only 100% correct if Matroska version 2 is selected for muxing. --- ChangeLog | 13 +++++++ gst/matroska/matroska-ids.h | 2 + gst/matroska/matroska-mux.c | 73 +++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/ChangeLog b/ChangeLog index 873f5300a6..c64fad6a43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-11-05 Sebastian Dröge + + * gst/matroska/matroska-ids.h: + * gst/matroska/matroska-mux.c: (gst_matroska_pad_free), + (gst_matroska_mux_handle_dirac_packet), + (gst_matroska_mux_write_data): + Implement Dirac muxing into Matroska comforming to the spec, i.e. + put all Dirac packages up to a picture into a Matroska block. + + TODO: Implement writing of the ReferenceBlock Matroska elements, + currently the Dirac muxing is only 100% correct if Matroska version 2 + is selected for muxing. + 2008-11-04 Sebastian Dröge Patch by: Bastien Nocera , diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h index 195035000a..a1e03777de 100644 --- a/gst/matroska/matroska-ids.h +++ b/gst/matroska/matroska-ids.h @@ -517,6 +517,8 @@ typedef struct _GstMatroskaTrackVideoContext { gdouble default_fps; GstMatroskaAspectRatioMode asr_mode; guint32 fourcc; + + GstBuffer *dirac_unit; } GstMatroskaTrackVideoContext; typedef struct _GstMatroskaTrackAudioContext { diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index e77d1d82f7..0b24c543dc 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -364,6 +364,16 @@ static void gst_matroska_pad_free (GstMatroskaPad * collect_pad) { /* free track information */ + if (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_VIDEO) { + GstMatroskaTrackVideoContext *ctx = + (GstMatroskaTrackVideoContext *) collect_pad->track; + + if (ctx->dirac_unit) { + gst_buffer_unref (ctx->dirac_unit); + ctx->dirac_unit = NULL; + } + } + if (collect_pad->track != NULL) { g_free (collect_pad->track->codec_id); g_free (collect_pad->track->codec_name); @@ -1939,6 +1949,61 @@ gst_matroska_mux_create_buffer_header (GstMatroskaTrackContext * track, return hdr; } +static GstBuffer * +gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux, + GstMatroskaPad * collect_pad, GstBuffer * buf) +{ + GstMatroskaTrackVideoContext *ctx = + (GstMatroskaTrackVideoContext *) collect_pad->track; + const guint8 *data = GST_BUFFER_DATA (buf); + guint8 parse_code; + GstBuffer *ret = NULL; + + if (GST_BUFFER_SIZE (buf) < 13) { + gst_buffer_unref (buf); + return ret; + } + + if (GST_READ_UINT32_BE (data) != 0x42424344) { + gst_buffer_unref (buf); + return ret; + } + + parse_code = GST_READ_UINT8 (data + 4); + + switch (parse_code) { + case 0x00: + if (ctx->dirac_unit) { + gst_buffer_unref (ctx->dirac_unit); + } + ctx->dirac_unit = buf; + break; + case 0x10: + case 0x20: + case 0x30: + if (ctx->dirac_unit) + ctx->dirac_unit = gst_buffer_join (ctx->dirac_unit, buf); + else + ctx->dirac_unit = buf; + break; + default: + /* picture */ + if (ctx->dirac_unit) { + ret = gst_buffer_join (ctx->dirac_unit, gst_buffer_ref (buf)); + ctx->dirac_unit = NULL; + ret = gst_buffer_make_metadata_writable (ret); + gst_buffer_copy_metadata (ret, buf, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | + GST_BUFFER_COPY_CAPS); + } else { + ret = buf; + } + break; + } + + return ret; +} + /** * gst_matroska_mux_write_data: * @mux: #GstMatroskaMux @@ -1972,6 +2037,14 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) return GST_FLOW_OK; } + /* for dirac we have to queue up everything up to a picture unit */ + if (strcmp (collect_pad->track->codec_id, + GST_MATROSKA_CODEC_ID_VIDEO_DIRAC) == 0) { + buf = gst_matroska_mux_handle_dirac_packet (mux, collect_pad, buf); + if (!buf) + return GST_FLOW_OK; + } + /* hm, invalid timestamp (due to --to be fixed--- element upstream); * this would wreak havoc with time stored in matroska file */ /* TODO: maybe calculate a timestamp by using the previous timestamp