diff options
author | Mark Harris <mark.hsj@gmail.com> | 2013-10-07 18:50:59 -0700 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-10-11 23:43:21 -0400 |
commit | b88a3ad39672ffa8ccf5ea73a0bffa1dd76a93aa (patch) | |
tree | 102fad9eadb5fb8000acbe41f1ca535368deb4cc /src/opus_decoder.c | |
parent | dbc83d316c2c221f9790e6162c9942082db8362a (diff) | |
download | libopus-b88a3ad39672ffa8ccf5ea73a0bffa1dd76a93aa.tar.gz |
Fix 40/60ms zero-length frame decode failure
Decoding failed with OPUS_BAD_ARG on a packet containing a 40ms or
60ms zero-length frame when it followed a hybrid or MDCT frame.
It now invokes the PLC for the duration of the packet as expected.
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
Diffstat (limited to 'src/opus_decoder.c')
-rw-r--r-- | src/opus_decoder.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/opus_decoder.c b/src/opus_decoder.c index ee0c9f56..5e39bd44 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -257,23 +257,33 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, ec_dec_init(&dec,(unsigned char*)data,len); } else { audiosize = frame_size; + mode = st->prev_mode; - if (st->prev_mode == 0) + if (mode == 0) { /* If we haven't got any packet yet, all we can do is return zeros */ for (i=0;i<audiosize*st->channels;i++) pcm[i] = 0; RESTORE_STACK; return audiosize; - } else { - mode = st->prev_mode; } - } - /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do - multiple calls */ - if (data==NULL && mode != MODE_SILK_ONLY) - frame_size = IMIN(frame_size, F20); + if (mode != MODE_SILK_ONLY && audiosize > F20) + { + do { + int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0); + if (ret<0) + { + RESTORE_STACK; + return ret; + } + pcm += ret*st->channels; + audiosize -= ret; + } while (audiosize > 0); + RESTORE_STACK; + return frame_size; + } + } pcm_transition_silk_size = 0; pcm_transition_celt_size = 0; |