Better error handling in the Opus API
This commit is contained in:
parent
3e7c051853
commit
9d8dc3a3cb
4 changed files with 64 additions and 28 deletions
10
src/opus.h
10
src/opus.h
|
@ -185,10 +185,11 @@ OPUS_EXPORT int opus_encoder_get_size(int channels);
|
||||||
OPUS_EXPORT OpusEncoder *opus_encoder_create(
|
OPUS_EXPORT OpusEncoder *opus_encoder_create(
|
||||||
int Fs, /* Sampling rate of input signal (Hz) */
|
int Fs, /* Sampling rate of input signal (Hz) */
|
||||||
int channels, /* Number of channels (1/2) in input signal */
|
int channels, /* Number of channels (1/2) in input signal */
|
||||||
int application /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
|
int application, /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
|
||||||
|
int *error /* Error code */
|
||||||
);
|
);
|
||||||
|
|
||||||
OPUS_EXPORT OpusEncoder *opus_encoder_init(
|
OPUS_EXPORT int opus_encoder_init(
|
||||||
OpusEncoder *st, /* Encoder state */
|
OpusEncoder *st, /* Encoder state */
|
||||||
int Fs, /* Sampling rate of input signal (Hz) */
|
int Fs, /* Sampling rate of input signal (Hz) */
|
||||||
int channels, /* Number of channels (1/2) in input signal */
|
int channels, /* Number of channels (1/2) in input signal */
|
||||||
|
@ -223,10 +224,11 @@ OPUS_EXPORT int opus_decoder_get_size(int channels);
|
||||||
|
|
||||||
OPUS_EXPORT OpusDecoder *opus_decoder_create(
|
OPUS_EXPORT OpusDecoder *opus_decoder_create(
|
||||||
int Fs, /* Sampling rate of output signal (Hz) */
|
int Fs, /* Sampling rate of output signal (Hz) */
|
||||||
int channels /* Number of channels (1/2) in output signal */
|
int channels, /* Number of channels (1/2) in output signal */
|
||||||
|
int *error /* Error code*/
|
||||||
);
|
);
|
||||||
|
|
||||||
OPUS_EXPORT OpusDecoder *opus_decoder_init(OpusDecoder *st,
|
OPUS_EXPORT int opus_decoder_init(OpusDecoder *st,
|
||||||
int Fs, /* Sampling rate of output signal (Hz) */
|
int Fs, /* Sampling rate of output signal (Hz) */
|
||||||
int channels /* Number of channels (1/2) in output signal */
|
int channels /* Number of channels (1/2) in output signal */
|
||||||
);
|
);
|
||||||
|
|
|
@ -86,19 +86,19 @@ int opus_decoder_get_size(int channels)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels)
|
int opus_decoder_init(OpusDecoder *st, int Fs, int channels)
|
||||||
{
|
{
|
||||||
void *silk_dec;
|
void *silk_dec;
|
||||||
CELTDecoder *celt_dec;
|
CELTDecoder *celt_dec;
|
||||||
int ret, silkDecSizeBytes;
|
int ret, silkDecSizeBytes;
|
||||||
|
|
||||||
if (channels<1 || channels > 2)
|
if (channels<1 || channels > 2)
|
||||||
return NULL;
|
return OPUS_BAD_ARG;
|
||||||
memset(st, 0, opus_decoder_get_size(channels));
|
memset(st, 0, opus_decoder_get_size(channels));
|
||||||
/* Initialize SILK encoder */
|
/* Initialize SILK encoder */
|
||||||
ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
|
ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
|
||||||
if( ret ) {
|
if( ret ) {
|
||||||
return NULL;
|
return OPUS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
silkDecSizeBytes = align(silkDecSizeBytes);
|
silkDecSizeBytes = align(silkDecSizeBytes);
|
||||||
st->silk_dec_offset = align(sizeof(OpusDecoder));
|
st->silk_dec_offset = align(sizeof(OpusDecoder));
|
||||||
|
@ -123,18 +123,29 @@ OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels)
|
||||||
|
|
||||||
st->prev_mode = 0;
|
st->prev_mode = 0;
|
||||||
st->frame_size = Fs/400;
|
st->frame_size = Fs/400;
|
||||||
return st;
|
return OPUS_OK;
|
||||||
failure:
|
failure:
|
||||||
free(st);
|
free(st);
|
||||||
return NULL;
|
return OPUS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusDecoder *opus_decoder_create(int Fs, int channels)
|
OpusDecoder *opus_decoder_create(int Fs, int channels, int *error)
|
||||||
{
|
{
|
||||||
char *raw_state = (char*)malloc(opus_decoder_get_size(channels));
|
int ret;
|
||||||
if (raw_state == NULL)
|
char *raw_state = (char*)malloc(opus_decoder_get_size(channels));
|
||||||
return NULL;
|
if (raw_state == NULL)
|
||||||
return opus_decoder_init((OpusDecoder*)raw_state, Fs, channels);
|
{
|
||||||
|
if (error)
|
||||||
|
*error = OPUS_ALLOC_FAIL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = opus_decoder_init((OpusDecoder*)raw_state, Fs, channels);
|
||||||
|
if (ret != OPUS_OK)
|
||||||
|
{
|
||||||
|
free(raw_state);
|
||||||
|
raw_state = NULL;
|
||||||
|
}
|
||||||
|
return (OpusDecoder*)raw_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out,
|
static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, opus_val16 *out,
|
||||||
|
|
|
@ -110,7 +110,7 @@ int opus_encoder_get_size(int channels)
|
||||||
return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
|
return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int application)
|
int opus_encoder_init(OpusEncoder* st, int Fs, int channels, int application)
|
||||||
{
|
{
|
||||||
void *silk_enc;
|
void *silk_enc;
|
||||||
CELTEncoder *celt_enc;
|
CELTEncoder *celt_enc;
|
||||||
|
@ -118,17 +118,17 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int applic
|
||||||
int ret, silkEncSizeBytes;
|
int ret, silkEncSizeBytes;
|
||||||
|
|
||||||
if (channels > 2 || channels < 1)
|
if (channels > 2 || channels < 1)
|
||||||
return NULL;
|
return OPUS_BAD_ARG;
|
||||||
if (application < OPUS_APPLICATION_VOIP || application > OPUS_APPLICATION_AUDIO)
|
if (application < OPUS_APPLICATION_VOIP || application > OPUS_APPLICATION_AUDIO)
|
||||||
return NULL;
|
return OPUS_BAD_ARG;
|
||||||
if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
|
if (Fs != 8000 && Fs != 12000 && Fs != 16000 && Fs != 24000 && Fs != 48000)
|
||||||
return NULL;
|
return OPUS_BAD_ARG;
|
||||||
|
|
||||||
memset(st, 0, opus_encoder_get_size(channels));
|
memset(st, 0, opus_encoder_get_size(channels));
|
||||||
/* Create SILK encoder */
|
/* Create SILK encoder */
|
||||||
ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
|
ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
|
||||||
if (ret)
|
if (ret)
|
||||||
return NULL;
|
return OPUS_BAD_ARG;
|
||||||
silkEncSizeBytes = align(silkEncSizeBytes);
|
silkEncSizeBytes = align(silkEncSizeBytes);
|
||||||
st->silk_enc_offset = align(sizeof(OpusEncoder));
|
st->silk_enc_offset = align(sizeof(OpusEncoder));
|
||||||
st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
|
st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
|
||||||
|
@ -190,11 +190,11 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int applic
|
||||||
else
|
else
|
||||||
st->delay_compensation += 2;
|
st->delay_compensation += 2;
|
||||||
|
|
||||||
return st;
|
return OPUS_OK;
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
free(st);
|
free(st);
|
||||||
return NULL;
|
return OPUS_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
|
static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
|
||||||
|
@ -228,12 +228,25 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel
|
||||||
toc |= (channels==2)<<2;
|
toc |= (channels==2)<<2;
|
||||||
return toc;
|
return toc;
|
||||||
}
|
}
|
||||||
OpusEncoder *opus_encoder_create(int Fs, int channels, int mode)
|
OpusEncoder *opus_encoder_create(int Fs, int channels, int mode, int *error)
|
||||||
{
|
{
|
||||||
char *raw_state = (char *)malloc(opus_encoder_get_size(channels));
|
int ret;
|
||||||
if (raw_state == NULL)
|
char *raw_state = (char *)malloc(opus_encoder_get_size(channels));
|
||||||
return NULL;
|
if (raw_state == NULL)
|
||||||
return opus_encoder_init((OpusEncoder*)raw_state, Fs, channels, mode);
|
{
|
||||||
|
if (error)
|
||||||
|
*error = OPUS_ALLOC_FAIL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = opus_encoder_init((OpusEncoder*)raw_state, Fs, channels, mode);
|
||||||
|
if (error)
|
||||||
|
*error = ret;
|
||||||
|
if (ret != OPUS_OK)
|
||||||
|
{
|
||||||
|
free(raw_state);
|
||||||
|
raw_state = NULL;
|
||||||
|
}
|
||||||
|
return (OpusEncoder*)raw_state;
|
||||||
}
|
}
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
|
|
|
@ -257,8 +257,18 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
enc = opus_encoder_create(sampling_rate, channels, application);
|
enc = opus_encoder_create(sampling_rate, channels, application, &err);
|
||||||
dec = opus_decoder_create(sampling_rate, channels);
|
if (err != OPUS_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
dec = opus_decoder_create(sampling_rate, channels, &err);
|
||||||
|
if (err != OPUS_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (enc==NULL)
|
if (enc==NULL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue