From e3de5057b6a24905f0c86bc5155e90d859ba86d9 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> Date: Sun, 20 Feb 2011 12:23:48 -0500 Subject: [PATCH] Buffer pre-filling in the encoder --- src/opus_encoder.c | 18 +++++++++++++----- src/opus_encoder.h | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/opus_encoder.c b/src/opus_encoder.c index d69a062c9..257eca6f3 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -94,6 +94,7 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, int framerate, period; int silk_internal_bandwidth; int bytes_target; + int prefill=0; bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1; @@ -102,6 +103,7 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, { SKP_SILK_SDK_EncControlStruct dummy; SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy); + prefill=1; } ec_enc_init(&enc, data, max_data_bytes-1); @@ -152,6 +154,9 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, /* Call SILK encoder for the low band */ nBytes = max_data_bytes-1; + if (prefill) + SKP_Silk_SDK_Encoder_prefill_buffer(st->silk_enc, &st->silk_mode, st->delay_buffer, ENCODER_BUFFER); + ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes ); if( ret ) { fprintf (stderr, "SILK encode error: %d\n", ret); @@ -200,8 +205,11 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000)); if (st->prev_mode == MODE_SILK_ONLY) { + unsigned char dummy[2]; celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE); 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[(ENCODER_BUFFER-ENCODER_DELAY_COMPENSATION-120)*st->channels], 120, dummy, 10); } else { celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2)); } @@ -230,7 +238,7 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, } for (i=0;i<IMIN(frame_size, ENCODER_DELAY_COMPENSATION)*st->channels;i++) - pcm_buf[i] = st->delay_buffer[i]; + pcm_buf[i] = st->delay_buffer[(ENCODER_BUFFER-ENCODER_DELAY_COMPENSATION)*st->channels+i]; for (;i<frame_size*st->channels;i++) pcm_buf[i] = pcm[i-ENCODER_DELAY_COMPENSATION*st->channels]; @@ -239,12 +247,12 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size, /* Encode high band with CELT */ ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); - if (frame_size>ENCODER_DELAY_COMPENSATION) + if (frame_size>ENCODER_BUFFER) { - for (i=0;i<ENCODER_DELAY_COMPENSATION*st->channels;i++) - st->delay_buffer[i] = pcm[(frame_size-ENCODER_DELAY_COMPENSATION)*st->channels+i]; + for (i=0;i<ENCODER_BUFFER*st->channels;i++) + st->delay_buffer[i] = pcm[(frame_size-ENCODER_BUFFER)*st->channels+i]; } else { - int tmp = ENCODER_DELAY_COMPENSATION-frame_size; + int tmp = ENCODER_BUFFER-frame_size; for (i=0;i<tmp*st->channels;i++) st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels]; for (i=0;i<frame_size*st->channels;i++) diff --git a/src/opus_encoder.h b/src/opus_encoder.h index aec775b23..a800a7477 100644 --- a/src/opus_encoder.h +++ b/src/opus_encoder.h @@ -34,6 +34,7 @@ /* FIXME: This is only valid for 48 kHz */ #define ENCODER_DELAY_COMPENSATION 130 +#define ENCODER_BUFFER 480 struct OpusEncoder { CELTEncoder *celt_enc; @@ -50,7 +51,7 @@ struct OpusEncoder { int use_vbr; int bitrate_bps; - short delay_buffer[ENCODER_DELAY_COMPENSATION*2]; + short delay_buffer[ENCODER_BUFFER*2]; #ifdef OPUS_TEST_RANGE_CODER_STATE int rangeFinal; -- GitLab