mirror of
https://github.com/xiph/opus.git
synced 2025-06-06 07:21:03 +00:00
Improving rate control for low bitrate
Using a finer table for the rate to SNR curves in silk_control_SNR(). It's now possible to have an SNR that reaches 0, so we can lower bitrate down to ~5 kbps for narrowband and 5.5 kbps for wideband.
This commit is contained in:
parent
004ef8b9b1
commit
85ce87ffbe
4 changed files with 70 additions and 53 deletions
|
@ -32,44 +32,82 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "tuning_parameters.h"
|
#include "tuning_parameters.h"
|
||||||
|
|
||||||
|
/* These tables hold SNR values divided by 21 (so they fit in 8 bits)
|
||||||
|
for different target bitrates spaced at 400 bps interval. The first
|
||||||
|
10 values are omitted (0-4 kb/s) because they're all zeros.
|
||||||
|
These tables were obtained by running different SNRs through the
|
||||||
|
encoder and measuring the active bitrate. */
|
||||||
|
static const unsigned char silk_TargetRate_NB_21[117 - 10] = {
|
||||||
|
0, 15, 39, 52, 61, 68,
|
||||||
|
74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124,
|
||||||
|
126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157,
|
||||||
|
158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182,
|
||||||
|
183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204,
|
||||||
|
205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225,
|
||||||
|
227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248,
|
||||||
|
249,250,252,253,255
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char silk_TargetRate_MB_21[165 - 10] = {
|
||||||
|
0, 0, 28, 43, 52, 59,
|
||||||
|
65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109,
|
||||||
|
111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136,
|
||||||
|
137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157,
|
||||||
|
158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175,
|
||||||
|
176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,
|
||||||
|
191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205,
|
||||||
|
206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,
|
||||||
|
221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235,
|
||||||
|
236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,
|
||||||
|
251,252,253,254,255
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char silk_TargetRate_WB_21[201 - 10] = {
|
||||||
|
0, 0, 0, 8, 29, 41,
|
||||||
|
49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99,
|
||||||
|
101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125,
|
||||||
|
126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144,
|
||||||
|
145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160,
|
||||||
|
161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175,
|
||||||
|
176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188,
|
||||||
|
189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,
|
||||||
|
200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211,
|
||||||
|
212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,
|
||||||
|
224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234,
|
||||||
|
235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246,
|
||||||
|
247,248,249,249,250,251,252,253,255
|
||||||
|
};
|
||||||
|
|
||||||
/* Control SNR of redidual quantizer */
|
/* Control SNR of redidual quantizer */
|
||||||
opus_int silk_control_SNR(
|
opus_int silk_control_SNR(
|
||||||
silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
|
silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
|
||||||
opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
|
opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int k, ret = SILK_NO_ERROR;
|
int id;
|
||||||
opus_int32 frac_Q6;
|
int bound;
|
||||||
const opus_int32 *rateTable;
|
const unsigned char *snr_table;
|
||||||
|
|
||||||
/* Set bitrate/coding quality */
|
psEncC->TargetRate_bps = TargetRate_bps;
|
||||||
TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
|
if( psEncC->nb_subfr == 2 ) {
|
||||||
if( TargetRate_bps != psEncC->TargetRate_bps ) {
|
TargetRate_bps -= 2000 + psEncC->fs_kHz/16;
|
||||||
psEncC->TargetRate_bps = TargetRate_bps;
|
|
||||||
|
|
||||||
/* If new TargetRate_bps, translate to SNR_dB value */
|
|
||||||
if( psEncC->fs_kHz == 8 ) {
|
|
||||||
rateTable = silk_TargetRate_table_NB;
|
|
||||||
} else if( psEncC->fs_kHz == 12 ) {
|
|
||||||
rateTable = silk_TargetRate_table_MB;
|
|
||||||
} else {
|
|
||||||
rateTable = silk_TargetRate_table_WB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reduce bitrate for 10 ms modes in these calculations */
|
|
||||||
if( psEncC->nb_subfr == 2 ) {
|
|
||||||
TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find bitrate interval in table and interpolate */
|
|
||||||
for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
|
|
||||||
if( TargetRate_bps <= rateTable[ k ] ) {
|
|
||||||
frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] );
|
|
||||||
psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if( psEncC->fs_kHz == 8 ) {
|
||||||
return ret;
|
bound = sizeof(silk_TargetRate_NB_21);
|
||||||
|
snr_table = silk_TargetRate_NB_21;
|
||||||
|
} else if( psEncC->fs_kHz == 12 ) {
|
||||||
|
bound = sizeof(silk_TargetRate_MB_21);
|
||||||
|
snr_table = silk_TargetRate_MB_21;
|
||||||
|
} else {
|
||||||
|
bound = sizeof(silk_TargetRate_WB_21);
|
||||||
|
snr_table = silk_TargetRate_WB_21;
|
||||||
|
}
|
||||||
|
id = (TargetRate_bps+200)/400;
|
||||||
|
id = silk_min(id - 10, bound-1);
|
||||||
|
if( id <= 0 ) {
|
||||||
|
psEncC->SNR_dB_Q7 = 0;
|
||||||
|
} else {
|
||||||
|
psEncC->SNR_dB_Q7 = snr_table[id]*21;
|
||||||
|
}
|
||||||
|
return SILK_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ extern "C"
|
||||||
/* Limits on bitrate */
|
/* Limits on bitrate */
|
||||||
#define MIN_TARGET_RATE_BPS 5000
|
#define MIN_TARGET_RATE_BPS 5000
|
||||||
#define MAX_TARGET_RATE_BPS 80000
|
#define MAX_TARGET_RATE_BPS 80000
|
||||||
#define TARGET_RATE_TAB_SZ 8
|
|
||||||
|
|
||||||
/* LBRR thresholds */
|
/* LBRR thresholds */
|
||||||
#define LBRR_NB_MIN_RATE_BPS 12000
|
#define LBRR_NB_MIN_RATE_BPS 12000
|
||||||
|
|
|
@ -97,12 +97,6 @@ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ];
|
||||||
extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */
|
extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */
|
||||||
extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */
|
extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */
|
||||||
|
|
||||||
/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
|
|
||||||
extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */
|
|
||||||
extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */
|
|
||||||
extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */
|
|
||||||
extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */
|
|
||||||
|
|
||||||
/* Quantization offsets */
|
/* Quantization offsets */
|
||||||
extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */
|
extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */
|
||||||
|
|
||||||
|
|
|
@ -38,20 +38,6 @@ extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
|
|
||||||
const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
|
|
||||||
0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS
|
|
||||||
};
|
|
||||||
const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
|
|
||||||
0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS
|
|
||||||
};
|
|
||||||
const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
|
|
||||||
0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS
|
|
||||||
};
|
|
||||||
const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
|
|
||||||
18, 29, 38, 40, 46, 52, 62, 84
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Tables for stereo predictor coding */
|
/* Tables for stereo predictor coding */
|
||||||
const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
|
const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
|
||||||
-13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
|
-13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue