Mercurial > libavcodec.hg
changeset 10127:b17566dcfcc9 libavcodec
reduce output buffer needs
(fixes playback of some multichannel files)
author | faust3 |
---|---|
date | Sat, 05 Sep 2009 10:07:55 +0000 |
parents | 6ff9347c8042 |
children | da4c9cfcba71 |
files | wmaprodec.c |
diffstat | 1 files changed, 24 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/wmaprodec.c Sat Sep 05 09:56:06 2009 +0000 +++ b/wmaprodec.c Sat Sep 05 10:07:55 2009 +0000 @@ -194,11 +194,13 @@ int frame_offset; ///< frame offset in the bit reservoir int subframe_offset; ///< subframe offset in the bit reservoir uint8_t packet_loss; ///< set in case of bitstream error + uint8_t output_buffer_full; ///< flag indicating that the output buffer is full /* frame decode state */ uint32_t frame_num; ///< current frame number (not used for decoding) GetBitContext gb; ///< bitstream reader context int buf_bit_size; ///< buffer size in bits + float* samples_start; ///< start samplebuffer pointer float* samples; ///< current samplebuffer pointer float* samples_end; ///< maximum samplebuffer pointer uint8_t drc_gain; ///< gain for the DRC tool @@ -1256,9 +1258,13 @@ /** check for potential output buffer overflow */ if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) { - av_log(s->avctx, AV_LOG_ERROR, - "not enough space for the output samples\n"); - s->packet_loss = 1; + /** return an error if no frame could be decoded at all */ + if (s->samples_start == s->samples) { + av_log(s->avctx, AV_LOG_ERROR, + "not enough space for the output samples\n"); + s->packet_loss = 1; + } else + s->output_buffer_full = 1; return 0; } @@ -1451,11 +1457,12 @@ int packet_sequence_number; s->samples = data; + s->samples_start = data; s->samples_end = (float*)((int8_t*)data + *data_size); - s->buf_bit_size = buf_size << 3; + *data_size = 0; - - *data_size = 0; + if (!s->output_buffer_full) { + s->buf_bit_size = buf_size << 3; /** sanity check for the buffer length */ if (buf_size < avctx->block_align) @@ -1498,8 +1505,15 @@ } s->packet_loss = 0; + + } else { + /** continue decoding */ + s->output_buffer_full = 0; + more_frames = decode_frame(s); + } + /** decode the rest of the packet */ - while (!s->packet_loss && more_frames && + while (!s->packet_loss && !s->output_buffer_full && more_frames && remaining_bits(s, gb) > s->log2_frame_size) { int frame_size = show_bits(gb, s->log2_frame_size); @@ -1517,7 +1531,8 @@ more_frames = 0; } - if (!s->packet_loss && remaining_bits(s, gb) > 0) { + if (!s->output_buffer_full && !s->packet_loss && + remaining_bits(s, gb) > 0) { /** save the rest of the data so that it can be decoded with the next packet */ save_bits(s, gb, remaining_bits(s, gb), 0); @@ -1525,7 +1540,7 @@ *data_size = (int8_t *)s->samples - (int8_t *)data; - return avctx->block_align; + return (s->output_buffer_full)?0: avctx->block_align; } /**