diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-09-16 21:34:42 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-10-20 13:09:46 -0400 |
commit | 1baa25c7dae0b43f0ff845f8ab4a94bf15b02440 (patch) | |
tree | 72c3284ffcfbdcea56ea5217750f3bfe7d0666d0 | |
parent | d03f9f65c090e29cfae5658e0a2e450b0e780346 (diff) | |
download | ffmpeg-1baa25c7dae0b43f0ff845f8ab4a94bf15b02440.tar.gz |
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.
-rw-r--r-- | libavcodec/shorten.c | 47 | ||||
-rw-r--r-- | tests/ref/fate/lossless-shortenaudio | 2 |
2 files changed, 34 insertions, 15 deletions
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 2732aabd5d..f510bcc380 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 9448052733..9cdb3690e3 100644 --- a/tests/ref/fate/lossless-shortenaudio +++ b/tests/ref/fate/lossless-shortenaudio @@ -1 +1 @@ -9949141c405524f37ef1058b1ef4114b +da93c50961443b88fce416ae61c8ca8a |