diff options
author | Felicia Lim <flim@google.com> | 2016-10-28 03:00:05 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2016-10-28 06:36:57 +0300 |
commit | 9962bf3d941c68c2e167cb4f4fe79eb32f98f2a2 (patch) | |
tree | 1aa36443d18c48e9be04a19816f8e8afa5fcf6c3 | |
parent | 0962cbe2ae535f8432fec37461ca006f113f200d (diff) |
Encode correct headers when asking for very small output bytes and using long frames
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
-rw-r--r-- | src/opus_encoder.c | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/src/opus_encoder.c b/src/opus_encoder.c index f6fa9e1f..79ef3f1f 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -1360,6 +1360,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ RESTORE_STACK; return OPUS_BAD_ARG; } + + /* Cannot encode 100 ms in 1 byte */ + if (max_data_bytes==1 && st->Fs==(frame_size*10)) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + silk_enc = (char*)st+st->silk_enc_offset; celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) @@ -1453,20 +1461,56 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ /*If the space is too low to do something useful, emit 'PLC' frames.*/ int tocmode = st->mode; int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; + int packet_code = 0; + int num_multiframes = 0; + if (tocmode==0) tocmode = MODE_SILK_ONLY; if (frame_rate>100) tocmode = MODE_CELT_ONLY; - if (frame_rate < 50) - tocmode = MODE_SILK_ONLY; + /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */ + if (frame_rate==25 && tocmode!=MODE_SILK_ONLY) + { + frame_rate = 50; + packet_code = 1; + } + + /* >= 60 ms frames */ + if (frame_rate<=16) + { + /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */ + if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10)) + { + tocmode = MODE_SILK_ONLY; + + packet_code = frame_rate <= 12; + frame_rate = frame_rate == 12 ? 25 : 16; + } + else + { + num_multiframes = 50/frame_rate; + frame_rate = 50; + packet_code = 3; + } + } + if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) bw=OPUS_BANDWIDTH_WIDEBAND; else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) bw=OPUS_BANDWIDTH_NARROWBAND; else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) bw=OPUS_BANDWIDTH_SUPERWIDEBAND; + data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); - ret = 1; + data[0] |= packet_code; + + ret = packet_code <= 1 ? 1 : 2; + + max_data_bytes = IMAX(max_data_bytes, ret); + + if (packet_code==3) + data[1] = num_multiframes; + if (!st->use_vbr) { ret = opus_packet_pad(data, ret, max_data_bytes); |