Removes pointers from the Opus state
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 5 May 2011 23:47:48 +0000 (19:47 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 5 May 2011 23:47:48 +0000 (19:47 -0400)
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
src/opus_decoder.h
src/opus_encoder.c
src/opus_encoder.h

index 14ab6cc..9a4757b 100644 (file)
@@ -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);
     }
index e8e51f8..c221210 100644 (file)
@@ -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;
 
index f8f6e5c..117c8b5 100644 (file)
@@ -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:
index a846db9..d46b0eb 100644 (file)
@@ -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;