aboutsummaryrefslogtreecommitdiff
path: root/src/opus_decoder.c
diff options
context:
space:
mode:
authorMark Harris <mark.hsj@gmail.com>2013-10-07 18:50:59 -0700
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-10-11 23:43:21 -0400
commitb88a3ad39672ffa8ccf5ea73a0bffa1dd76a93aa (patch)
tree102fad9eadb5fb8000acbe41f1ca535368deb4cc /src/opus_decoder.c
parentdbc83d316c2c221f9790e6162c9942082db8362a (diff)
downloadlibopus-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.c26
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;