diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2008-11-05 14:42:35 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2008-11-05 14:42:35 +0000 |
commit | ff5c03555467d44f66c4112500f57011872a87c0 (patch) | |
tree | 332946bcb2034f6c1ad8814a47ef226178917d89 /gst/matroska | |
parent | a50de826a2cfc400423c9259ef8c6e5aa8208d7d (diff) |
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.
Diffstat (limited to 'gst/matroska')
-rw-r--r-- | gst/matroska/matroska-ids.h | 2 | ||||
-rw-r--r-- | gst/matroska/matroska-mux.c | 73 |
2 files changed, 75 insertions, 0 deletions
diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h index 19503500..a1e03777 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 e77d1d82..0b24c543 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 |