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.
This commit is contained in:
parent
55788c8c85
commit
220a7d4ba8
2 changed files with 52 additions and 17 deletions
|
@ -88,8 +88,9 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
|
||||||
CELTDecoder *celt_dec;
|
CELTDecoder *celt_dec;
|
||||||
int ret, silkDecSizeBytes;
|
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;
|
return OPUS_BAD_ARG;
|
||||||
|
|
||||||
OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
|
OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
|
||||||
/* Initialize SILK encoder */
|
/* Initialize SILK encoder */
|
||||||
ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
|
ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
|
||||||
|
@ -122,6 +123,12 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
|
||||||
OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
|
OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
|
||||||
{
|
{
|
||||||
int ret;
|
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));
|
OpusDecoder *st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,6 +76,7 @@ struct OpusEncoder {
|
||||||
opus_val32 hp_mem[4];
|
opus_val32 hp_mem[4];
|
||||||
int mode;
|
int mode;
|
||||||
int prev_mode;
|
int prev_mode;
|
||||||
|
int prev_framesize;
|
||||||
int bandwidth;
|
int bandwidth;
|
||||||
/* Sampling rate (at the API level) */
|
/* Sampling rate (at the API level) */
|
||||||
int first;
|
int first;
|
||||||
|
@ -142,12 +143,9 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
|
||||||
int err;
|
int err;
|
||||||
int ret, silkEncSizeBytes;
|
int ret, silkEncSizeBytes;
|
||||||
|
|
||||||
if (channels > 2 || channels < 1)
|
if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
|
||||||
return OPUS_BAD_ARG;
|
(application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
|
||||||
if (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
|
&& application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
|
||||||
&& application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
|
|
||||||
return OPUS_BAD_ARG;
|
|
||||||
if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
|
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
|
|
||||||
OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
|
OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
|
||||||
|
@ -328,9 +326,17 @@ static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
|
||||||
#endif
|
#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;
|
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));
|
OpusEncoder *st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
{
|
{
|
||||||
|
@ -338,7 +344,7 @@ OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int mode, int *err
|
||||||
*error = OPUS_ALLOC_FAIL;
|
*error = OPUS_ALLOC_FAIL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ret = opus_encoder_init(st, Fs, channels, mode);
|
ret = opus_encoder_init(st, Fs, channels, application);
|
||||||
if (error)
|
if (error)
|
||||||
*error = ret;
|
*error = ret;
|
||||||
if (ret != OPUS_OK)
|
if (ret != OPUS_OK)
|
||||||
|
@ -348,6 +354,18 @@ OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int mode, int *err
|
||||||
}
|
}
|
||||||
return st;
|
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
|
#ifdef FIXED_POINT
|
||||||
#define opus_encode_native opus_encode
|
#define opus_encode_native opus_encode
|
||||||
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
|
@ -398,12 +416,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
else
|
else
|
||||||
delay_compensation = st->delay_compensation;
|
delay_compensation = st->delay_compensation;
|
||||||
|
|
||||||
if (st->user_bitrate_bps==OPUS_AUTO)
|
st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
|
||||||
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;
|
|
||||||
|
|
||||||
/* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
|
/* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
|
||||||
equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);
|
equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50);
|
||||||
|
@ -944,6 +957,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
st->prev_mode = MODE_CELT_ONLY;
|
st->prev_mode = MODE_CELT_ONLY;
|
||||||
else
|
else
|
||||||
st->prev_mode = st->mode;
|
st->prev_mode = st->mode;
|
||||||
|
st->prev_framesize = frame_size;
|
||||||
st->first = 0;
|
st->first = 0;
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
return ret+1+redundancy_bytes;
|
return ret+1+redundancy_bytes;
|
||||||
|
@ -1017,7 +1031,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_GET_APPLICATION_REQUEST:
|
case OPUS_GET_APPLICATION_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 *value = va_arg(ap, opus_int32*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->mode;
|
*value = st->application;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_BITRATE_REQUEST:
|
case OPUS_SET_BITRATE_REQUEST:
|
||||||
|
@ -1038,12 +1052,14 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_GET_BITRATE_REQUEST:
|
case OPUS_GET_BITRATE_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 *value = va_arg(ap, opus_int32*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->bitrate_bps;
|
*value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_SET_FORCE_CHANNELS_REQUEST:
|
case OPUS_SET_FORCE_CHANNELS_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<1 || value>st->channels)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->force_channels = value;
|
st->force_channels = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1077,6 +1093,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_DTX_REQUEST:
|
case OPUS_SET_DTX_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<0 || value>1)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->silk_mode.useDTX = value;
|
st->silk_mode.useDTX = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1089,6 +1107,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_COMPLEXITY_REQUEST:
|
case OPUS_SET_COMPLEXITY_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<0 || value>10)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->silk_mode.complexity = value;
|
st->silk_mode.complexity = value;
|
||||||
celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
|
celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
|
||||||
}
|
}
|
||||||
|
@ -1102,6 +1122,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_INBAND_FEC_REQUEST:
|
case OPUS_SET_INBAND_FEC_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<0 || value>1)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->silk_mode.useInBandFEC = value;
|
st->silk_mode.useInBandFEC = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1129,6 +1151,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_VBR_REQUEST:
|
case OPUS_SET_VBR_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<0 || value>1)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->use_vbr = value;
|
st->use_vbr = value;
|
||||||
st->silk_mode.useCBR = 1-value;
|
st->silk_mode.useCBR = 1-value;
|
||||||
}
|
}
|
||||||
|
@ -1156,6 +1180,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_VBR_CONSTRAINT_REQUEST:
|
case OPUS_SET_VBR_CONSTRAINT_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if(value<0 || value>1)
|
||||||
|
return OPUS_BAD_ARG;
|
||||||
st->vbr_constraint = value;
|
st->vbr_constraint = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1168,6 +1194,8 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_SET_SIGNAL_REQUEST:
|
case OPUS_SET_SIGNAL_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 value = va_arg(ap, opus_int32);
|
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;
|
st->signal_type = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue