summaryrefslogtreecommitdiffstats
path: root/gst/matroska
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-11-05 14:42:35 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-11-05 14:42:35 +0000
commitff5c03555467d44f66c4112500f57011872a87c0 (patch)
tree332946bcb2034f6c1ad8814a47ef226178917d89 /gst/matroska
parenta50de826a2cfc400423c9259ef8c6e5aa8208d7d (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.h2
-rw-r--r--gst/matroska/matroska-mux.c73
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