diff options
author | Paul B Mahol <onemda@gmail.com> | 2016-04-13 20:21:07 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2016-04-13 22:56:33 +0200 |
commit | 5ac71e9db84c83d5b52904c6910bb4a52d184931 (patch) | |
tree | 46cce02edac6918b22901874aa62dd35d59509cf | |
parent | 3c0511f29e9e775c709a8e7e9c8c9729724a8b65 (diff) | |
download | ffmpeg-5ac71e9db84c83d5b52904c6910bb4a52d184931.tar.gz |
avcodec/wmalosslessdec: improve >2 channel support
Before it worked for stereo files only.
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r-- | libavcodec/wmalosslessdec.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index c41eb6ced6..4d50915615 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -72,7 +72,8 @@ typedef struct WmallDecodeCtx { AVCodecContext *avctx; AVFrame *frame; LLAudDSPContext dsp; ///< accelerated DSP functions - uint8_t frame_data[MAX_FRAMESIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< compressed frame data + uint8_t *frame_data; ///< compressed frame data + int max_frame_size; ///< max bitstream size PutBitContext pb; ///< context for filling the frame_data buffer /* frame size dependent frame information (set during initialization) */ @@ -190,9 +191,14 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } + s->max_frame_size = MAX_FRAMESIZE * avctx->channels; + s->frame_data = av_mallocz(s->max_frame_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!s->frame_data) + return AVERROR(ENOMEM); + s->avctx = avctx; ff_llauddsp_init(&s->dsp); - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + init_put_bits(&s->pb, s->frame_data, s->max_frame_size); if (avctx->extradata_size >= 18) { s->decode_flags = AV_RL16(edata_ptr + 14); @@ -1124,12 +1130,12 @@ static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, if (!append) { s->frame_offset = get_bits_count(gb) & 7; s->num_saved_bits = s->frame_offset; - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + init_put_bits(&s->pb, s->frame_data, s->max_frame_size); } buflen = (s->num_saved_bits + len + 8) >> 3; - if (len <= 0 || buflen > MAX_FRAMESIZE) { + if (len <= 0 || buflen > s->max_frame_size) { avpriv_request_sample(s->avctx, "Too small input buffer"); s->packet_loss = 1; return; @@ -1175,14 +1181,9 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, if (!buf_size) return 0; - /* sanity check for the buffer length */ - if (buf_size < avctx->block_align) { - av_log(avctx, AV_LOG_ERROR, "buf size %d invalid\n", buf_size); - return AVERROR_INVALIDDATA; - } - s->next_packet_start = buf_size - avctx->block_align; - buf_size = avctx->block_align; + s->next_packet_start = buf_size - FFMIN(avctx->block_align, buf_size); + buf_size = FFMIN(avctx->block_align, buf_size); s->buf_bit_size = buf_size << 3; /* parse packet header */ @@ -1230,7 +1231,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, * to decode incomplete frames in the s->len_prefix == 0 case. */ s->num_saved_bits = 0; s->packet_loss = 0; - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + init_put_bits(&s->pb, s->frame_data, s->max_frame_size); } } else { @@ -1284,7 +1285,7 @@ static void flush(AVCodecContext *avctx) s->next_packet_start = 0; s->cdlms[0][0].order = 0; s->frame->nb_samples = 0; - init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + init_put_bits(&s->pb, s->frame_data, s->max_frame_size); } static av_cold int decode_close(AVCodecContext *avctx) @@ -1292,6 +1293,7 @@ static av_cold int decode_close(AVCodecContext *avctx) WmallDecodeCtx *s = avctx->priv_data; av_frame_free(&s->frame); + av_freep(&s->frame_data); return 0; } |