diff options
author | bnnm <bananaman255@gmail.com> | 2018-10-27 01:49:50 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2018-11-10 18:13:40 +0100 |
commit | 27e114b4511b771ccf2c64ab9f4a3d0391ace4ea (patch) | |
tree | 81b2b28ac8aca01b6236f972f29bbb1332e4e85c /libavcodec/wmaprodec.c | |
parent | 55e021f39b02e838672582dbe94fe279bfc8328c (diff) | |
download | ffmpeg-27e114b4511b771ccf2c64ab9f4a3d0391ace4ea.tar.gz |
avcodec/wmaprodec: improve XMA missing samples
Writes missing (delay) samples after EOF.
Signed-off-by: bnnm <bananaman255@gmail.com>
Diffstat (limited to 'libavcodec/wmaprodec.c')
-rw-r--r-- | libavcodec/wmaprodec.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 9439bfa771..d0fa974c80 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -210,6 +210,7 @@ typedef struct WMAProDecodeCtx { int subframe_offset; ///< subframe offset in the bit reservoir uint8_t packet_loss; ///< set in case of bitstream error uint8_t packet_done; ///< set when a packet is fully decoded + uint8_t eof_done; ///< set when EOF reached and extra subframe is written (XMA1/2) /* frame decode state */ uint32_t frame_num; ///< current frame number (not used for decoding) @@ -1609,7 +1610,34 @@ static int decode_packet(AVCodecContext *avctx, WMAProDecodeCtx *s, *got_frame_ptr = 0; - if (s->packet_done || s->packet_loss) { + if (!buf_size) { + AVFrame *frame = data; + int i; + + /** Must output remaining samples after stream end. WMAPRO 5.1 created + * by XWMA encoder don't though (maybe only 1/2ch streams need it). */ + s->packet_done = 0; + if (s->eof_done) + return 0; + + /** clean output buffer and copy last IMDCT samples */ + for (i = 0; i < s->nb_channels; i++) { + memset(frame->extended_data[i], 0, + s->samples_per_frame * sizeof(*s->channel[i].out)); + + memcpy(frame->extended_data[i], s->channel[i].out, + s->samples_per_frame * sizeof(*s->channel[i].out) >> 1); + } + + /* TODO: XMA should output 128 samples only (instead of 512) and WMAPRO + * maybe 768 (with 2048), XMA needs changes in multi-stream handling though. */ + + s->eof_done = 1; + s->packet_done = 1; + *got_frame_ptr = 1; + return 0; + } + else if (s->packet_done || s->packet_loss) { s->packet_done = 0; /** sanity check for the buffer length */ @@ -1922,6 +1950,7 @@ static void flush(WMAProDecodeCtx *s) sizeof(*s->channel[i].out)); s->packet_loss = 1; s->skip_packets = 0; + s->eof_done = 0; } @@ -1976,7 +2005,7 @@ AVCodec ff_xma1_decoder = { .init = xma_decode_init, .close = xma_decode_end, .decode = xma_decode_packet, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; @@ -1991,7 +2020,7 @@ AVCodec ff_xma2_decoder = { .close = xma_decode_end, .decode = xma_decode_packet, .flush = xma_flush, - .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; |