Using only a sign for the intra prediction instead of using up to 5 bits for
an offset.
This commit is contained in:
parent
24c9cdaca1
commit
9a8bac019c
4 changed files with 51 additions and 115 deletions
|
@ -331,7 +331,7 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
|
|||
if (q<0)
|
||||
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1]);
|
||||
else
|
||||
intra_prediction(m, X+C*eBands[i], W+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], enc);
|
||||
intra_prediction(m, X+C*eBands[i], W+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1], enc);
|
||||
}
|
||||
|
||||
if (q > 0)
|
||||
|
@ -389,7 +389,7 @@ void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P,
|
|||
if (q<0)
|
||||
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1]);
|
||||
else
|
||||
intra_unquant(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], dec);
|
||||
intra_unquant(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1], dec);
|
||||
}
|
||||
|
||||
if (q > 0)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define BITOVERFLOW 10000
|
||||
|
||||
#ifndef STATIC_MODES
|
||||
#if 0
|
||||
static int log2_frac(ec_uint32 val, int frac)
|
||||
{
|
||||
int i;
|
||||
|
@ -70,6 +71,7 @@ static int log2_frac(ec_uint32 val, int frac)
|
|||
}
|
||||
return L;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int log2_frac64(ec_uint64 val, int frac)
|
||||
{
|
||||
|
@ -135,14 +137,9 @@ void compute_alloc_cache(CELTMode *m)
|
|||
/* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
|
||||
if (bits[i][j] > (60<<BITRES))
|
||||
done = 1;
|
||||
/* Add the intra-frame prediction bits */
|
||||
/* Add the intra-frame prediction sign bit */
|
||||
if (eBands[i] >= m->pitchEnd)
|
||||
{
|
||||
int max_pos = 2*eBands[i]-eBands[i+1];
|
||||
if (max_pos > 32)
|
||||
max_pos = 32;
|
||||
bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
|
||||
}
|
||||
bits[i][j] += (1<<BITRES);
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
|
|
147
libcelt/vq.c
147
libcelt/vq.c
|
@ -267,76 +267,41 @@ static const celt_word16_t pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55
|
|||
#define MAX_INTRA 32
|
||||
#define LOG_MAX_INTRA 5
|
||||
|
||||
void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, ec_enc *enc)
|
||||
void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_enc *enc)
|
||||
{
|
||||
int i,j,c;
|
||||
int best=0;
|
||||
celt_word16_t best_num=-VERY_LARGE16;
|
||||
celt_word16_t best_den=0;
|
||||
int i,j;
|
||||
celt_word16_t s = 1;
|
||||
int sign;
|
||||
celt_word32_t E;
|
||||
celt_word16_t pred_gain;
|
||||
int max_pos = N0-N;
|
||||
celt_word32_t yy=0;
|
||||
VARDECL(celt_norm_t, Xr);
|
||||
celt_word32_t xy=0;
|
||||
const int C = CHANNELS(m);
|
||||
SAVE_STACK;
|
||||
|
||||
ALLOC(Xr, C*N, celt_norm_t);
|
||||
|
||||
if (max_pos > MAX_INTRA)
|
||||
max_pos = MAX_INTRA;
|
||||
|
||||
/* Reverse the samples of x without reversing the channels */
|
||||
for (c=0;c<C;c++)
|
||||
if (K>10)
|
||||
pred_gain = pg[10];
|
||||
else
|
||||
pred_gain = pg[K];
|
||||
E = EPSILON;
|
||||
if (N0 >= (Nmax>>1))
|
||||
{
|
||||
celt_norm_t * restrict Xrp = &Xr[C*N-C+c];
|
||||
const celt_norm_t * restrict xp = &x[c];
|
||||
j=0; do {
|
||||
*Xrp = *xp;
|
||||
Xrp -= C;
|
||||
xp += C;
|
||||
} while (++j<N); /* Promises we loop at least once */
|
||||
}
|
||||
/* Compute yy for i=0 */
|
||||
j=0;
|
||||
do {
|
||||
yy = MAC16_16(yy, Y[j], Y[j]);
|
||||
} while (++j<C*N); /* Promises we loop at least once */
|
||||
|
||||
for (i=0;i<max_pos;i++)
|
||||
{
|
||||
celt_word32_t xy=0;
|
||||
celt_word16_t num, den;
|
||||
const celt_word16_t * restrict xp = Xr;
|
||||
const celt_word16_t * restrict yp = Y+C*i;
|
||||
j=0;
|
||||
do {
|
||||
xy = MAC16_16(xy, *xp++, *yp++);
|
||||
} while (++j<C*N); /* Promises we loop at least once */
|
||||
/* Using xy^2/yy as the score but without having to do the division */
|
||||
num = MULT16_16_Q15(ROUND16(xy,14),ROUND16(xy,14));
|
||||
den = ROUND16(yy,14);
|
||||
/* If you're really desperate for speed, just use xy as the score */
|
||||
/* OPT: Make sure to use a conditional move here */
|
||||
if (MULT16_16(best_den, num) > MULT16_16(den, best_num))
|
||||
for (i=0;i<C;i++)
|
||||
{
|
||||
best_num = num;
|
||||
best_den = den;
|
||||
best = i;
|
||||
/* Store xy as the sign. We'll normalise it to +/- 1 later. */
|
||||
s = ROUND16(xy,14);
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
P[j*C+i] = Y[(Nmax-N0-j-1)*C+i];
|
||||
E += P[j*C+i]*P[j*C+i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j=0;j<C*N;j++)
|
||||
{
|
||||
P[j] = Y[j];
|
||||
E = MAC16_16(E, P[j],P[j]);
|
||||
}
|
||||
/* Update yy for the next iteration */
|
||||
yp = Y+C*i;
|
||||
j=0;
|
||||
do {
|
||||
yy = yy - MULT16_16(*yp, *yp) + MULT16_16(yp[C*N], yp[C*N]);
|
||||
yp++;
|
||||
} while (++j<C);
|
||||
}
|
||||
if (s<0)
|
||||
for (j=0;j<C*N;j++)
|
||||
xy = MAC16_16(xy, P[j], x[j]);
|
||||
if (xy<0)
|
||||
{
|
||||
s = -1;
|
||||
sign = 1;
|
||||
|
@ -344,30 +309,10 @@ void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *
|
|||
s = 1;
|
||||
sign = 0;
|
||||
}
|
||||
/*printf ("%d %d ", sign, best);*/
|
||||
ec_enc_bits(enc,sign,1);
|
||||
if (max_pos == MAX_INTRA)
|
||||
ec_enc_bits(enc,best,LOG_MAX_INTRA);
|
||||
else
|
||||
ec_enc_uint(enc,best,max_pos);
|
||||
|
||||
/*printf ("%d %f\n", best, best_score);*/
|
||||
|
||||
if (K>10)
|
||||
pred_gain = pg[10];
|
||||
else
|
||||
pred_gain = pg[K];
|
||||
E = EPSILON;
|
||||
for (c=0;c<C;c++)
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
P[C*j+c] = s*Y[C*best+C*(N-j-1)+c];
|
||||
E = MAC16_16(E, P[C*j+c],P[C*j+c]);
|
||||
}
|
||||
}
|
||||
/*pred_gain = pred_gain/sqrt(E);*/
|
||||
pred_gain = MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
|
||||
pred_gain = s*MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
|
||||
for (j=0;j<C*N;j++)
|
||||
P[j] = PSHR32(MULT16_16(pred_gain, P[j]),8);
|
||||
if (K>0)
|
||||
|
@ -378,51 +323,45 @@ void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *
|
|||
for (j=0;j<C*N;j++)
|
||||
x[j] = P[j];
|
||||
}
|
||||
/*printf ("quant ");*/
|
||||
/*for (j=0;j<N;j++) printf ("%f ", P[j]);*/
|
||||
RESTORE_STACK;
|
||||
}
|
||||
|
||||
void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, ec_dec *dec)
|
||||
void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_dec *dec)
|
||||
{
|
||||
int j, c;
|
||||
int sign;
|
||||
int i, j;
|
||||
celt_word16_t s;
|
||||
int best;
|
||||
celt_word32_t E;
|
||||
celt_word16_t pred_gain;
|
||||
const int C = CHANNELS(m);
|
||||
int max_pos = N0-N;
|
||||
if (max_pos > MAX_INTRA)
|
||||
max_pos = MAX_INTRA;
|
||||
|
||||
sign = ec_dec_bits(dec, 1);
|
||||
if (sign == 0)
|
||||
|
||||
if (ec_dec_bits(dec, 1) == 0)
|
||||
s = 1;
|
||||
else
|
||||
s = -1;
|
||||
|
||||
if (max_pos == MAX_INTRA)
|
||||
best = C*ec_dec_bits(dec, LOG_MAX_INTRA);
|
||||
else
|
||||
best = C*ec_dec_uint(dec, max_pos);
|
||||
/*printf ("%d %d ", sign, best);*/
|
||||
|
||||
if (K>10)
|
||||
pred_gain = pg[10];
|
||||
else
|
||||
pred_gain = pg[K];
|
||||
E = EPSILON;
|
||||
for (c=0;c<C;c++)
|
||||
if (N0 >= (Nmax>>1))
|
||||
{
|
||||
for (j=0;j<N;j++)
|
||||
for (i=0;i<C;i++)
|
||||
{
|
||||
P[C*j+c] = s*Y[best+C*(N-j-1)+c];
|
||||
E = MAC16_16(E, P[C*j+c],P[C*j+c]);
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
P[j*C+i] = Y[(Nmax-N0-j-1)*C+i];
|
||||
E += P[j*C+i]*P[j*C+i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (j=0;j<C*N;j++)
|
||||
{
|
||||
P[j] = Y[j];
|
||||
E = MAC16_16(E, P[j],P[j]);
|
||||
}
|
||||
}
|
||||
/*pred_gain = pred_gain/sqrt(E);*/
|
||||
pred_gain = MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
|
||||
pred_gain = s*MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
|
||||
for (j=0;j<C*N;j++)
|
||||
P[j] = PSHR32(MULT16_16(pred_gain, P[j]),8);
|
||||
if (K==0)
|
||||
|
|
|
@ -73,9 +73,9 @@ void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, ec_dec *dec);
|
|||
* @param N0 Number of valid offsets
|
||||
* @param enc Entropy encoder state
|
||||
*/
|
||||
void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, ec_enc *enc);
|
||||
void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_enc *enc);
|
||||
|
||||
void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t *P, int N0, ec_dec *dec);
|
||||
void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t *P, int N0, int Nmax, ec_dec *dec);
|
||||
|
||||
/** Encode the entire band as a "fold" from other parts of the spectrum. No bits required (only use is case of an emergency!) */
|
||||
void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t *P, int N0, int Nmax);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue