Mercurial > libavformat.hg
diff matroskadec.c @ 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 | 2e2221a3febb |
children | 30bf0c9f940d |
line wrap: on
line diff
--- 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;