[FFmpeg-cvslog] shorten: fix end-of-stream decoding.
Justin Ruggles
git at videolan.org
Fri Oct 21 02:37:10 CEST 2011
ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Fri Sep 16 21:34:42 2011 -0400| [1baa25c7dae0b43f0ff845f8ab4a94bf15b02440] | committer: Justin Ruggles
shorten: fix end-of-stream decoding.
enable CODEC_CAP_DELAY to flush any remaining frames in the buffer.
Stop decoding when the FN_QUIT command is found so that a trailing seek table
isn't decoded as a normal frame.
decode all channels in the same call to avcodec_decode_audio3() so that
decoding will not stop after the first channel of the last frame.
Updated FATE reference. More valid audio is now decoded.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1baa25c7dae0b43f0ff845f8ab4a94bf15b02440
---
libavcodec/shorten.c | 47 +++++++++++++++++++++++----------
tests/ref/fate/lossless-shortenaudio | 2 +-
2 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index 2732aab..f510bcc 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -103,6 +103,7 @@ typedef struct ShortenContext {
int bitindex;
int32_t lpcqoffset;
int got_header;
+ int got_quit_command;
} ShortenContext;
static av_cold int shorten_decode_init(AVCodecContext * avctx)
@@ -425,13 +426,15 @@ static int shorten_decode_frame(AVCodecContext *avctx,
memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
s->bitstream_index=0;
}
- memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
+ if (buf)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
buf= &s->bitstream[s->bitstream_index];
buf_size += s->bitstream_size;
s->bitstream_size= buf_size;
- /* do not decode until buffer has at least max_framesize bytes */
- if(buf_size < s->max_framesize){
+ /* do not decode until buffer has at least max_framesize bytes or
+ the end of the file has been reached */
+ if (buf_size < s->max_framesize && avpkt->data) {
*data_size = 0;
return input_buf_size;
}
@@ -445,20 +448,31 @@ static int shorten_decode_frame(AVCodecContext *avctx,
if ((ret = read_header(s)) < 0)
return ret;
*data_size = 0;
+ goto finish_frame;
}
- else
- {
+
+ /* if quit command was read previously, don't decode anything */
+ if (s->got_quit_command) {
+ *data_size = 0;
+ return avpkt->size;
+ }
+
+ s->cur_chan = 0;
+ while (s->cur_chan < s->channels) {
int cmd;
int len;
+
+ if (get_bits_left(&s->gb) < 3+FNSIZE) {
+ *data_size = 0;
+ break;
+ }
+
cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
if (cmd > FN_VERBATIM) {
av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
- if (s->bitstream_size > 0) {
- s->bitstream_index++;
- s->bitstream_size--;
- }
- return -1;
+ *data_size = 0;
+ break;
}
if (!is_audio_command[cmd]) {
@@ -488,9 +502,13 @@ static int shorten_decode_frame(AVCodecContext *avctx,
break;
}
case FN_QUIT:
+ s->got_quit_command = 1;
break;
}
- *data_size = 0;
+ if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) {
+ *data_size = 0;
+ break;
+ }
} else {
/* process audio command */
int residual_size = 0;
@@ -559,14 +577,14 @@ static int shorten_decode_frame(AVCodecContext *avctx,
return AVERROR(EINVAL);
}
samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
- s->cur_chan = 0;
*data_size = out_size;
- } else {
- *data_size = 0;
}
}
}
+ if (s->cur_chan < s->channels)
+ *data_size = 0;
+finish_frame:
s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
i= (get_bits_count(&s->gb))/8;
if (i > buf_size) {
@@ -606,5 +624,6 @@ AVCodec ff_shorten_decoder = {
.init = shorten_decode_init,
.close = shorten_decode_close,
.decode = shorten_decode_frame,
+ .capabilities = CODEC_CAP_DELAY,
.long_name= NULL_IF_CONFIG_SMALL("Shorten"),
};
diff --git a/tests/ref/fate/lossless-shortenaudio b/tests/ref/fate/lossless-shortenaudio
index 9448052..9cdb369 100644
--- a/tests/ref/fate/lossless-shortenaudio
+++ b/tests/ref/fate/lossless-shortenaudio
@@ -1 +1 @@
-9949141c405524f37ef1058b1ef4114b
+da93c50961443b88fce416ae61c8ca8a
More information about the ffmpeg-cvslog
mailing list