From 5095c47053bdacfafd0ee0d1c11058d54c235e9a Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> Date: Thu, 5 May 2011 19:47:48 -0400 Subject: [PATCH] Removes pointers from the Opus state We now store the SILK/CELT offsets so that the Opus state can now be moved/copied elsewhere in memory without problem --- src/opus_decoder.c | 44 ++++++++++++++---------- src/opus_decoder.h | 4 +-- src/opus_encoder.c | 83 ++++++++++++++++++++++++++-------------------- src/opus_encoder.h | 4 +-- 4 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 14ab6ccb2..9a4757bc1 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -41,6 +41,8 @@ OpusDecoder *opus_decoder_create(int Fs, int channels) { + void *silk_dec; + CELTDecoder *celt_dec; char *raw_state; int ret, silkDecSizeBytes, celtDecSizeBytes; OpusDecoder *st; @@ -53,21 +55,23 @@ OpusDecoder *opus_decoder_create(int Fs, int channels) celtDecSizeBytes = celt_decoder_get_size(channels); raw_state = calloc(sizeof(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1); st = (OpusDecoder*)raw_state; - st->silk_dec = (void*)(raw_state+sizeof(OpusDecoder)); - st->celt_dec = (CELTDecoder*)(raw_state+sizeof(OpusDecoder)+silkDecSizeBytes); + st->silk_dec_offset = sizeof(OpusDecoder); + st->celt_dec_offset = sizeof(OpusDecoder)+silkDecSizeBytes; + silk_dec = raw_state+st->silk_dec_offset; + celt_dec = (CELTDecoder*)(raw_state+st->celt_dec_offset); st->stream_channels = st->channels = channels; st->Fs = Fs; /* Reset decoder */ - ret = SKP_Silk_SDK_InitDecoder( st->silk_dec ); + ret = SKP_Silk_SDK_InitDecoder( silk_dec ); if( ret ) { /* Handle error */ } /* Initialize CELT decoder */ - st->celt_dec = celt_decoder_init(st->celt_dec, Fs, channels, NULL); - celt_decoder_ctl(st->celt_dec, CELT_SET_SIGNALLING(0)); + celt_decoder_init(celt_dec, Fs, channels, NULL); + celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); st->prev_mode = 0; return st; @@ -108,6 +112,8 @@ static int opus_packet_get_mode(const unsigned char *data) static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, int len, short *pcm, int frame_size, int decode_fec) { + void *silk_dec; + CELTDecoder *celt_dec; int i, silk_ret=0, celt_ret=0; ec_dec dec; SKP_SILK_SDK_DecControlStruct DecControl; @@ -126,6 +132,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, int F2_5, F5, F10; const celt_word16 *window; + silk_dec = (char*)st+st->silk_dec_offset; + celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); F10 = st->Fs/100; F5 = F10>>1; F2_5 = F5>>1; @@ -168,7 +176,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, SKP_int16 *pcm_ptr = pcm; if (st->prev_mode==MODE_CELT_ONLY) - SKP_Silk_SDK_InitDecoder( st->silk_dec ); + SKP_Silk_SDK_InitDecoder( silk_dec ); DecControl.API_sampleRate = st->Fs; DecControl.payloadSize_ms = 1000 * audiosize / st->Fs; @@ -194,7 +202,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, do { /* Call SILK decoder */ int first_frame = decoded_samples == 0; - silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, + silk_ret = SKP_Silk_SDK_Decode( silk_dec, &DecControl, lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); if( silk_ret ) { fprintf (stderr, "SILK decode error\n"); @@ -249,8 +257,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, endband = 21; break; } - celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(endband)); - celt_decoder_ctl(st->celt_dec, CELT_SET_CHANNELS(st->stream_channels)); + celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); + celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)); } if (redundancy) @@ -262,20 +270,20 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) { - celt_decode(st->celt_dec, data+len, redundancy_bytes, redundant_audio, F5); - celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE); + celt_decode(celt_dec, data+len, redundancy_bytes, redundant_audio, F5); + celt_decoder_ctl(celt_dec, CELT_RESET_STATE); } /* MUST be after PLC */ - celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(start_band)); + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); if (transition) - celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE); + celt_decoder_ctl(celt_dec, CELT_RESET_STATE); if (mode != MODE_SILK_ONLY) { /* Decode CELT */ - celt_ret = celt_decode_with_ec(st->celt_dec, decode_fec?NULL:data, len, pcm_celt, frame_size, &dec); + celt_ret = celt_decode_with_ec(celt_dec, decode_fec?NULL:data, len, pcm_celt, frame_size, &dec); for (i=0;i<frame_size*st->channels;i++) pcm[i] = ADD_SAT16(pcm[i], pcm_celt[i]); } @@ -283,17 +291,17 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, { const CELTMode *celt_mode; - celt_decoder_ctl(st->celt_dec, CELT_GET_MODE(&celt_mode)); + celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); window = celt_mode->window; } /* 5 ms redundant frame for SILK->CELT */ if (redundancy && !celt_to_silk) { - celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE); - celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0)); + celt_decoder_ctl(celt_dec, CELT_RESET_STATE); + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - celt_decode(st->celt_dec, data+len, redundancy_bytes, redundant_audio, F5); + celt_decode(celt_dec, data+len, redundancy_bytes, redundant_audio, F5); smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); } diff --git a/src/opus_decoder.h b/src/opus_decoder.h index e8e51f8d0..c221210f9 100644 --- a/src/opus_decoder.h +++ b/src/opus_decoder.h @@ -32,8 +32,8 @@ #include "opus.h" struct OpusDecoder { - CELTDecoder *celt_dec; - void *silk_dec; + int celt_dec_offset; + int silk_dec_offset; int channels; int stream_channels; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index f8f6e5cc8..117c8b5a8 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -57,6 +57,8 @@ static const int audio_bandwidth_thresholds[10] = { OpusEncoder *opus_encoder_create(int Fs, int channels) { + void *silk_enc; + CELTEncoder *celt_enc; int err; char *raw_state; OpusEncoder *st; @@ -71,13 +73,16 @@ OpusEncoder *opus_encoder_create(int Fs, int channels) if (raw_state == NULL) return NULL; st = (OpusEncoder*)raw_state; - st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder)); - st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes); + st->silk_enc_offset = sizeof(OpusEncoder); + st->celt_enc_offset = sizeof(OpusEncoder)+silkEncSizeBytes; + silk_enc = (char*)st+st->silk_enc_offset; + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); + st->stream_channels = st->channels = channels; st->Fs = Fs; - ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &st->silk_mode ); + ret = SKP_Silk_SDK_InitEncoder( silk_enc, &st->silk_mode ); if( ret ) goto failure; @@ -94,10 +99,10 @@ OpusEncoder *opus_encoder_create(int Fs, int channels) /* Create CELT encoder */ /* Initialize CELT encoder */ - st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, &err); + celt_encoder_init(celt_enc, Fs, channels, &err); if (err != CELT_OK) goto failure; - celt_encoder_ctl(st->celt_enc, CELT_SET_SIGNALLING(0)); + celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0)); st->mode = MODE_HYBRID; st->bandwidth = BANDWIDTH_FULLBAND; @@ -121,6 +126,8 @@ failure: int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, unsigned char *data, int max_data_bytes) { + void *silk_enc; + CELTEncoder *celt_enc; int i; int ret=0; SKP_int32 nBytes; @@ -140,6 +147,8 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, int to_celt = 0; celt_int32 mono_rate; + silk_enc = (char*)st+st->silk_enc_offset; + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); /* Rete-dependent mono-stereo decision */ if (st->channels == 2) { @@ -247,7 +256,7 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) { SKP_SILK_SDK_EncControlStruct dummy; - SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy); + SKP_Silk_SDK_InitEncoder( silk_enc, &dummy); prefill=1; } if (st->prev_mode >0 && @@ -321,10 +330,10 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, if (prefill) { int zero=0; - SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 ); + SKP_Silk_SDK_Encode( silk_enc, &st->silk_mode, st->delay_buffer, st->encoder_buffer, NULL, &zero, 1 ); } - ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 ); + ret = SKP_Silk_SDK_Encode( silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 ); if( ret ) { fprintf (stderr, "SILK encode error: %d\n", ret); /* Handle error */ @@ -364,23 +373,23 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, endband = 21; break; } - celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband)); - celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels)); + celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); + celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); } if (st->mode != MODE_SILK_ONLY) { - celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0)); - celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000)); + celt_encoder_ctl(celt_enc, CELT_SET_VBR(0)); + celt_encoder_ctl(celt_enc, CELT_SET_BITRATE(510000)); if (st->prev_mode == MODE_SILK_ONLY) { unsigned char dummy[10]; - celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE); - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0)); - /* FIXME: This wastes CPU a bit compared to just prefilling the buffer */ - celt_encode(st->celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10); + celt_encoder_ctl(celt_enc, CELT_RESET_STATE); + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); + /* TODO: This wastes CPU a bit compared to just prefilling the buffer */ + celt_encode(celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10); } else { - celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2)); + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2)); } if (st->mode == MODE_HYBRID) @@ -397,9 +406,9 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, } else { if (st->use_vbr) { - celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1)); - celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint)); - celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps)); + celt_encoder_ctl(celt_enc, CELT_SET_VBR(1)); + celt_encoder_ctl(celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint)); + celt_encoder_ctl(celt_enc, CELT_SET_BITRATE(st->bitrate_bps)); nb_compr_bytes = max_data_bytes-1; } else { nb_compr_bytes = bytes_target; @@ -439,19 +448,18 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, /* 5 ms redundant frame for CELT->SILK */ if (redundancy && celt_to_silk) { - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); - /* FIXME: That's OK for now, but we need to set the flags properly */ - celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0)); - celt_encode(st->celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes); - celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE); + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); + celt_encoder_ctl(celt_enc, CELT_SET_VBR(0)); + celt_encode(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes); + celt_encoder_ctl(celt_enc, CELT_RESET_STATE); } - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band)); + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band)); if (st->mode != MODE_SILK_ONLY) { /* Encode high band with CELT */ - ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); + ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); } /* 5 ms redundant frame for SILK->CELT */ @@ -461,14 +469,14 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, N2 = st->Fs/200; N4 = st->Fs/400; - celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE); - celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0)); + celt_encoder_ctl(celt_enc, CELT_RESET_STATE); + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); - /* FIXME: Do proper prefilling here */ - celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes); + /* TODO: We could speed up prefilling here */ + celt_encode(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes); - celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes); + celt_encode(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes); } @@ -527,10 +535,13 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, int opus_encoder_ctl(OpusEncoder *st, int request, ...) { + CELTEncoder *celt_enc; va_list ap; va_start(ap, request); + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); + switch (request) { case OPUS_SET_MODE_REQUEST: @@ -594,7 +605,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { int value = va_arg(ap, int); st->silk_mode.complexity = value; - celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value)); + celt_encoder_ctl(celt_enc, CELT_SET_COMPLEXITY(value)); } break; case OPUS_GET_COMPLEXITY_REQUEST: @@ -621,7 +632,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) if (value < 0 || value > 100) return OPUS_BAD_ARG; st->silk_mode.packetLossPercentage = value; - celt_encoder_ctl(st->celt_enc, CELT_SET_LOSS_PERC(value)); + celt_encoder_ctl(celt_enc, CELT_SET_LOSS_PERC(value)); } break; case OPUS_GET_PACKET_LOSS_PERC_REQUEST: diff --git a/src/opus_encoder.h b/src/opus_encoder.h index a846db9ab..d46b0eb67 100644 --- a/src/opus_encoder.h +++ b/src/opus_encoder.h @@ -36,9 +36,9 @@ #define MAX_ENCODER_BUFFER 480 struct OpusEncoder { - CELTEncoder *celt_enc; + int celt_enc_offset; + int silk_enc_offset; SKP_SILK_SDK_EncControlStruct silk_mode; - void *silk_enc; int channels; int stream_channels; -- GitLab