diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index cf61135529..51fb6c83ce 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -35,6 +35,7 @@ #include "avcodec.h" #include "bitstream.h" #include "dct.h" +#include "decode.h" #include "internal.h" #include "rdft.h" #include "wma_freqs.h" @@ -57,7 +58,7 @@ typedef struct BinkAudioContext { float root; DECLARE_ALIGNED(32, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE]; float previous[MAX_CHANNELS][BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block - uint8_t *packet_buffer; + AVPacket *pkt; union { RDFTContext rdft; DCTContext dct; @@ -140,6 +141,10 @@ static av_cold int decode_init(AVCodecContext *avctx) else return -1; + s->pkt = av_packet_alloc(); + if (!s->pkt) + return AVERROR(ENOMEM); + return 0; } @@ -269,12 +274,13 @@ static av_cold int decode_end(AVCodecContext *avctx) { BinkAudioContext * s = avctx->priv_data; av_freep(&s->bands); - av_freep(&s->packet_buffer); if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) ff_rdft_end(&s->trans.rdft); else if (CONFIG_BINKAUDIO_DCT_DECODER) ff_dct_end(&s->trans.dct); + av_packet_free(&s->pkt); + return 0; } @@ -285,32 +291,26 @@ static void get_bits_align32(BitstreamContext *s) bitstream_skip(s, n); } -static int decode_frame(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) +static int binkaudio_receive_frame(AVCodecContext *avctx, AVFrame *frame) { BinkAudioContext *s = avctx->priv_data; - AVFrame *frame = data; BitstreamContext *bc = &s->bc; - int ret, consumed = 0; + int ret; - if (!bitstream_bits_left(bc)) { - uint8_t *buf; - /* handle end-of-stream */ - if (!avpkt->size) { - *got_frame_ptr = 0; - return 0; - } - if (avpkt->size < 4) { + if (!s->pkt->data) { + ret = ff_decode_get_packet(avctx, s->pkt); + if (ret < 0) + return ret; + + if (s->pkt->size < 4) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } - buf = av_realloc(s->packet_buffer, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!buf) - return AVERROR(ENOMEM); - s->packet_buffer = buf; - memcpy(s->packet_buffer, avpkt->data, avpkt->size); - bitstream_init(bc, s->packet_buffer, avpkt->size * 8); - consumed = avpkt->size; + + ret = bitstream_init8(bc, s->pkt->data, s->pkt->size); + if (ret < 0) + goto fail; /* skip reported size */ bitstream_skip(bc, 32); @@ -329,11 +329,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } get_bits_align32(bc); + if (!bitstream_bits_left(bc)) { + memset(bc, 0, sizeof(*bc)); + av_packet_unref(s->pkt); + } frame->nb_samples = s->block_size / avctx->channels; - *got_frame_ptr = 1; - return consumed; + return 0; +fail: + av_packet_unref(s->pkt); + return ret; } AVCodec ff_binkaudio_rdft_decoder = { @@ -344,7 +350,7 @@ AVCodec ff_binkaudio_rdft_decoder = { .priv_data_size = sizeof(BinkAudioContext), .init = decode_init, .close = decode_end, - .decode = decode_frame, + .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, }; @@ -356,6 +362,6 @@ AVCodec ff_binkaudio_dct_decoder = { .priv_data_size = sizeof(BinkAudioContext), .init = decode_init, .close = decode_end, - .decode = decode_frame, + .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, };