summaryrefslogtreecommitdiff
path: root/libavcodec/wmaprodec.c
diff options
context:
space:
mode:
authorbnnm <bananaman255@gmail.com>2018-10-27 01:49:50 +0200
committerPaul B Mahol <onemda@gmail.com>2018-11-10 18:13:40 +0100
commit27e114b4511b771ccf2c64ab9f4a3d0391ace4ea (patch)
tree81b2b28ac8aca01b6236f972f29bbb1332e4e85c /libavcodec/wmaprodec.c
parent55e021f39b02e838672582dbe94fe279bfc8328c (diff)
downloadffmpeg-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.c35
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 },
};