Mercurial > libavformat.hg
changeset 3279:807c5f54e8b5 libavformat
matroskadec: add support for track content encoding
Only the header strip method is supported for now.
author | aurel |
---|---|
date | Thu, 08 May 2008 21:47:31 +0000 |
parents | 1de87c1b6a12 |
children | 30bf0c9f940d |
files | matroska.h matroskadec.c |
diffstat | 2 files changed, 171 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/matroska.h Tue May 06 09:16:36 2008 +0000 +++ b/matroska.h Thu May 08 21:47:31 2008 +0000 @@ -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 @@ 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.
--- a/matroskadec.c Tue May 06 09:16:36 2008 +0000 +++ b/matroskadec.c Thu May 08 21:47:31 2008 +0000 @@ -55,6 +55,11 @@ 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 @@ 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 @@ } 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;