|
|
|
@ -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, |
|
|
|
|
}; |
|
|
|
|