diff --git a/src/opus.h b/src/opus.h index 17934bff7048a4b03e6c705b644671f479654831..fb49b0b1fe0fa0654a8121cc8e2a9d7db009c41d 100644 --- a/src/opus.h +++ b/src/opus.h @@ -185,10 +185,11 @@ OPUS_EXPORT int opus_encoder_get_size(int channels); OPUS_EXPORT OpusEncoder *opus_encoder_create( int Fs, /* Sampling rate of input signal (Hz) */ 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 */ int Fs, /* Sampling rate of input signal (Hz) */ 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( 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 channels /* Number of channels (1/2) in output signal */ ); diff --git a/src/opus_decoder.c b/src/opus_decoder.c index e3b12e2b57beeb0a0d4ab4eb14777e195ba27551..b45012947613289bba2f4286c214301a322b3ec9 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -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; CELTDecoder *celt_dec; int ret, silkDecSizeBytes; if (channels<1 || channels > 2) - return NULL; + return OPUS_BAD_ARG; memset(st, 0, opus_decoder_get_size(channels)); /* Initialize SILK encoder */ ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); if( ret ) { - return NULL; + return OPUS_INTERNAL_ERROR; } silkDecSizeBytes = align(silkDecSizeBytes); 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->frame_size = Fs/400; - return st; + return OPUS_OK; failure: 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)); - if (raw_state == NULL) - return NULL; - return opus_decoder_init((OpusDecoder*)raw_state, Fs, channels); + int ret; + char *raw_state = (char*)malloc(opus_decoder_get_size(channels)); + if (raw_state == NULL) + { + 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, diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 7d45cc25fa81392afdb19b433785761972264632..dd7487ce382f3cec531dbca5adc892cb8b9e4aa6 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -110,7 +110,7 @@ int opus_encoder_get_size(int channels) 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; CELTEncoder *celt_enc; @@ -118,17 +118,17 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int applic int ret, silkEncSizeBytes; if (channels > 2 || channels < 1) - return NULL; + return OPUS_BAD_ARG; 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) - return NULL; + return OPUS_BAD_ARG; memset(st, 0, opus_encoder_get_size(channels)); /* Create SILK encoder */ ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); if (ret) - return NULL; + return OPUS_BAD_ARG; silkEncSizeBytes = align(silkEncSizeBytes); st->silk_enc_offset = align(sizeof(OpusEncoder)); 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 st->delay_compensation += 2; - return st; + return OPUS_OK; failure: free(st); - return NULL; + return OPUS_INTERNAL_ERROR; } 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; 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)); - if (raw_state == NULL) - return NULL; - return opus_encoder_init((OpusEncoder*)raw_state, Fs, channels, mode); + int ret; + char *raw_state = (char *)malloc(opus_encoder_get_size(channels)); + if (raw_state == NULL) + { + 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 int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size, diff --git a/src/test_opus.c b/src/test_opus.c index 9e73202fe536031779ceb02a170f5a61d3d02f59..3a84fafc8c4a5ad1494caab06a4acc5e93ac6ac1 100644 --- a/src/test_opus.c +++ b/src/test_opus.c @@ -257,8 +257,18 @@ int main(int argc, char *argv[]) return 1; } - enc = opus_encoder_create(sampling_rate, channels, application); - dec = opus_decoder_create(sampling_rate, channels); + enc = opus_encoder_create(sampling_rate, channels, application, &err); + 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) {