diff options
author | Rostislav Pehlivanov <atomnuker@gmail.com> | 2017-04-08 00:53:31 +0100 |
---|---|---|
committer | Rostislav Pehlivanov <atomnuker@gmail.com> | 2017-04-08 00:54:56 +0100 |
commit | d0a3143193ff3284f3dfbcc173bb94c9b91077d0 (patch) | |
tree | dcb203887c5b7c7eef9bd633fdaad8a52da2457a | |
parent | c39fba703bf35da0b4b894b2b33978c205507341 (diff) | |
download | ffmpeg-d0a3143193ff3284f3dfbcc173bb94c9b91077d0.tar.gz |
opusenc: switch between intra/inter mode for coarse energy
Saves around 5kbps.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
-rw-r--r-- | libavcodec/opus_celt.h | 1 | ||||
-rw-r--r-- | libavcodec/opusenc.c | 36 |
2 files changed, 28 insertions, 9 deletions
diff --git a/libavcodec/opus_celt.h b/libavcodec/opus_celt.h index 1ed57f3651..f0d55d600b 100644 --- a/libavcodec/opus_celt.h +++ b/libavcodec/opus_celt.h @@ -100,7 +100,6 @@ struct CeltFrame { int end_band; int coded_bands; int transient; - int intra; int pfilter; int skip_band_floor; int tf_select; diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c index 4e0781bf51..5f5700ea50 100644 --- a/libavcodec/opusenc.c +++ b/libavcodec/opusenc.c @@ -630,19 +630,20 @@ static void ff_celt_enc_bitalloc(OpusRangeCoder *rc, CeltFrame *f) } } -static void celt_quant_coarse(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f) +static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, + float last_energy[][CELT_MAX_BANDS], int intra) { int i, ch; float alpha, beta, prev[2] = { 0, 0 }; - const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][f->intra]; + const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra]; /* Inter is really just differential coding */ if (opus_rc_tell(rc) + 3 <= f->framebits) - ff_opus_rc_enc_log(rc, f->intra, 3); + ff_opus_rc_enc_log(rc, intra, 3); else - f->intra = 0; + intra = 0; - if (f->intra) { + if (intra) { alpha = 0.0f; beta = 1.0f - 4915.0f/32768.0f; } else { @@ -654,7 +655,7 @@ static void celt_quant_coarse(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame * for (ch = 0; ch < f->channels; ch++) { CeltBlock *block = &f->block[ch]; const int left = f->framebits - opus_rc_tell(rc); - const float last = FFMAX(-9.0f, s->last_quantized_energy[ch][i]); + const float last = FFMAX(-9.0f, last_energy[ch][i]); float diff = block->energy[i] - prev[ch] - last*alpha; int q_en = lrintf(diff); if (left >= 15) { @@ -673,6 +674,26 @@ static void celt_quant_coarse(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame * } } +static void celt_quant_coarse(OpusRangeCoder *rc, CeltFrame *f, + float last_energy[][CELT_MAX_BANDS]) +{ + uint32_t inter, intra; + OPUS_RC_CHECKPOINT_SPAWN(rc); + + exp_quant_coarse(rc, f, last_energy, 1); + intra = OPUS_RC_CHECKPOINT_BITS(rc); + + OPUS_RC_CHECKPOINT_ROLLBACK(rc); + + exp_quant_coarse(rc, f, last_energy, 0); + inter = OPUS_RC_CHECKPOINT_BITS(rc); + + if (inter > intra) { /* Unlikely */ + OPUS_RC_CHECKPOINT_ROLLBACK(rc); + exp_quant_coarse(rc, f, last_energy, 1); + } +} + static void celt_quant_fine(OpusRangeCoder *rc, CeltFrame *f) { int i, ch; @@ -823,7 +844,7 @@ static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame * if (f->size && opus_rc_tell(rc) + 3 <= f->framebits) ff_opus_rc_enc_log(rc, f->transient, 3); - celt_quant_coarse (s, rc, f); + celt_quant_coarse(rc, f, s->last_quantized_energy); celt_enc_tf (rc, f); ff_celt_enc_bitalloc(rc, f); celt_quant_fine (rc, f); @@ -871,7 +892,6 @@ static void ff_opus_psy_celt_frame_setup(OpusEncContext *s, CeltFrame *f, int in f->silence = 0; f->pfilter = 0; f->transient = 0; - f->intra = 1; f->tf_select = 0; f->anticollapse = 0; f->alloc_trim = 5; |