X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fbinkaudio.c;h=e0f3d14eef2ca31adf9ec87e8b4a6833b2c1a8b9;hb=f089e02fa2b7716d9fa5228c734e55678437db85;hp=f1fa2ab882c892fab6eba7146bbae90e535ce401;hpb=b5a42c7f098a0eaee9cb08ce8b26b0c9a307d9c4;p=ffmpeg diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index f1fa2ab882c..e0f3d14eef2 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -34,6 +34,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" #include "dct.h" +#include "decode.h" #include "get_bits.h" #include "internal.h" #include "rdft.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; } @@ -284,34 +290,26 @@ static void get_bits_align32(GetBitContext *s) if (n) skip_bits(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; GetBitContext *gb = &s->gb; - int ret, consumed = 0; + int ret; - if (!get_bits_left(gb)) { - 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); - memset(buf + avpkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - s->packet_buffer = buf; - memcpy(s->packet_buffer, avpkt->data, avpkt->size); - if ((ret = init_get_bits8(gb, s->packet_buffer, avpkt->size)) < 0) - return ret; - consumed = avpkt->size; + + ret = init_get_bits8(gb, s->pkt->data, s->pkt->size); + if (ret < 0) + goto fail; /* skip reported size */ skip_bits_long(gb, 32); @@ -328,11 +326,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } get_bits_align32(gb); + if (!get_bits_left(gb)) { + memset(gb, 0, sizeof(*gb)); + 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 = { @@ -343,7 +347,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, }; @@ -355,6 +359,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, };