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
This commit is contained in:
parent
9edde42690
commit
5095c47053
4 changed files with 77 additions and 58 deletions
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
OpusDecoder *opus_decoder_create(int Fs, int channels)
|
OpusDecoder *opus_decoder_create(int Fs, int channels)
|
||||||
{
|
{
|
||||||
|
void *silk_dec;
|
||||||
|
CELTDecoder *celt_dec;
|
||||||
char *raw_state;
|
char *raw_state;
|
||||||
int ret, silkDecSizeBytes, celtDecSizeBytes;
|
int ret, silkDecSizeBytes, celtDecSizeBytes;
|
||||||
OpusDecoder *st;
|
OpusDecoder *st;
|
||||||
|
@ -53,21 +55,23 @@ OpusDecoder *opus_decoder_create(int Fs, int channels)
|
||||||
celtDecSizeBytes = celt_decoder_get_size(channels);
|
celtDecSizeBytes = celt_decoder_get_size(channels);
|
||||||
raw_state = calloc(sizeof(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1);
|
raw_state = calloc(sizeof(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1);
|
||||||
st = (OpusDecoder*)raw_state;
|
st = (OpusDecoder*)raw_state;
|
||||||
st->silk_dec = (void*)(raw_state+sizeof(OpusDecoder));
|
st->silk_dec_offset = sizeof(OpusDecoder);
|
||||||
st->celt_dec = (CELTDecoder*)(raw_state+sizeof(OpusDecoder)+silkDecSizeBytes);
|
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->stream_channels = st->channels = channels;
|
||||||
|
|
||||||
st->Fs = Fs;
|
st->Fs = Fs;
|
||||||
|
|
||||||
/* Reset decoder */
|
/* Reset decoder */
|
||||||
ret = SKP_Silk_SDK_InitDecoder( st->silk_dec );
|
ret = SKP_Silk_SDK_InitDecoder( silk_dec );
|
||||||
if( ret ) {
|
if( ret ) {
|
||||||
/* Handle error */
|
/* Handle error */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize CELT decoder */
|
/* Initialize CELT decoder */
|
||||||
st->celt_dec = celt_decoder_init(st->celt_dec, Fs, channels, NULL);
|
celt_decoder_init(celt_dec, Fs, channels, NULL);
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_SET_SIGNALLING(0));
|
celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
|
||||||
|
|
||||||
st->prev_mode = 0;
|
st->prev_mode = 0;
|
||||||
return st;
|
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,
|
static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
|
||||||
int len, short *pcm, int frame_size, int decode_fec)
|
int len, short *pcm, int frame_size, int decode_fec)
|
||||||
{
|
{
|
||||||
|
void *silk_dec;
|
||||||
|
CELTDecoder *celt_dec;
|
||||||
int i, silk_ret=0, celt_ret=0;
|
int i, silk_ret=0, celt_ret=0;
|
||||||
ec_dec dec;
|
ec_dec dec;
|
||||||
SKP_SILK_SDK_DecControlStruct DecControl;
|
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;
|
int F2_5, F5, F10;
|
||||||
const celt_word16 *window;
|
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;
|
F10 = st->Fs/100;
|
||||||
F5 = F10>>1;
|
F5 = F10>>1;
|
||||||
F2_5 = F5>>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;
|
SKP_int16 *pcm_ptr = pcm;
|
||||||
|
|
||||||
if (st->prev_mode==MODE_CELT_ONLY)
|
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.API_sampleRate = st->Fs;
|
||||||
DecControl.payloadSize_ms = 1000 * audiosize / 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 {
|
do {
|
||||||
/* Call SILK decoder */
|
/* Call SILK decoder */
|
||||||
int first_frame = decoded_samples == 0;
|
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 );
|
lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size );
|
||||||
if( silk_ret ) {
|
if( silk_ret ) {
|
||||||
fprintf (stderr, "SILK decode error\n");
|
fprintf (stderr, "SILK decode error\n");
|
||||||
|
@ -249,8 +257,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
|
||||||
endband = 21;
|
endband = 21;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(endband));
|
celt_decoder_ctl(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_CHANNELS(st->stream_channels));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redundancy)
|
if (redundancy)
|
||||||
|
@ -262,20 +270,20 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
|
||||||
/* 5 ms redundant frame for CELT->SILK*/
|
/* 5 ms redundant frame for CELT->SILK*/
|
||||||
if (redundancy && celt_to_silk)
|
if (redundancy && celt_to_silk)
|
||||||
{
|
{
|
||||||
celt_decode(st->celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
|
celt_decode(celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE);
|
celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MUST be after PLC */
|
/* 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)
|
if (transition)
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE);
|
celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
|
||||||
|
|
||||||
if (mode != MODE_SILK_ONLY)
|
if (mode != MODE_SILK_ONLY)
|
||||||
{
|
{
|
||||||
/* Decode CELT */
|
/* 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++)
|
for (i=0;i<frame_size*st->channels;i++)
|
||||||
pcm[i] = ADD_SAT16(pcm[i], pcm_celt[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;
|
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;
|
window = celt_mode->window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5 ms redundant frame for SILK->CELT */
|
/* 5 ms redundant frame for SILK->CELT */
|
||||||
if (redundancy && !celt_to_silk)
|
if (redundancy && !celt_to_silk)
|
||||||
{
|
{
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_RESET_STATE);
|
celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
|
||||||
celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0));
|
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,
|
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);
|
pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
#include "opus.h"
|
#include "opus.h"
|
||||||
|
|
||||||
struct OpusDecoder {
|
struct OpusDecoder {
|
||||||
CELTDecoder *celt_dec;
|
int celt_dec_offset;
|
||||||
void *silk_dec;
|
int silk_dec_offset;
|
||||||
int channels;
|
int channels;
|
||||||
int stream_channels;
|
int stream_channels;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ static const int audio_bandwidth_thresholds[10] = {
|
||||||
|
|
||||||
OpusEncoder *opus_encoder_create(int Fs, int channels)
|
OpusEncoder *opus_encoder_create(int Fs, int channels)
|
||||||
{
|
{
|
||||||
|
void *silk_enc;
|
||||||
|
CELTEncoder *celt_enc;
|
||||||
int err;
|
int err;
|
||||||
char *raw_state;
|
char *raw_state;
|
||||||
OpusEncoder *st;
|
OpusEncoder *st;
|
||||||
|
@ -71,13 +73,16 @@ OpusEncoder *opus_encoder_create(int Fs, int channels)
|
||||||
if (raw_state == NULL)
|
if (raw_state == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
st = (OpusEncoder*)raw_state;
|
st = (OpusEncoder*)raw_state;
|
||||||
st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
|
st->silk_enc_offset = sizeof(OpusEncoder);
|
||||||
st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes);
|
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->stream_channels = st->channels = channels;
|
||||||
|
|
||||||
st->Fs = Fs;
|
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 )
|
if( ret )
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
|
@ -94,10 +99,10 @@ OpusEncoder *opus_encoder_create(int Fs, int channels)
|
||||||
|
|
||||||
/* Create CELT encoder */
|
/* Create CELT encoder */
|
||||||
/* Initialize 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)
|
if (err != CELT_OK)
|
||||||
goto failure;
|
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->mode = MODE_HYBRID;
|
||||||
st->bandwidth = BANDWIDTH_FULLBAND;
|
st->bandwidth = BANDWIDTH_FULLBAND;
|
||||||
|
@ -121,6 +126,8 @@ failure:
|
||||||
int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
unsigned char *data, int max_data_bytes)
|
unsigned char *data, int max_data_bytes)
|
||||||
{
|
{
|
||||||
|
void *silk_enc;
|
||||||
|
CELTEncoder *celt_enc;
|
||||||
int i;
|
int i;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
SKP_int32 nBytes;
|
SKP_int32 nBytes;
|
||||||
|
@ -140,6 +147,8 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
int to_celt = 0;
|
int to_celt = 0;
|
||||||
celt_int32 mono_rate;
|
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 */
|
/* Rete-dependent mono-stereo decision */
|
||||||
if (st->channels == 2)
|
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)
|
if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
|
||||||
{
|
{
|
||||||
SKP_SILK_SDK_EncControlStruct dummy;
|
SKP_SILK_SDK_EncControlStruct dummy;
|
||||||
SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
|
SKP_Silk_SDK_InitEncoder( silk_enc, &dummy);
|
||||||
prefill=1;
|
prefill=1;
|
||||||
}
|
}
|
||||||
if (st->prev_mode >0 &&
|
if (st->prev_mode >0 &&
|
||||||
|
@ -321,10 +330,10 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
if (prefill)
|
if (prefill)
|
||||||
{
|
{
|
||||||
int zero=0;
|
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 ) {
|
if( ret ) {
|
||||||
fprintf (stderr, "SILK encode error: %d\n", ret);
|
fprintf (stderr, "SILK encode error: %d\n", ret);
|
||||||
/* Handle error */
|
/* Handle error */
|
||||||
|
@ -364,23 +373,23 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
endband = 21;
|
endband = 21;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
|
celt_encoder_ctl(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_CHANNELS(st->stream_channels));
|
||||||
}
|
}
|
||||||
if (st->mode != MODE_SILK_ONLY)
|
if (st->mode != MODE_SILK_ONLY)
|
||||||
{
|
{
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_VBR(0));
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
|
celt_encoder_ctl(celt_enc, CELT_SET_BITRATE(510000));
|
||||||
if (st->prev_mode == MODE_SILK_ONLY)
|
if (st->prev_mode == MODE_SILK_ONLY)
|
||||||
{
|
{
|
||||||
unsigned char dummy[10];
|
unsigned char dummy[10];
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
|
celt_encoder_ctl(celt_enc, CELT_RESET_STATE);
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
|
||||||
/* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
|
/* TODO: 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_encode(celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10);
|
||||||
} else {
|
} 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)
|
if (st->mode == MODE_HYBRID)
|
||||||
|
@ -397,9 +406,9 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
} else {
|
} else {
|
||||||
if (st->use_vbr)
|
if (st->use_vbr)
|
||||||
{
|
{
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
|
celt_encoder_ctl(celt_enc, CELT_SET_VBR(1));
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_VBR_CONSTRAINT(st->vbr_constraint));
|
celt_encoder_ctl(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_BITRATE(st->bitrate_bps));
|
||||||
nb_compr_bytes = max_data_bytes-1;
|
nb_compr_bytes = max_data_bytes-1;
|
||||||
} else {
|
} else {
|
||||||
nb_compr_bytes = bytes_target;
|
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 */
|
/* 5 ms redundant frame for CELT->SILK */
|
||||||
if (redundancy && celt_to_silk)
|
if (redundancy && celt_to_silk)
|
||||||
{
|
{
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
|
||||||
/* FIXME: That's OK for now, but we need to set the flags properly */
|
celt_encoder_ctl(celt_enc, CELT_SET_VBR(0));
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
|
celt_encode(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
|
||||||
celt_encode(st->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_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)
|
if (st->mode != MODE_SILK_ONLY)
|
||||||
{
|
{
|
||||||
/* Encode high band with CELT */
|
/* 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 */
|
/* 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;
|
N2 = st->Fs/200;
|
||||||
N4 = st->Fs/400;
|
N4 = st->Fs/400;
|
||||||
|
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
|
celt_encoder_ctl(celt_enc, CELT_RESET_STATE);
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
|
||||||
celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
|
||||||
|
|
||||||
/* FIXME: Do proper prefilling here */
|
/* TODO: We could speed up prefilling here */
|
||||||
celt_encode(st->celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
|
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, ...)
|
int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
{
|
{
|
||||||
|
CELTEncoder *celt_enc;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, request);
|
va_start(ap, request);
|
||||||
|
|
||||||
|
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
|
||||||
|
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
case OPUS_SET_MODE_REQUEST:
|
case OPUS_SET_MODE_REQUEST:
|
||||||
|
@ -594,7 +605,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
{
|
{
|
||||||
int value = va_arg(ap, int);
|
int value = va_arg(ap, int);
|
||||||
st->silk_mode.complexity = value;
|
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;
|
break;
|
||||||
case OPUS_GET_COMPLEXITY_REQUEST:
|
case OPUS_GET_COMPLEXITY_REQUEST:
|
||||||
|
@ -621,7 +632,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
if (value < 0 || value > 100)
|
if (value < 0 || value > 100)
|
||||||
return OPUS_BAD_ARG;
|
return OPUS_BAD_ARG;
|
||||||
st->silk_mode.packetLossPercentage = value;
|
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;
|
break;
|
||||||
case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
|
case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
#define MAX_ENCODER_BUFFER 480
|
#define MAX_ENCODER_BUFFER 480
|
||||||
|
|
||||||
struct OpusEncoder {
|
struct OpusEncoder {
|
||||||
CELTEncoder *celt_enc;
|
int celt_enc_offset;
|
||||||
|
int silk_enc_offset;
|
||||||
SKP_SILK_SDK_EncControlStruct silk_mode;
|
SKP_SILK_SDK_EncControlStruct silk_mode;
|
||||||
void *silk_enc;
|
|
||||||
int channels;
|
int channels;
|
||||||
int stream_channels;
|
int stream_channels;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue