Using only a sign for the intra prediction instead of using up to 5 bits for
an offset.
diff --git a/libcelt/vq.c b/libcelt/vq.c
index 886763f..3a5d718 100644
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -267,76 +267,41 @@
#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];
+ }
}
- /* 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);
+ } else {
+ for (j=0;j<C*N;j++)
+ {
+ P[j] = Y[j];
+ E = MAC16_16(E, P[j],P[j]);
+ }
}
- 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 @@
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 @@
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)