ref: 3252bf2a68272b887fabbd654e10ca88378039ca
parent: a8783a15b4af956487c3b22591be5f0750b6987c
author: Jean-Marc Valin <[email protected]>
date: Thu Apr 18 23:14:28 EDT 2013
Variable framesize improvements - Properly apply the transient boost by counting all the bits in the cost - Disable the post-filter for non-20-ms frames that follow a transient (applies only to variable framesize)
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -73,6 +73,7 @@
int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
int loss_rate;
int lsb_depth;
+ int variable_duration;
/* Everything beyond this point gets cleared on a reset */
#define ENCODER_RESET_START rng
@@ -1162,6 +1163,7 @@
const opus_int16 *eBands;
int secondMdct;
int signalBandwidth;
+ int transient_got_disabled;
ALLOC_STACK;
mode = st->mode;
@@ -1325,7 +1327,8 @@
{
int enabled;
int qg;
- enabled = nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5;
+ enabled = nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf
+ && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration);
prefilter_tapset = st->tapset_decision;
pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes);
@@ -1364,6 +1367,7 @@
shortBlocks = M;
} else {
isTransient = 0;
+ transient_got_disabled=1;
}
ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
@@ -1874,7 +1878,7 @@
}
} while (++c<CC);
- if (isTransient)
+ if (isTransient || transient_got_disabled)
st->consec_transient++;
else
st->consec_transient=0;
@@ -2056,6 +2060,12 @@
{
opus_int32 *value = va_arg(ap, opus_int32*);
*value=st->lsb_depth;
+ }
+ break;
+ case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ st->variable_duration = value;
}
break;
case OPUS_RESET_STATE:
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -597,11 +597,17 @@
int states[MAX_DYNAMIC_FRAMESIZE][16];
float best_cost;
int best_state;
-
+ float factor;
+ /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */
+ if (rate<80)
+ factor=0;
+ else if (rate>160)
+ factor=1;
+ else
+ factor = (rate-80.f)/80.f;
/* Makes variable framesize less aggressive at lower bitrates, but I can't
- find any valid theretical justification for this (other than it seems
+ find any valid theoretical justification for this (other than it seems
to help) */
- frame_cost *= 720/rate;
for (i=0;i<16;i++)
{
/* Impossible state */
@@ -610,7 +616,7 @@
}
for (i=0;i<4;i++)
{
- cost[0][1<<i] = frame_cost + rate*(1<<i)*transient_boost(E, E_1, i, N+1);
+ cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));
states[0][1<<i] = i;
}
for (i=1;i<N;i++)
@@ -641,7 +647,7 @@
min_cost = tmp;
}
}
- curr_cost = frame_cost+rate*(1<<j)*transient_boost(E+i, E_1+i, j, N-i+1);
+ curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));
cost[i][1<<j] = min_cost;
/* If part of the frame is outside the analysis window, only count part of the cost */
if (N-i < (1<<j))
@@ -760,7 +766,7 @@
e[i+pos] = e[i+pos-1];
if (buffering)
N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);
- bestLM = transient_viterbi(e, e_1, N, (1.f+.5*tonality)*(40*C+40), bitrate/400);
+ bestLM = transient_viterbi(e, e_1, N, (1.f+.5*tonality)*(60*C+40), bitrate/400);
mem[0] = e[1<<bestLM];
if (buffering)
{
@@ -1548,7 +1554,7 @@
#ifndef FIXED_POINT
if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
{
- bonus = (40*st->stream_channels+40)*(st->Fs/frame_size-50);
+ bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
if (analysis_info->valid)
bonus = bonus*(1.f+.5*analysis_info->tonality);
}
@@ -2159,6 +2165,7 @@
{
opus_int32 value = va_arg(ap, opus_int32);
st->variable_duration = value;
+ celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));
}
break;
case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: