Commit 7551a559 authored by Sascha Sommer's avatar Sascha Sommer

reduce output buffer needs

(fixes playback of some multichannel files)

Originally committed as revision 19763 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 20169324
...@@ -194,11 +194,13 @@ typedef struct WMAProDecodeCtx { ...@@ -194,11 +194,13 @@ typedef struct WMAProDecodeCtx {
int frame_offset; ///< frame offset in the bit reservoir int frame_offset; ///< frame offset in the bit reservoir
int subframe_offset; ///< subframe 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 packet_loss; ///< set in case of bitstream error
uint8_t output_buffer_full; ///< flag indicating that the output buffer is full
/* frame decode state */ /* frame decode state */
uint32_t frame_num; ///< current frame number (not used for decoding) uint32_t frame_num; ///< current frame number (not used for decoding)
GetBitContext gb; ///< bitstream reader context GetBitContext gb; ///< bitstream reader context
int buf_bit_size; ///< buffer size in bits int buf_bit_size; ///< buffer size in bits
float* samples_start; ///< start samplebuffer pointer
float* samples; ///< current samplebuffer pointer float* samples; ///< current samplebuffer pointer
float* samples_end; ///< maximum samplebuffer pointer float* samples_end; ///< maximum samplebuffer pointer
uint8_t drc_gain; ///< gain for the DRC tool uint8_t drc_gain; ///< gain for the DRC tool
...@@ -1256,9 +1258,13 @@ static int decode_frame(WMAProDecodeCtx *s) ...@@ -1256,9 +1258,13 @@ static int decode_frame(WMAProDecodeCtx *s)
/** check for potential output buffer overflow */ /** check for potential output buffer overflow */
if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) { if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
av_log(s->avctx, AV_LOG_ERROR, /** return an error if no frame could be decoded at all */
"not enough space for the output samples\n"); if (s->samples_start == s->samples) {
s->packet_loss = 1; 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; return 0;
} }
...@@ -1451,12 +1457,13 @@ static int decode_packet(AVCodecContext *avctx, ...@@ -1451,12 +1457,13 @@ static int decode_packet(AVCodecContext *avctx,
int packet_sequence_number; int packet_sequence_number;
s->samples = data; s->samples = data;
s->samples_start = data;
s->samples_end = (float*)((int8_t*)data + *data_size); 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 */ /** sanity check for the buffer length */
if (buf_size < avctx->block_align) if (buf_size < avctx->block_align)
return 0; return 0;
...@@ -1498,8 +1505,15 @@ static int decode_packet(AVCodecContext *avctx, ...@@ -1498,8 +1505,15 @@ static int decode_packet(AVCodecContext *avctx,
} }
s->packet_loss = 0; s->packet_loss = 0;
} else {
/** continue decoding */
s->output_buffer_full = 0;
more_frames = decode_frame(s);
}
/** decode the rest of the packet */ /** 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) { remaining_bits(s, gb) > s->log2_frame_size) {
int frame_size = show_bits(gb, s->log2_frame_size); int frame_size = show_bits(gb, s->log2_frame_size);
...@@ -1517,7 +1531,8 @@ static int decode_packet(AVCodecContext *avctx, ...@@ -1517,7 +1531,8 @@ static int decode_packet(AVCodecContext *avctx,
more_frames = 0; 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 /** save the rest of the data so that it can be decoded
with the next packet */ with the next packet */
save_bits(s, gb, remaining_bits(s, gb), 0); save_bits(s, gb, remaining_bits(s, gb), 0);
...@@ -1525,7 +1540,7 @@ static int decode_packet(AVCodecContext *avctx, ...@@ -1525,7 +1540,7 @@ static int decode_packet(AVCodecContext *avctx,
*data_size = (int8_t *)s->samples - (int8_t *)data; *data_size = (int8_t *)s->samples - (int8_t *)data;
return avctx->block_align; return (s->output_buffer_full)?0: avctx->block_align;
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment