aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2008-05-08 21:47:31 +0000
committerAurelien Jacobs <aurel@gnuage.org>2008-05-08 21:47:31 +0000
commit53a1e82bd25f926679a165a6c632ccc799fddb3c (patch)
tree82785f3db0cf12c976594a88ee4ba79550f9e951
parent40d0e665d09aca5918c0b70b7045f32fae71f3eb (diff)
downloadffmpeg-53a1e82bd25f926679a165a6c632ccc799fddb3c.tar.gz
matroskadec: add support for track content encoding
Only the header strip method is supported for now. Originally committed as revision 13082 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/matroska.h16
-rw-r--r--libavformat/matroskadec.c157
2 files changed, 171 insertions, 2 deletions
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index 370a8bfd89..025eefb3e2 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -89,6 +89,8 @@
#define MATROSKA_ID_TRACKMINCACHE 0x6DE7
#define MATROSKA_ID_TRACKMAXCACHE 0x6DF8
#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383
+#define MATROSKA_ID_TRACKCONTENTENCODINGS 0x6D80
+#define MATROSKA_ID_TRACKCONTENTENCODING 0x6240
/* IDs in the trackvideo master */
#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3
@@ -108,6 +110,13 @@
#define MATROSKA_ID_AUDIOBITDEPTH 0x6264
#define MATROSKA_ID_AUDIOCHANNELS 0x9F
+/* IDs in the content encoding master */
+#define MATROSKA_ID_ENCODINGSCOPE 0x5032
+#define MATROSKA_ID_ENCODINGTYPE 0x5033
+#define MATROSKA_ID_ENCODINGCOMPRESSION 0x5034
+#define MATROSKA_ID_ENCODINGCOMPALGO 0x4254
+#define MATROSKA_ID_ENCODINGCOMPSETTINGS 0x4255
+
/* ID in the cues master */
#define MATROSKA_ID_POINTENTRY 0xBB
@@ -168,6 +177,13 @@ typedef enum {
MATROSKA_ASPECT_RATIO_MODE_FIXED = 0x2,
} MatroskaAspectRatioMode;
+typedef enum {
+ MATROSKA_TRACK_ENCODING_COMP_ZLIB = 0,
+ MATROSKA_TRACK_ENCODING_COMP_BZLIB = 1,
+ MATROSKA_TRACK_ENCODING_COMP_LZO = 2,
+ MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3,
+} MatroskaTrackEncodingCompAlgo;
+
/*
* These aren't in any way "matroska-form" things,
* it's just something I use in the muxer/demuxer.
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 25fbdd5967..4899fb4db7 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -55,6 +55,11 @@ typedef struct Track {
uint64_t default_duration;
MatroskaTrackFlags flags;
+
+ int encoding_scope;
+ int encoding_algo;
+ uint8_t *encoding_settings;
+ int encoding_settings_len;
} MatroskaTrack;
typedef struct MatroskaVideoTrack {
@@ -1428,6 +1433,147 @@ matroska_add_stream (MatroskaDemuxContext *matroska)
break;
}
+ case MATROSKA_ID_TRACKCONTENTENCODINGS: {
+ if ((res = ebml_read_master(matroska, &id)) < 0)
+ break;
+
+ while (res == 0) {
+ if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
+ res = AVERROR(EIO);
+ break;
+ } else if (matroska->level_up > 0) {
+ matroska->level_up--;
+ break;
+ }
+
+ switch (id) {
+ case MATROSKA_ID_TRACKCONTENTENCODING: {
+ int encoding_scope = 1;
+ if ((res = ebml_read_master(matroska, &id)) < 0)
+ break;
+
+ while (res == 0) {
+ if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
+ res = AVERROR(EIO);
+ break;
+ } else if (matroska->level_up > 0) {
+ matroska->level_up--;
+ break;
+ }
+
+ switch (id) {
+ case MATROSKA_ID_ENCODINGSCOPE: {
+ uint64_t num;
+ if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
+ break;
+ encoding_scope = num;
+ break;
+ }
+
+ case MATROSKA_ID_ENCODINGTYPE: {
+ uint64_t num;
+ if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
+ break;
+ if (num)
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Unsupported encoding type");
+ break;
+ }
+
+ case MATROSKA_ID_ENCODINGCOMPRESSION: {
+ if ((res = ebml_read_master(matroska, &id)) < 0)
+ break;
+
+ while (res == 0) {
+ if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {
+ res = AVERROR(EIO);
+ break;
+ } else if (matroska->level_up > 0) {
+ matroska->level_up--;
+ break;
+ }
+
+ switch (id) {
+ case MATROSKA_ID_ENCODINGCOMPALGO: {
+ uint64_t num;
+ if ((res = ebml_read_uint(matroska, &id, &num)) < 0)
+ break;
+ if (num != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP)
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Unsupported compression algo");
+ track->encoding_algo = num;
+ break;
+ }
+
+ case MATROSKA_ID_ENCODINGCOMPSETTINGS: {
+ uint8_t *data;
+ int size;
+ if ((res = ebml_read_binary(matroska, &id, &data, &size) < 0))
+ break;
+ track->encoding_settings = data;
+ track->encoding_settings_len = size;
+ break;
+ }
+
+ default:
+ av_log(matroska->ctx, AV_LOG_INFO,
+ "Unknown compression header entry "
+ "0x%x - ignoring\n", id);
+ /* pass-through */
+
+ case EBML_ID_VOID:
+ res = ebml_read_skip(matroska);
+ break;
+ }
+
+ if (matroska->level_up) {
+ matroska->level_up--;
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ av_log(matroska->ctx, AV_LOG_INFO,
+ "Unknown content encoding header entry "
+ "0x%x - ignoring\n", id);
+ /* pass-through */
+
+ case EBML_ID_VOID:
+ res = ebml_read_skip(matroska);
+ break;
+ }
+
+ if (matroska->level_up) {
+ matroska->level_up--;
+ break;
+ }
+ }
+
+ track->encoding_scope = encoding_scope;
+ break;
+ }
+
+ default:
+ av_log(matroska->ctx, AV_LOG_INFO,
+ "Unknown content encodings header entry "
+ "0x%x - ignoring\n", id);
+ /* pass-through */
+
+ case EBML_ID_VOID:
+ res = ebml_read_skip(matroska);
+ break;
+ }
+
+ if (matroska->level_up) {
+ matroska->level_up--;
+ break;
+ }
+ }
+ break;
+ }
+
default:
av_log(matroska->ctx, AV_LOG_INFO,
"Unknown track header entry 0x%x - ignoring\n", id);
@@ -2551,14 +2697,21 @@ matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,
} else {
int offset = 0;
+ if (matroska->tracks[track]->encoding_scope&1 &&
+ matroska->tracks[track]->encoding_algo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) {
+ offset = matroska->tracks[track]->encoding_settings_len;
+ }
+
pkt = av_mallocz(sizeof(AVPacket));
/* XXX: prevent data copy... */
- if (av_new_packet(pkt, lace_size[n]-offset) < 0) {
+ if (av_new_packet(pkt, lace_size[n]+offset) < 0) {
res = AVERROR(ENOMEM);
n = laces-1;
break;
}
- memcpy (pkt->data, data+offset, lace_size[n]-offset);
+ if (offset)
+ memcpy (pkt->data, matroska->tracks[track]->encoding_settings, offset);
+ memcpy (pkt->data+offset, data, lace_size[n]);
if (n == 0)
pkt->flags = is_keyframe;