/*------------------------------------------------------------*/ void sbtB8_dual_L3(float *sample, unsigned char *pcm, int ch) { int i; if (ch == 0) { for (i = 0; i < 18; i++) { fdct8(sample, pMP3Stream->vbuf + pMP3Stream->vb_ptr); windowB8_dual(pMP3Stream->vbuf, pMP3Stream->vb_ptr, pcm); sample += 32; pMP3Stream->vb_ptr = (pMP3Stream->vb_ptr - 8) & 127; pcm += 16; } } else { for (i = 0; i < 18; i++) { fdct8(sample, pMP3Stream->vbuf2 + pMP3Stream->vb2_ptr); windowB8_dual(pMP3Stream->vbuf2, pMP3Stream->vb2_ptr, pcm + 1); sample += 32; pMP3Stream->vb2_ptr = (pMP3Stream->vb2_ptr - 8) & 127; pcm += 16; } } }
void sbt8_dual_L3(float *sample, short *pcm, int ch) { int i; if (ch == 0) { for (i = 0; i < 18; i++) { fdct8(sample, vbuf + vb_ptr); window8_dual(vbuf, vb_ptr, pcm); sample += 32; vb_ptr = (vb_ptr - 8) & 127; pcm += 16; } } else { for (i = 0; i < 18; i++) { fdct8(sample, vbuf2 + vb2_ptr); window8_dual(vbuf2, vb2_ptr, pcm + 1); sample += 32; vb2_ptr = (vb2_ptr - 8) & 127; pcm += 16; } } }
/*Performs a forward 8x8 Type-II DCT transform. The output is scaled by a factor of 4 relative to the orthonormal version of the transform. _y: The buffer to store the result in. This may be the same as _x. _x: The input coefficients. */ void oc_fdct8x8(ogg_int16_t _y[64],const ogg_int16_t _x[64]){ const ogg_int16_t *in; ogg_int16_t *end; ogg_int16_t *out; ogg_int16_t w[64]; /*Transform rows of x into columns of w.*/ for(in=_x,out=w,end=out+8;out<end;in+=8,out++)fdct8(out,in); /*Transform rows of w into columns of y.*/ for(in=w,out=_y,end=out+8;out<end;in+=8,out++)fdct8(out,in); }
/*Performs a forward 8x8 Type-II DCT transform on blocks which overlap the border of the picture region. This method ONLY works with rectangular regions. _border: A description of which pixels are inside the border. _y: The buffer to store the result in. This may be the same as _x. _x: The input coefficients. Pixel values outside the border will be modified.*/ void oc_fdct8x8_border(const oc_border_info *_border,ogg_int16_t _y[64], ogg_int16_t _x[64]){ ogg_int16_t *in; ogg_int16_t *end; ogg_int16_t *out; ogg_int16_t w[64]; ogg_int64_t mask; const oc_extension_info *rext; const oc_extension_info *cext; int rmask; int cmask; int ri; /*Identify the shapes of the non-zero rows and columns.*/ rmask=cmask=0; mask=_border->mask; for(ri=0;ri<8;ri++){ rmask|=mask&0xFF; cmask|=((mask&0xFF)!=0)<<ri; mask>>=8; } /*Find the associated extension info for these shapes.*/ if(rmask==0xFF)rext=NULL; else for(rext=OC_EXTENSION_INFO;rext->mask!=rmask;){ /*If we somehow can't find the shape, then just do an unpadded fDCT. It won't be efficient, but it should still be correct.*/ if(++rext>=OC_EXTENSION_INFO+OC_NSHAPES){ oc_fdct8x8(_y,_x); return; } } if(cmask==0xFF)cext=NULL; else for(cext=OC_EXTENSION_INFO;cext->mask!=cmask;){ /*If we somehow can't find the shape, then just do an unpadded fDCT. It won't be efficient, but it should still be correct.*/ if(++cext>=OC_EXTENSION_INFO+OC_NSHAPES){ oc_fdct8x8(_y,_x); return; } } /*Transform the rows. We can ignore zero rows without a problem.*/ if(rext==NULL)for(in=_x,out=w,end=out+8;out<end;in+=8,out++)fdct8(out,in); else for(in=_x,out=w,end=out+8,ri=cmask;out<end;in+=8,out++,ri>>=1){ if(ri&1)fdct8_ext(out,in,rext); } /*Transform the columns. We transform even columns that are supposedly zero, because rounding errors may make them slightly non-zero, and this will give a more precise reconstruction with very small quantizers.*/ if(cext==NULL)for(in=w,out=_y,end=out+8;out<end;in+=8,out++)fdct8(out,in); else for(in=w,out=_y,end=out+8;out<end;in+=8,out++)fdct8_ext(out,in,cext); }
/*Pads a single row of a partial block and then performs a forward Type-II DCT on the result. The output is scaled by a factor of 2 from the orthonormal version of the transform. _y: The buffer to store the result in. Data will be placed in every 8th entry (e.g., in a column of an 8x8 block). _x: The input coefficients. The first 8 entries are used (e.g., from a row of an 8x8 block). _e: The extension information for the shape.*/ static void fdct8_ext(ogg_int16_t *_y,ogg_int16_t _x[8], const oc_extension_info *_e){ if(_e->na==1){ int ci; /*While the branch below is still correct for shapes with na==1, we can perform the entire transform with just 1 multiply in this case instead of 23.*/ _y[0]=(ogg_int16_t)(OC_DIV2_16(OC_C4S4*(_x[_e->pi[0]]<<3))); for(ci=8;ci<64;ci+=8)_y[ci]=0; } else{ int zpi; int api; int nz; /*First multiply by the extension matrix to compute the padding values.*/ nz=8-_e->na; for(zpi=0;zpi<nz;zpi++){ ogg_int32_t v; v=0; for(api=0;api<_e->na;api++)v+=_e->ext[zpi][api]*_x[_e->pi[api]]; _x[_e->pi[zpi+_e->na]]= (ogg_int16_t)OC_DIV_ROUND_POW2(v,OC_EXT_SHIFT,1<<OC_EXT_SHIFT-1); } fdct8(_y,_x); } }
int main( int argc , char * argv[] ) { int xx[8] = { 1,2,3,4,4,4,3,2 } ; int yy[8] ; float zz[8] ; int ii ; for( ii=0 ;ii < 8 ; ii++ ) zz[ii] = xx[ii] ; memcpy(yy,xx,sizeof(int)*8) ; printf("y = %d %d %d %d %d %d %d %d\n", yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],yy[6],yy[7]) ; dct8_ref(yy) ; printf("dct8_ref = %d %d %d %d %d %d %d %d\n", yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],yy[6],yy[7]) ; idct8_ref(yy) ; printf("idct8_ref = %d %d %d %d %d %d %d %d\n", yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],yy[6],yy[7]) ; memcpy(yy,xx,sizeof(int)*8) ; dct8(yy) ; printf("dct8 = %d %d %d %d %d %d %d %d\n", yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],yy[6],yy[7]) ; idct8(yy) ; printf("idct8 = %d %d %d %d %d %d %d %d\n", yy[0],yy[1],yy[2],yy[3],yy[4],yy[5],yy[6],yy[7]) ; fdct8(zz) ; printf("fdct8 = %g %g %g %g %g %g %g %g\n", zz[0],zz[1],zz[2],zz[3],zz[4],zz[5],zz[6],zz[7]) ; ifdct8(zz) ; printf("ifdct8 = %g %g %g %g %g %g %g %g\n", zz[0],zz[1],zz[2],zz[3],zz[4],zz[5],zz[6],zz[7]) ; exit(0) ; }
/*------------------------------------------------------------*/ void sbtB8_mono_L3(float *sample, unsigned char *pcm, int ch) { int i; ch = 0; for (i = 0; i < 18; i++) { fdct8(sample, pMP3Stream->vbuf + pMP3Stream->vb_ptr); windowB8(pMP3Stream->vbuf, pMP3Stream->vb_ptr, pcm); sample += 32; pMP3Stream->vb_ptr = (pMP3Stream->vb_ptr - 8) & 127; pcm += 8; } }
void sbt8_mono(float *sample, short *pcm, int n) { int i; for (i = 0; i < n; i++) { fdct8(sample, vbuf + vb_ptr); window8(vbuf, vb_ptr, pcm); sample += 64; vb_ptr = (vb_ptr - 8) & 127; pcm += 8; } }
/*------------------------------------------------------------*/ void sbt8_mono(MPEG *m, float *sample, short *pcm, int n) { int i; for (i = 0; i < n; i++) { fdct8(m,sample, m->csbt.vbuf + m->csbt.vb_ptr); window8(m,m->csbt.vbuf, m->csbt.vb_ptr, pcm); sample += 64; m->csbt.vb_ptr = (m->csbt.vb_ptr - 8) & 127; pcm += 8; } }
/*------------------------------------------------------------*/ void sbtB8_mono(float *sample, unsigned char *pcm, int n) { int i; for (i = 0; i < n; i++) { fdct8(sample, pMP3Stream->vbuf + pMP3Stream->vb_ptr); windowB8(pMP3Stream->vbuf, pMP3Stream->vb_ptr, pcm); sample += 64; pMP3Stream->vb_ptr = (pMP3Stream->vb_ptr - 8) & 127; pcm += 8; } }
void sbtB8_mono(float *sample, unsigned char *pcm, int n) { int i; for (i = 0; i < n; i++) { fdct8(sample, vbuf + vb_ptr); windowB8(vbuf, vb_ptr, pcm); sample += 64; vb_ptr = (vb_ptr - 8) & 127; pcm += 8; } }
void sbt8_mono_L3(float *sample, short *pcm, int ch) { int i; ch = 0; for (i = 0; i < 18; i++) { fdct8(sample, vbuf + vb_ptr); window8(vbuf, vb_ptr, pcm); sample += 32; vb_ptr = (vb_ptr - 8) & 127; pcm += 8; } }
/*------------------------------------------------------------*/ void sbtB8_mono(float *sample, unsigned char *pcm, int n, float vbuf[][512], int vb_ptr_arg[]) { int i; vb_ptr = vb_ptr_arg[0]; for(i=0;i<n;i++) { fdct8(sample, vbuf[0]+vb_ptr); windowB8(vbuf[0], vb_ptr, pcm); sample += 64; vb_ptr = (vb_ptr-8) & 127; pcm += 8; } vb_ptr_arg[0] = vb_ptr; }
void vp9_fdct8x8_quant_c(const int16_t *input, int stride, tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan) { int eob = -1; int i, j; tran_low_t intermediate[64]; (void)iscan; // Transform columns { tran_low_t *output = intermediate; tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 tran_high_t t0, t1, t2, t3; // needs32 tran_high_t x0, x1, x2, x3; // canbe16 int i; for (i = 0; i < 8; i++) { // stage 1 s0 = (input[0 * stride] + input[7 * stride]) * 4; s1 = (input[1 * stride] + input[6 * stride]) * 4; s2 = (input[2 * stride] + input[5 * stride]) * 4; s3 = (input[3 * stride] + input[4 * stride]) * 4; s4 = (input[3 * stride] - input[4 * stride]) * 4; s5 = (input[2 * stride] - input[5 * stride]) * 4; s6 = (input[1 * stride] - input[6 * stride]) * 4; s7 = (input[0 * stride] - input[7 * stride]) * 4; // fdct4(step, step); x0 = s0 + s3; x1 = s1 + s2; x2 = s1 - s2; x3 = s0 - s3; t0 = (x0 + x1) * cospi_16_64; t1 = (x0 - x1) * cospi_16_64; t2 = x2 * cospi_24_64 + x3 * cospi_8_64; t3 = -x2 * cospi_8_64 + x3 * cospi_24_64; output[0 * 8] = (tran_low_t)fdct_round_shift(t0); output[2 * 8] = (tran_low_t)fdct_round_shift(t2); output[4 * 8] = (tran_low_t)fdct_round_shift(t1); output[6 * 8] = (tran_low_t)fdct_round_shift(t3); // Stage 2 t0 = (s6 - s5) * cospi_16_64; t1 = (s6 + s5) * cospi_16_64; t2 = fdct_round_shift(t0); t3 = fdct_round_shift(t1); // Stage 3 x0 = s4 + t2; x1 = s4 - t2; x2 = s7 - t3; x3 = s7 + t3; // Stage 4 t0 = x0 * cospi_28_64 + x3 * cospi_4_64; t1 = x1 * cospi_12_64 + x2 * cospi_20_64; t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; output[1 * 8] = (tran_low_t)fdct_round_shift(t0); output[3 * 8] = (tran_low_t)fdct_round_shift(t2); output[5 * 8] = (tran_low_t)fdct_round_shift(t1); output[7 * 8] = (tran_low_t)fdct_round_shift(t3); input++; output++; } } // Rows for (i = 0; i < 8; ++i) { fdct8(&intermediate[i * 8], &coeff_ptr[i * 8]); for (j = 0; j < 8; ++j) coeff_ptr[j + i * 8] /= 2; } memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); if (!skip_block) { // Quantization pass: All coefficients with index >= zero_flag are // skippable. Note: zero_flag can be zero. for (i = 0; i < n_coeffs; i++) { const int rc = scan[i]; const int coeff = coeff_ptr[rc]; const int coeff_sign = (coeff >> 31); const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); tmp = (tmp * quant_ptr[rc != 0]) >> 16; qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; if (tmp) eob = i; } } *eob_ptr = eob + 1; }
static void fdct8x8(double *y, int ystride, const double *x, int xstride) { double t[8*8]; int i; for (i = 0; i < 8; i++) fdct8(t + 8*i, x + i, xstride); for (i = 0; i < 8; i++) fdct8(y + ystride*i, t + i, 8); }
void vp10_fdct8x8_quant_c(const int16_t *input, int stride, tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan #if CONFIG_AOM_QM , const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr #endif ) { int eob = -1; int i, j; tran_low_t intermediate[64]; // Transform columns { tran_low_t *output = intermediate; tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16 tran_high_t t0, t1, t2, t3; // needs32 tran_high_t x0, x1, x2, x3; // canbe16 int i; for (i = 0; i < 8; i++) { // stage 1 s0 = (input[0 * stride] + input[7 * stride]) * 4; s1 = (input[1 * stride] + input[6 * stride]) * 4; s2 = (input[2 * stride] + input[5 * stride]) * 4; s3 = (input[3 * stride] + input[4 * stride]) * 4; s4 = (input[3 * stride] - input[4 * stride]) * 4; s5 = (input[2 * stride] - input[5 * stride]) * 4; s6 = (input[1 * stride] - input[6 * stride]) * 4; s7 = (input[0 * stride] - input[7 * stride]) * 4; // fdct4(step, step); x0 = s0 + s3; x1 = s1 + s2; x2 = s1 - s2; x3 = s0 - s3; t0 = (x0 + x1) * cospi_16_64; t1 = (x0 - x1) * cospi_16_64; t2 = x2 * cospi_24_64 + x3 * cospi_8_64; t3 = -x2 * cospi_8_64 + x3 * cospi_24_64; output[0 * 8] = (tran_low_t)fdct_round_shift(t0); output[2 * 8] = (tran_low_t)fdct_round_shift(t2); output[4 * 8] = (tran_low_t)fdct_round_shift(t1); output[6 * 8] = (tran_low_t)fdct_round_shift(t3); // stage 2 t0 = (s6 - s5) * cospi_16_64; t1 = (s6 + s5) * cospi_16_64; t2 = fdct_round_shift(t0); t3 = fdct_round_shift(t1); // stage 3 x0 = s4 + t2; x1 = s4 - t2; x2 = s7 - t3; x3 = s7 + t3; // stage 4 t0 = x0 * cospi_28_64 + x3 * cospi_4_64; t1 = x1 * cospi_12_64 + x2 * cospi_20_64; t2 = x2 * cospi_12_64 + x1 * -cospi_20_64; t3 = x3 * cospi_28_64 + x0 * -cospi_4_64; output[1 * 8] = (tran_low_t)fdct_round_shift(t0); output[3 * 8] = (tran_low_t)fdct_round_shift(t2); output[5 * 8] = (tran_low_t)fdct_round_shift(t1); output[7 * 8] = (tran_low_t)fdct_round_shift(t3); input++; output++; } } // Rows for (i = 0; i < 8; ++i) { fdct8(&intermediate[i * 8], &coeff_ptr[i * 8]); for (j = 0; j < 8; ++j) coeff_ptr[j + i * 8] /= 2; } // TODO(jingning) Decide the need of these arguments after the // quantization process is completed. (void)zbin_ptr; (void)quant_shift_ptr; (void)iscan; memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr)); memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr)); if (!skip_block) { // Quantization pass: All coefficients with index >= zero_flag are // skippable. Note: zero_flag can be zero. for (i = 0; i < n_coeffs; i++) { const int rc = scan[i]; const int coeff = coeff_ptr[rc]; #if CONFIG_AOM_QM const qm_val_t wt = qm_ptr[rc]; const qm_val_t iwt = iqm_ptr[rc]; const int dequant = (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS; #endif const int coeff_sign = (coeff >> 31); const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; int64_t tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); int tmp32; #if CONFIG_AOM_QM tmp32 = (tmp * quant_ptr[rc != 0] * wt) >> (16 + AOM_QM_BITS); qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant; #else tmp32 = (tmp * quant_ptr[rc != 0]) >> 16; qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign; dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; #endif if (tmp32) eob = i; } } *eob_ptr = eob + 1; }