diff options
author | Aurelien Jacobs <aurel@gnuage.org> | 2008-05-08 21:47:31 +0000 |
---|---|---|
committer | Aurelien Jacobs <aurel@gnuage.org> | 2008-05-08 21:47:31 +0000 |
commit | 53a1e82bd25f926679a165a6c632ccc799fddb3c (patch) | |
tree | 82785f3db0cf12c976594a88ee4ba79550f9e951 /libavformat/matroskadec.c | |
parent | 40d0e665d09aca5918c0b70b7045f32fae71f3eb (diff) | |
download | ffmpeg-streaming-53a1e82bd25f926679a165a6c632ccc799fddb3c.zip ffmpeg-streaming-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
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r-- | libavformat/matroskadec.c | 157 |
1 files changed, 155 insertions, 2 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 25fbdd5..4899fb4 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; |