ref: 220a7d4ba82bffc2955277b41df6f0163dc1bccb
parent: 55788c8c857f28f3b5e6d14cab978398d79fcf24
author: Gregory Maxwell <[email protected]>
date: Sat Oct 1 16:30:16 EDT 2011
Fix bug in the OPUS_GET_APPLICATION_REQUEST ctl and also add a bunch of set ctl range checking and improve encoder/decoder error code consistency.
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -88,8 +88,9 @@
CELTDecoder *celt_dec;
int ret, silkDecSizeBytes;
- if (channels<1 || channels > 2)
+ if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
return OPUS_BAD_ARG;
+
OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
/* Initialize SILK encoder */
ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
@@ -122,6 +123,12 @@
OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
{
int ret;
+ if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2))
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
OpusDecoder *st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
if (st == NULL)
{
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -76,6 +76,7 @@
opus_val32 hp_mem[4];
int mode;
int prev_mode;
+ int prev_framesize;
int bandwidth;
/* Sampling rate (at the API level) */
int first;
@@ -142,13 +143,10 @@
int err;
int ret, silkEncSizeBytes;
- if (channels > 2 || channels < 1)
+ if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
+ (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
+ && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
return OPUS_BAD_ARG;
- if (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
- && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
- return OPUS_BAD_ARG;
- if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
- return OPUS_BAD_ARG;
OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
/* Create SILK encoder */
@@ -328,9 +326,17 @@
#endif
}
-OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int mode, int *error)
+OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
{
int ret;
+ if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
+ (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
+ && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
+ {
+ if (error)
+ *error = OPUS_BAD_ARG;
+ return NULL;
+ }
OpusEncoder *st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
if (st == NULL)
{
@@ -338,7 +344,7 @@
*error = OPUS_ALLOC_FAIL;
return NULL;
}
- ret = opus_encoder_init(st, Fs, channels, mode);
+ ret = opus_encoder_init(st, Fs, channels, application);
if (error)
*error = ret;
if (ret != OPUS_OK)
@@ -348,6 +354,18 @@
}
return st;
}
+
+static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
+{
+ if(!frame_size)frame_size=st->Fs/400;
+ if (st->user_bitrate_bps==OPUS_AUTO)
+ return 60*st->Fs/frame_size + st->Fs*st->channels;
+ else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
+ return max_data_bytes*8*st->Fs/frame_size;
+ else
+ return st->user_bitrate_bps;
+}
+
#ifdef FIXED_POINT
#define opus_encode_native opus_encode
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
@@ -398,12 +416,7 @@
else
delay_compensation = st->delay_compensation;
- if (st->user_bitrate_bps==OPUS_AUTO)
- st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels;
- else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
- st->bitrate_bps = max_data_bytes*8*st->Fs/frame_size;
- else
- st->bitrate_bps = st->user_bitrate_bps;
+ st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
/* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);
@@ -944,6 +957,7 @@
st->prev_mode = MODE_CELT_ONLY;
else
st->prev_mode = st->mode;
+ st->prev_framesize = frame_size;
st->first = 0;
RESTORE_STACK;
return ret+1+redundancy_bytes;
@@ -1017,7 +1031,7 @@
case OPUS_GET_APPLICATION_REQUEST:
{
opus_int32 *value = va_arg(ap, opus_int32*);
- *value = st->mode;
+ *value = st->application;
}
break;
case OPUS_SET_BITRATE_REQUEST:
@@ -1038,12 +1052,14 @@
case OPUS_GET_BITRATE_REQUEST:
{
opus_int32 *value = va_arg(ap, opus_int32*);
- *value = st->bitrate_bps;
+ *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
}
break;
case OPUS_SET_FORCE_CHANNELS_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<1 || value>st->channels)
+ return OPUS_BAD_ARG;
st->force_channels = value;
}
break;
@@ -1077,6 +1093,8 @@
case OPUS_SET_DTX_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<0 || value>1)
+ return OPUS_BAD_ARG;
st->silk_mode.useDTX = value;
}
break;
@@ -1089,6 +1107,8 @@
case OPUS_SET_COMPLEXITY_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<0 || value>10)
+ return OPUS_BAD_ARG;
st->silk_mode.complexity = value;
celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
}
@@ -1102,6 +1122,8 @@
case OPUS_SET_INBAND_FEC_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<0 || value>1)
+ return OPUS_BAD_ARG;
st->silk_mode.useInBandFEC = value;
}
break;
@@ -1129,6 +1151,8 @@
case OPUS_SET_VBR_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<0 || value>1)
+ return OPUS_BAD_ARG;
st->use_vbr = value;
st->silk_mode.useCBR = 1-value;
}
@@ -1156,6 +1180,8 @@
case OPUS_SET_VBR_CONSTRAINT_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value<0 || value>1)
+ return OPUS_BAD_ARG;
st->vbr_constraint = value;
}
break;
@@ -1168,6 +1194,8 @@
case OPUS_SET_SIGNAL_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
+ if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
+ return OPUS_BAD_ARG;
st->signal_type = value;
}
break;