diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-05-28 11:58:46 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-05-28 11:58:46 +0200 |
commit | 3ed3aaab32f58dab2a841a95e032e871d928fb7f (patch) | |
tree | 86cdfb67870860e42d568d965ca1cfff242cd586 /libavformat | |
parent | 8012f93ed8afbf0b45fa378085cd4b000e30057f (diff) | |
parent | 851bc1d6be0c7485609e0208d188f3edbc4ade13 (diff) | |
download | ffmpeg-3ed3aaab32f58dab2a841a95e032e871d928fb7f.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
smacker: assign video frame PTS
matroskadec: export full wavpack blocks.
Conflicts:
libavcodec/wavpack.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/matroskadec.c | 98 | ||||
-rw-r--r-- | libavformat/smacker.c | 1 |
2 files changed, 99 insertions, 0 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b82f289e9f..60bb73b327 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2144,6 +2144,88 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, return 0; } + +/* reconstruct full wavpack blocks from mangled matroska ones */ +static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, + uint8_t **pdst, int *size) +{ + uint8_t *dst = NULL; + int dstlen = 0; + int srclen = *size; + uint32_t samples; + uint16_t ver; + int ret, offset = 0; + + if (srclen < 12 || track->stream->codec->extradata_size < 2) + return AVERROR_INVALIDDATA; + + ver = AV_RL16(track->stream->codec->extradata); + + samples = AV_RL32(src); + src += 4; + srclen -= 4; + + while (srclen >= 8) { + int multiblock; + uint32_t blocksize; + uint8_t *tmp; + + uint32_t flags = AV_RL32(src); + uint32_t crc = AV_RL32(src + 4); + src += 8; + srclen -= 8; + + multiblock = (flags & 0x1800) != 0x1800; + if (multiblock) { + if (srclen < 4) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + blocksize = AV_RL32(src); + src += 4; + srclen -= 4; + } else + blocksize = srclen; + + if (blocksize > srclen) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + + tmp = av_realloc(dst, dstlen + blocksize + 32); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst = tmp; + dstlen += blocksize + 32; + + AV_WL32(dst + offset, MKTAG('w', 'v', 'p', 'k')); // tag + AV_WL32(dst + offset + 4, blocksize + 24); // blocksize - 8 + AV_WL16(dst + offset + 8, ver); // version + AV_WL16(dst + offset + 10, 0); // track/index_no + AV_WL32(dst + offset + 12, 0); // total samples + AV_WL32(dst + offset + 16, 0); // block index + AV_WL32(dst + offset + 20, samples); // number of samples + AV_WL32(dst + offset + 24, flags); // flags + AV_WL32(dst + offset + 28, crc); // crc + memcpy (dst + offset + 32, src, blocksize); // block data + + src += blocksize; + srclen -= blocksize; + offset += blocksize + 32; + } + + *pdst = dst; + *size = dstlen; + + return 0; + +fail: + av_freep(&dst); + return ret; +} + static int matroska_parse_frame(MatroskaDemuxContext *matroska, MatroskaTrack *track, AVStream *st, @@ -2163,6 +2245,18 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, return res; } + if (st->codec->codec_id == AV_CODEC_ID_WAVPACK) { + uint8_t *wv_data; + res = matroska_parse_wavpack(track, pkt_data, &wv_data, &pkt_size); + if (res < 0) { + av_log(matroska->ctx, AV_LOG_ERROR, "Error parsing a wavpack block.\n"); + goto fail; + } + if (pkt_data != data) + av_freep(&pkt_data); + pkt_data = wv_data; + } + if (st->codec->codec_id == AV_CODEC_ID_PRORES) offset = 8; @@ -2249,6 +2343,10 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, #endif return 0; +fail: + if (pkt_data != data) + av_freep(&pkt_data); + return res; } static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 7f270b48b1..e04a214ff3 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -338,6 +338,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) if(ret != frame_size) return AVERROR(EIO); pkt->stream_index = smk->videoindex; + pkt->pts = smk->cur_frame; pkt->size = ret + 769; smk->cur_frame++; smk->nextpos = avio_tell(s->pb); |