binkaudio: switch to the new send/receive API

It is more natural for this codec and allows to avoid awkward constructs
like "consuming 0 bytes from input". Also, keep a reference to the input
packet to avoid unnecessary copying.
This commit is contained in:
Anton Khirnov 2016-11-24 23:05:20 +01:00
parent fa1749dd34
commit 730c023260
1 changed files with 32 additions and 26 deletions

View File

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