From 5609cec9a5e1ea8fcb056f2306a115cb3b61c4c9 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Tue, 13 Dec 2011 14:52:43 -0500 Subject: [PATCH] Fixes two minor issues found in random testing at ridiculously low rate. - When it cannot produce the rate it's being asked, the encoder now returns a "PLC packet" - Makes it possible to use the CELT PLC for more than 20 ms --- src/opus_decoder.c | 14 ++++++++++++++ src/opus_encoder.c | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 3df0cdfce..97e3e9689 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -246,6 +246,20 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, } } + /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */ + if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY) + { + int nb_samples = 0; + do { + int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0); + if (ret != F20) + return OPUS_INTERNAL_ERROR; + pcm += F20*st->channels; + nb_samples += F20; + } while (nb_samples < frame_size); + RESTORE_STACK; + return frame_size; + } ALLOC(pcm_transition, F5*st->channels, opus_val16); if (data!=NULL && st->prev_mode > 0 && ( diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 54b48d421..b95cf2889 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -479,6 +479,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, RESTORE_STACK; return OPUS_BAD_ARG; } + if (max_data_bytes<=0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); @@ -490,6 +495,22 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); frame_rate = st->Fs/frame_size; + if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 + || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) + { + int tocmode = st->mode; + if (tocmode==0) + tocmode = MODE_SILK_ONLY; + if (frame_rate>100) + tocmode = MODE_CELT_ONLY; + if (frame_rate < 50) + tocmode = MODE_SILK_ONLY; + data[0] = gen_toc(tocmode, frame_rate, + st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth, + st->stream_channels); + RESTORE_STACK; + return 1; + } if (!st->use_vbr) { int cbrBytes; -- GitLab