summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2011-12-13 14:52:43 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2011-12-13 14:52:43 -0500
commit5609cec9a5e1ea8fcb056f2306a115cb3b61c4c9 (patch)
tree3c1a34714cc64f5a865e696a2fd307ff869ba5d1 /src
parentbbfc9c9ee5de680320aeae2f8bd981ebe7af6861 (diff)
downloadopus-5609cec9a5e1ea8fcb056f2306a115cb3b61c4c9.tar.gz
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
Diffstat (limited to 'src')
-rw-r--r--src/opus_decoder.c14
-rw-r--r--src/opus_encoder.c21
2 files changed, 35 insertions, 0 deletions
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 3df0cdfc..97e3e968 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 54b48d42..b95cf288 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;