129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------ 229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo 329a84457aed4c45bc900998b5e11c03023264208James Dong * 429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License. 629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at 729a84457aed4c45bc900998b5e11c03023264208James Dong * 829a84457aed4c45bc900998b5e11c03023264208James Dong * http://www.apache.org/licenses/LICENSE-2.0 929a84457aed4c45bc900998b5e11c03023264208James Dong * 1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software 1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied. 1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions 1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License. 1629a84457aed4c45bc900998b5e11c03023264208James Dong * ------------------------------------------------------------------- 1729a84457aed4c45bc900998b5e11c03023264208James Dong */ 1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h" 1929a84457aed4c45bc900998b5e11c03023264208James Dong 2029a84457aed4c45bc900998b5e11c03023264208James Dong/* subtract with the prediction and do transformation */ 2129a84457aed4c45bc900998b5e11c03023264208James Dongvoid trans(uint8 *cur, int pitch, uint8 *predBlock, int16 *dataBlock) 2229a84457aed4c45bc900998b5e11c03023264208James Dong{ 2329a84457aed4c45bc900998b5e11c03023264208James Dong int16 *ptr = dataBlock; 2429a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, j; 2529a84457aed4c45bc900998b5e11c03023264208James Dong int curpitch = (uint)pitch >> 16; 2629a84457aed4c45bc900998b5e11c03023264208James Dong int predpitch = (pitch & 0xFFFF); 2729a84457aed4c45bc900998b5e11c03023264208James Dong 2829a84457aed4c45bc900998b5e11c03023264208James Dong /* horizontal */ 2929a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 3029a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 3129a84457aed4c45bc900998b5e11c03023264208James Dong { 3229a84457aed4c45bc900998b5e11c03023264208James Dong /* calculate the residue first */ 3329a84457aed4c45bc900998b5e11c03023264208James Dong r0 = cur[0] - predBlock[0]; 3429a84457aed4c45bc900998b5e11c03023264208James Dong r1 = cur[1] - predBlock[1]; 3529a84457aed4c45bc900998b5e11c03023264208James Dong r2 = cur[2] - predBlock[2]; 3629a84457aed4c45bc900998b5e11c03023264208James Dong r3 = cur[3] - predBlock[3]; 3729a84457aed4c45bc900998b5e11c03023264208James Dong 3829a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; //ptr[0] + ptr[3]; 3929a84457aed4c45bc900998b5e11c03023264208James Dong r3 = r0 - (r3 << 1); //ptr[0] - ptr[3]; 4029a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; //ptr[1] + ptr[2]; 4129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = r1 - (r2 << 1); //ptr[1] - ptr[2]; 4229a84457aed4c45bc900998b5e11c03023264208James Dong 4329a84457aed4c45bc900998b5e11c03023264208James Dong ptr[0] = r0 + r1; 4429a84457aed4c45bc900998b5e11c03023264208James Dong ptr[2] = r0 - r1; 4529a84457aed4c45bc900998b5e11c03023264208James Dong ptr[1] = (r3 << 1) + r2; 4629a84457aed4c45bc900998b5e11c03023264208James Dong ptr[3] = r3 - (r2 << 1); 4729a84457aed4c45bc900998b5e11c03023264208James Dong 4829a84457aed4c45bc900998b5e11c03023264208James Dong ptr += 16; 4929a84457aed4c45bc900998b5e11c03023264208James Dong predBlock += predpitch; 5029a84457aed4c45bc900998b5e11c03023264208James Dong cur += curpitch; 5129a84457aed4c45bc900998b5e11c03023264208James Dong j--; 5229a84457aed4c45bc900998b5e11c03023264208James Dong } 5329a84457aed4c45bc900998b5e11c03023264208James Dong /* vertical */ 5429a84457aed4c45bc900998b5e11c03023264208James Dong ptr = dataBlock; 5529a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 5629a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 5729a84457aed4c45bc900998b5e11c03023264208James Dong { 5829a84457aed4c45bc900998b5e11c03023264208James Dong r0 = ptr[0] + ptr[48]; 5929a84457aed4c45bc900998b5e11c03023264208James Dong r3 = ptr[0] - ptr[48]; 6029a84457aed4c45bc900998b5e11c03023264208James Dong r1 = ptr[16] + ptr[32]; 6129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = ptr[16] - ptr[32]; 6229a84457aed4c45bc900998b5e11c03023264208James Dong 6329a84457aed4c45bc900998b5e11c03023264208James Dong ptr[0] = r0 + r1; 6429a84457aed4c45bc900998b5e11c03023264208James Dong ptr[32] = r0 - r1; 6529a84457aed4c45bc900998b5e11c03023264208James Dong ptr[16] = (r3 << 1) + r2; 6629a84457aed4c45bc900998b5e11c03023264208James Dong ptr[48] = r3 - (r2 << 1); 6729a84457aed4c45bc900998b5e11c03023264208James Dong 6829a84457aed4c45bc900998b5e11c03023264208James Dong ptr++; 6929a84457aed4c45bc900998b5e11c03023264208James Dong j--; 7029a84457aed4c45bc900998b5e11c03023264208James Dong } 7129a84457aed4c45bc900998b5e11c03023264208James Dong 7229a84457aed4c45bc900998b5e11c03023264208James Dong return ; 7329a84457aed4c45bc900998b5e11c03023264208James Dong} 7429a84457aed4c45bc900998b5e11c03023264208James Dong 7529a84457aed4c45bc900998b5e11c03023264208James Dong 7629a84457aed4c45bc900998b5e11c03023264208James Dong/* do residue transform quant invquant, invtrans and write output out */ 7729a84457aed4c45bc900998b5e11c03023264208James Dongint dct_luma(AVCEncObject *encvid, int blkidx, uint8 *cur, uint8 *org, int *coef_cost) 7829a84457aed4c45bc900998b5e11c03023264208James Dong{ 7929a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 8029a84457aed4c45bc900998b5e11c03023264208James Dong int org_pitch = encvid->currInput->pitch; 8129a84457aed4c45bc900998b5e11c03023264208James Dong int pitch = video->currPic->pitch; 8229a84457aed4c45bc900998b5e11c03023264208James Dong int16 *coef = video->block; 8329a84457aed4c45bc900998b5e11c03023264208James Dong uint8 *pred = video->pred_block; // size 16 for a 4x4 block 8429a84457aed4c45bc900998b5e11c03023264208James Dong int pred_pitch = video->pred_pitch; 8529a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, j, k, idx; 8629a84457aed4c45bc900998b5e11c03023264208James Dong int *level, *run; 8729a84457aed4c45bc900998b5e11c03023264208James Dong int Qq, Rq, q_bits, qp_const, quant; 8829a84457aed4c45bc900998b5e11c03023264208James Dong int data, lev, zero_run; 8929a84457aed4c45bc900998b5e11c03023264208James Dong int numcoeff; 9029a84457aed4c45bc900998b5e11c03023264208James Dong 9129a84457aed4c45bc900998b5e11c03023264208James Dong coef += ((blkidx & 0x3) << 2) + ((blkidx >> 2) << 6); /* point to the 4x4 block */ 9229a84457aed4c45bc900998b5e11c03023264208James Dong 9329a84457aed4c45bc900998b5e11c03023264208James Dong /* first take a 4x4 transform */ 9429a84457aed4c45bc900998b5e11c03023264208James Dong /* horizontal */ 9529a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 9629a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 9729a84457aed4c45bc900998b5e11c03023264208James Dong { 9829a84457aed4c45bc900998b5e11c03023264208James Dong /* calculate the residue first */ 9929a84457aed4c45bc900998b5e11c03023264208James Dong r0 = org[0] - pred[0]; /* OPTIMIZEABLE */ 10029a84457aed4c45bc900998b5e11c03023264208James Dong r1 = org[1] - pred[1]; 10129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = org[2] - pred[2]; 10229a84457aed4c45bc900998b5e11c03023264208James Dong r3 = org[3] - pred[3]; 10329a84457aed4c45bc900998b5e11c03023264208James Dong 10429a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; //ptr[0] + ptr[3]; 10529a84457aed4c45bc900998b5e11c03023264208James Dong r3 = r0 - (r3 << 1); //ptr[0] - ptr[3]; 10629a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; //ptr[1] + ptr[2]; 10729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = r1 - (r2 << 1); //ptr[1] - ptr[2]; 10829a84457aed4c45bc900998b5e11c03023264208James Dong 10929a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1; 11029a84457aed4c45bc900998b5e11c03023264208James Dong coef[2] = r0 - r1; 11129a84457aed4c45bc900998b5e11c03023264208James Dong coef[1] = (r3 << 1) + r2; 11229a84457aed4c45bc900998b5e11c03023264208James Dong coef[3] = r3 - (r2 << 1); 11329a84457aed4c45bc900998b5e11c03023264208James Dong 11429a84457aed4c45bc900998b5e11c03023264208James Dong coef += 16; 11529a84457aed4c45bc900998b5e11c03023264208James Dong org += org_pitch; 11629a84457aed4c45bc900998b5e11c03023264208James Dong pred += pred_pitch; 11729a84457aed4c45bc900998b5e11c03023264208James Dong j--; 11829a84457aed4c45bc900998b5e11c03023264208James Dong } 11929a84457aed4c45bc900998b5e11c03023264208James Dong /* vertical */ 12029a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 64; 12129a84457aed4c45bc900998b5e11c03023264208James Dong pred -= (pred_pitch << 2); 12229a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 12329a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) /* OPTIMIZABLE */ 12429a84457aed4c45bc900998b5e11c03023264208James Dong { 12529a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[48]; 12629a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[0] - coef[48]; 12729a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[16] + coef[32]; 12829a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[16] - coef[32]; 12929a84457aed4c45bc900998b5e11c03023264208James Dong 13029a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1; 13129a84457aed4c45bc900998b5e11c03023264208James Dong coef[32] = r0 - r1; 13229a84457aed4c45bc900998b5e11c03023264208James Dong coef[16] = (r3 << 1) + r2; 13329a84457aed4c45bc900998b5e11c03023264208James Dong coef[48] = r3 - (r2 << 1); 13429a84457aed4c45bc900998b5e11c03023264208James Dong 13529a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 13629a84457aed4c45bc900998b5e11c03023264208James Dong j--; 13729a84457aed4c45bc900998b5e11c03023264208James Dong } 13829a84457aed4c45bc900998b5e11c03023264208James Dong 13929a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 4; 14029a84457aed4c45bc900998b5e11c03023264208James Dong 14129a84457aed4c45bc900998b5e11c03023264208James Dong /* quant */ 14229a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[ras2dec[blkidx]]; 14329a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[ras2dec[blkidx]]; 14429a84457aed4c45bc900998b5e11c03023264208James Dong 14529a84457aed4c45bc900998b5e11c03023264208James Dong Rq = video->QPy_mod_6; 14629a84457aed4c45bc900998b5e11c03023264208James Dong Qq = video->QPy_div_6; 14729a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = encvid->qp_const; 14829a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 15 + Qq; 14929a84457aed4c45bc900998b5e11c03023264208James Dong 15029a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 15129a84457aed4c45bc900998b5e11c03023264208James Dong numcoeff = 0; 15229a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 0; k < 16; k++) 15329a84457aed4c45bc900998b5e11c03023264208James Dong { 15429a84457aed4c45bc900998b5e11c03023264208James Dong idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */ 15529a84457aed4c45bc900998b5e11c03023264208James Dong data = coef[idx]; 15629a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][k]; 15729a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 15829a84457aed4c45bc900998b5e11c03023264208James Dong { 15929a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + qp_const; 16029a84457aed4c45bc900998b5e11c03023264208James Dong } 16129a84457aed4c45bc900998b5e11c03023264208James Dong else 16229a84457aed4c45bc900998b5e11c03023264208James Dong { 16329a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + qp_const; 16429a84457aed4c45bc900998b5e11c03023264208James Dong } 16529a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= q_bits; 16629a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 16729a84457aed4c45bc900998b5e11c03023264208James Dong { 16829a84457aed4c45bc900998b5e11c03023264208James Dong *coef_cost += ((lev > 1) ? MAX_VALUE : COEFF_COST[DISABLE_THRESHOLDING][zero_run]); 16929a84457aed4c45bc900998b5e11c03023264208James Dong 17029a84457aed4c45bc900998b5e11c03023264208James Dong /* dequant */ 17129a84457aed4c45bc900998b5e11c03023264208James Dong quant = dequant_coefres[Rq][k]; 17229a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 17329a84457aed4c45bc900998b5e11c03023264208James Dong { 17429a84457aed4c45bc900998b5e11c03023264208James Dong level[numcoeff] = lev; 17529a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (lev * quant) << Qq; 17629a84457aed4c45bc900998b5e11c03023264208James Dong } 17729a84457aed4c45bc900998b5e11c03023264208James Dong else 17829a84457aed4c45bc900998b5e11c03023264208James Dong { 17929a84457aed4c45bc900998b5e11c03023264208James Dong level[numcoeff] = -lev; 18029a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (-lev * quant) << Qq; 18129a84457aed4c45bc900998b5e11c03023264208James Dong } 18229a84457aed4c45bc900998b5e11c03023264208James Dong run[numcoeff++] = zero_run; 18329a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 18429a84457aed4c45bc900998b5e11c03023264208James Dong } 18529a84457aed4c45bc900998b5e11c03023264208James Dong else 18629a84457aed4c45bc900998b5e11c03023264208James Dong { 18729a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 18829a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = 0; 18929a84457aed4c45bc900998b5e11c03023264208James Dong } 19029a84457aed4c45bc900998b5e11c03023264208James Dong } 19129a84457aed4c45bc900998b5e11c03023264208James Dong 19229a84457aed4c45bc900998b5e11c03023264208James Dong if (video->currMB->mb_intra) // only do inverse transform with intra block 19329a84457aed4c45bc900998b5e11c03023264208James Dong { 19429a84457aed4c45bc900998b5e11c03023264208James Dong if (numcoeff) /* then do inverse transform */ 19529a84457aed4c45bc900998b5e11c03023264208James Dong { 19629a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) /* horizontal */ 19729a84457aed4c45bc900998b5e11c03023264208James Dong { 19829a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[2]; 19929a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[2]; 20029a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[1] >> 1) - coef[3]; 20129a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[1] + (coef[3] >> 1); 20229a84457aed4c45bc900998b5e11c03023264208James Dong 20329a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r3; 20429a84457aed4c45bc900998b5e11c03023264208James Dong coef[1] = r1 + r2; 20529a84457aed4c45bc900998b5e11c03023264208James Dong coef[2] = r1 - r2; 20629a84457aed4c45bc900998b5e11c03023264208James Dong coef[3] = r0 - r3; 20729a84457aed4c45bc900998b5e11c03023264208James Dong 20829a84457aed4c45bc900998b5e11c03023264208James Dong coef += 16; 20929a84457aed4c45bc900998b5e11c03023264208James Dong } 21029a84457aed4c45bc900998b5e11c03023264208James Dong 21129a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 64; 21229a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) /* vertical, has to be done after horizontal */ 21329a84457aed4c45bc900998b5e11c03023264208James Dong { 21429a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[32]; 21529a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[32]; 21629a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[16] >> 1) - coef[48]; 21729a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[16] + (coef[48] >> 1); 21829a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; 21929a84457aed4c45bc900998b5e11c03023264208James Dong r3 = (r0 - (r3 << 1)); /* r0-r3 */ 22029a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; 22129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (r1 - (r2 << 1)); /* r1-r2 */ 22229a84457aed4c45bc900998b5e11c03023264208James Dong r0 += 32; 22329a84457aed4c45bc900998b5e11c03023264208James Dong r1 += 32; 22429a84457aed4c45bc900998b5e11c03023264208James Dong r2 += 32; 22529a84457aed4c45bc900998b5e11c03023264208James Dong r3 += 32; 22629a84457aed4c45bc900998b5e11c03023264208James Dong 22729a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (r0 >> 6); 22829a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 22929a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *(pred += pred_pitch) + (r1 >> 6); 23029a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 23129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = *(pred += pred_pitch) + (r2 >> 6); 23229a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 23329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[pred_pitch] + (r3 >> 6); 23429a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 23529a84457aed4c45bc900998b5e11c03023264208James Dong 23629a84457aed4c45bc900998b5e11c03023264208James Dong *cur = r0; 23729a84457aed4c45bc900998b5e11c03023264208James Dong *(cur += pitch) = r1; 23829a84457aed4c45bc900998b5e11c03023264208James Dong *(cur += pitch) = r2; 23929a84457aed4c45bc900998b5e11c03023264208James Dong cur[pitch] = r3; 24029a84457aed4c45bc900998b5e11c03023264208James Dong cur -= (pitch << 1); 24129a84457aed4c45bc900998b5e11c03023264208James Dong cur++; 24229a84457aed4c45bc900998b5e11c03023264208James Dong pred -= (pred_pitch << 1); 24329a84457aed4c45bc900998b5e11c03023264208James Dong pred++; 24429a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 24529a84457aed4c45bc900998b5e11c03023264208James Dong } 24629a84457aed4c45bc900998b5e11c03023264208James Dong } 24729a84457aed4c45bc900998b5e11c03023264208James Dong else // copy from pred to cur 24829a84457aed4c45bc900998b5e11c03023264208James Dong { 24929a84457aed4c45bc900998b5e11c03023264208James Dong *((uint32*)cur) = *((uint32*)pred); 25029a84457aed4c45bc900998b5e11c03023264208James Dong *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch)); 25129a84457aed4c45bc900998b5e11c03023264208James Dong *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch)); 25229a84457aed4c45bc900998b5e11c03023264208James Dong *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch)); 25329a84457aed4c45bc900998b5e11c03023264208James Dong } 25429a84457aed4c45bc900998b5e11c03023264208James Dong } 25529a84457aed4c45bc900998b5e11c03023264208James Dong 25629a84457aed4c45bc900998b5e11c03023264208James Dong return numcoeff; 25729a84457aed4c45bc900998b5e11c03023264208James Dong} 25829a84457aed4c45bc900998b5e11c03023264208James Dong 25929a84457aed4c45bc900998b5e11c03023264208James Dong 26029a84457aed4c45bc900998b5e11c03023264208James Dongvoid MBInterIdct(AVCCommonObj *video, uint8 *curL, AVCMacroblock *currMB, int picPitch) 26129a84457aed4c45bc900998b5e11c03023264208James Dong{ 26229a84457aed4c45bc900998b5e11c03023264208James Dong int16 *coef, *coef8 = video->block; 26329a84457aed4c45bc900998b5e11c03023264208James Dong uint8 *cur; // the same as curL 26429a84457aed4c45bc900998b5e11c03023264208James Dong int b8, b4; 26529a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, j, blkidx; 26629a84457aed4c45bc900998b5e11c03023264208James Dong 26729a84457aed4c45bc900998b5e11c03023264208James Dong for (b8 = 0; b8 < 4; b8++) 26829a84457aed4c45bc900998b5e11c03023264208James Dong { 26929a84457aed4c45bc900998b5e11c03023264208James Dong cur = curL; 27029a84457aed4c45bc900998b5e11c03023264208James Dong coef = coef8; 27129a84457aed4c45bc900998b5e11c03023264208James Dong 27229a84457aed4c45bc900998b5e11c03023264208James Dong if (currMB->CBP&(1 << b8)) 27329a84457aed4c45bc900998b5e11c03023264208James Dong { 27429a84457aed4c45bc900998b5e11c03023264208James Dong for (b4 = 0; b4 < 4; b4++) 27529a84457aed4c45bc900998b5e11c03023264208James Dong { 27629a84457aed4c45bc900998b5e11c03023264208James Dong blkidx = blkIdx2blkXY[b8][b4]; 27729a84457aed4c45bc900998b5e11c03023264208James Dong /* do IDCT */ 27829a84457aed4c45bc900998b5e11c03023264208James Dong if (currMB->nz_coeff[blkidx]) 27929a84457aed4c45bc900998b5e11c03023264208James Dong { 28029a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) /* horizontal */ 28129a84457aed4c45bc900998b5e11c03023264208James Dong { 28229a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[2]; 28329a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[2]; 28429a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[1] >> 1) - coef[3]; 28529a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[1] + (coef[3] >> 1); 28629a84457aed4c45bc900998b5e11c03023264208James Dong 28729a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r3; 28829a84457aed4c45bc900998b5e11c03023264208James Dong coef[1] = r1 + r2; 28929a84457aed4c45bc900998b5e11c03023264208James Dong coef[2] = r1 - r2; 29029a84457aed4c45bc900998b5e11c03023264208James Dong coef[3] = r0 - r3; 29129a84457aed4c45bc900998b5e11c03023264208James Dong 29229a84457aed4c45bc900998b5e11c03023264208James Dong coef += 16; 29329a84457aed4c45bc900998b5e11c03023264208James Dong } 29429a84457aed4c45bc900998b5e11c03023264208James Dong 29529a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 64; 29629a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) /* vertical, has to be done after horizontal */ 29729a84457aed4c45bc900998b5e11c03023264208James Dong { 29829a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[32]; 29929a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[32]; 30029a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[16] >> 1) - coef[48]; 30129a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[16] + (coef[48] >> 1); 30229a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; 30329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = (r0 - (r3 << 1)); /* r0-r3 */ 30429a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; 30529a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (r1 - (r2 << 1)); /* r1-r2 */ 30629a84457aed4c45bc900998b5e11c03023264208James Dong r0 += 32; 30729a84457aed4c45bc900998b5e11c03023264208James Dong r1 += 32; 30829a84457aed4c45bc900998b5e11c03023264208James Dong r2 += 32; 30929a84457aed4c45bc900998b5e11c03023264208James Dong r3 += 32; 31029a84457aed4c45bc900998b5e11c03023264208James Dong 31129a84457aed4c45bc900998b5e11c03023264208James Dong r0 = cur[0] + (r0 >> 6); 31229a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 31329a84457aed4c45bc900998b5e11c03023264208James Dong *cur = r0; 31429a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *(cur += picPitch) + (r1 >> 6); 31529a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 31629a84457aed4c45bc900998b5e11c03023264208James Dong *cur = r1; 31729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = *(cur += picPitch) + (r2 >> 6); 31829a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 31929a84457aed4c45bc900998b5e11c03023264208James Dong *cur = r2; 32029a84457aed4c45bc900998b5e11c03023264208James Dong r3 = cur[picPitch] + (r3 >> 6); 32129a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 32229a84457aed4c45bc900998b5e11c03023264208James Dong cur[picPitch] = r3; 32329a84457aed4c45bc900998b5e11c03023264208James Dong 32429a84457aed4c45bc900998b5e11c03023264208James Dong cur -= (picPitch << 1); 32529a84457aed4c45bc900998b5e11c03023264208James Dong cur++; 32629a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 32729a84457aed4c45bc900998b5e11c03023264208James Dong } 32829a84457aed4c45bc900998b5e11c03023264208James Dong cur -= 4; 32929a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 4; 33029a84457aed4c45bc900998b5e11c03023264208James Dong } 33129a84457aed4c45bc900998b5e11c03023264208James Dong if (b4&1) 33229a84457aed4c45bc900998b5e11c03023264208James Dong { 33329a84457aed4c45bc900998b5e11c03023264208James Dong cur += ((picPitch << 2) - 4); 33429a84457aed4c45bc900998b5e11c03023264208James Dong coef += 60; 33529a84457aed4c45bc900998b5e11c03023264208James Dong } 33629a84457aed4c45bc900998b5e11c03023264208James Dong else 33729a84457aed4c45bc900998b5e11c03023264208James Dong { 33829a84457aed4c45bc900998b5e11c03023264208James Dong cur += 4; 33929a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 34029a84457aed4c45bc900998b5e11c03023264208James Dong } 34129a84457aed4c45bc900998b5e11c03023264208James Dong } 34229a84457aed4c45bc900998b5e11c03023264208James Dong } 34329a84457aed4c45bc900998b5e11c03023264208James Dong 34429a84457aed4c45bc900998b5e11c03023264208James Dong if (b8&1) 34529a84457aed4c45bc900998b5e11c03023264208James Dong { 34629a84457aed4c45bc900998b5e11c03023264208James Dong curL += ((picPitch << 3) - 8); 34729a84457aed4c45bc900998b5e11c03023264208James Dong coef8 += 120; 34829a84457aed4c45bc900998b5e11c03023264208James Dong } 34929a84457aed4c45bc900998b5e11c03023264208James Dong else 35029a84457aed4c45bc900998b5e11c03023264208James Dong { 35129a84457aed4c45bc900998b5e11c03023264208James Dong curL += 8; 35229a84457aed4c45bc900998b5e11c03023264208James Dong coef8 += 8; 35329a84457aed4c45bc900998b5e11c03023264208James Dong } 35429a84457aed4c45bc900998b5e11c03023264208James Dong } 35529a84457aed4c45bc900998b5e11c03023264208James Dong 35629a84457aed4c45bc900998b5e11c03023264208James Dong return ; 35729a84457aed4c45bc900998b5e11c03023264208James Dong} 35829a84457aed4c45bc900998b5e11c03023264208James Dong 35929a84457aed4c45bc900998b5e11c03023264208James Dong/* performa dct, quant, iquant, idct for the entire MB */ 36029a84457aed4c45bc900998b5e11c03023264208James Dongvoid dct_luma_16x16(AVCEncObject *encvid, uint8 *curL, uint8 *orgL) 36129a84457aed4c45bc900998b5e11c03023264208James Dong{ 36229a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 36329a84457aed4c45bc900998b5e11c03023264208James Dong int pitch = video->currPic->pitch; 36429a84457aed4c45bc900998b5e11c03023264208James Dong int org_pitch = encvid->currInput->pitch; 36529a84457aed4c45bc900998b5e11c03023264208James Dong AVCMacroblock *currMB = video->currMB; 36629a84457aed4c45bc900998b5e11c03023264208James Dong int16 *coef = video->block; 36729a84457aed4c45bc900998b5e11c03023264208James Dong uint8 *pred = encvid->pred_i16[currMB->i16Mode]; 36829a84457aed4c45bc900998b5e11c03023264208James Dong int blk_x, blk_y, j, k, idx, b8, b4; 36929a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, m0, m1, m2 , m3; 37029a84457aed4c45bc900998b5e11c03023264208James Dong int data, lev; 37129a84457aed4c45bc900998b5e11c03023264208James Dong int *level, *run, zero_run, ncoeff; 37229a84457aed4c45bc900998b5e11c03023264208James Dong int Rq, Qq, quant, q_bits, qp_const; 37329a84457aed4c45bc900998b5e11c03023264208James Dong int offset_cur[4], offset_pred[4], offset; 37429a84457aed4c45bc900998b5e11c03023264208James Dong 37529a84457aed4c45bc900998b5e11c03023264208James Dong /* horizontal */ 37629a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 16; j > 0; j--) 37729a84457aed4c45bc900998b5e11c03023264208James Dong { 37829a84457aed4c45bc900998b5e11c03023264208James Dong for (blk_x = 4; blk_x > 0; blk_x--) 37929a84457aed4c45bc900998b5e11c03023264208James Dong { 38029a84457aed4c45bc900998b5e11c03023264208James Dong /* calculate the residue first */ 38129a84457aed4c45bc900998b5e11c03023264208James Dong r0 = *orgL++ - *pred++; 38229a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *orgL++ - *pred++; 38329a84457aed4c45bc900998b5e11c03023264208James Dong r2 = *orgL++ - *pred++; 38429a84457aed4c45bc900998b5e11c03023264208James Dong r3 = *orgL++ - *pred++; 38529a84457aed4c45bc900998b5e11c03023264208James Dong 38629a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; //ptr[0] + ptr[3]; 38729a84457aed4c45bc900998b5e11c03023264208James Dong r3 = r0 - (r3 << 1); //ptr[0] - ptr[3]; 38829a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; //ptr[1] + ptr[2]; 38929a84457aed4c45bc900998b5e11c03023264208James Dong r2 = r1 - (r2 << 1); //ptr[1] - ptr[2]; 39029a84457aed4c45bc900998b5e11c03023264208James Dong 39129a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r0 + r1; 39229a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = (r3 << 1) + r2; 39329a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r0 - r1; 39429a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r3 - (r2 << 1); 39529a84457aed4c45bc900998b5e11c03023264208James Dong } 39629a84457aed4c45bc900998b5e11c03023264208James Dong orgL += (org_pitch - 16); 39729a84457aed4c45bc900998b5e11c03023264208James Dong } 39829a84457aed4c45bc900998b5e11c03023264208James Dong pred -= 256; 39929a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 256; 40029a84457aed4c45bc900998b5e11c03023264208James Dong /* vertical */ 40129a84457aed4c45bc900998b5e11c03023264208James Dong for (blk_y = 4; blk_y > 0; blk_y--) 40229a84457aed4c45bc900998b5e11c03023264208James Dong { 40329a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 16; j > 0; j--) 40429a84457aed4c45bc900998b5e11c03023264208James Dong { 40529a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[48]; 40629a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[0] - coef[48]; 40729a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[16] + coef[32]; 40829a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[16] - coef[32]; 40929a84457aed4c45bc900998b5e11c03023264208James Dong 41029a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1; 41129a84457aed4c45bc900998b5e11c03023264208James Dong coef[32] = r0 - r1; 41229a84457aed4c45bc900998b5e11c03023264208James Dong coef[16] = (r3 << 1) + r2; 41329a84457aed4c45bc900998b5e11c03023264208James Dong coef[48] = r3 - (r2 << 1); 41429a84457aed4c45bc900998b5e11c03023264208James Dong 41529a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 41629a84457aed4c45bc900998b5e11c03023264208James Dong } 41729a84457aed4c45bc900998b5e11c03023264208James Dong coef += 48; 41829a84457aed4c45bc900998b5e11c03023264208James Dong } 41929a84457aed4c45bc900998b5e11c03023264208James Dong 42029a84457aed4c45bc900998b5e11c03023264208James Dong /* then perform DC transform */ 42129a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 256; 42229a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 42329a84457aed4c45bc900998b5e11c03023264208James Dong { 42429a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[12]; 42529a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[0] - coef[12]; 42629a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[4] + coef[8]; 42729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[4] - coef[8]; 42829a84457aed4c45bc900998b5e11c03023264208James Dong 42929a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1; 43029a84457aed4c45bc900998b5e11c03023264208James Dong coef[8] = r0 - r1; 43129a84457aed4c45bc900998b5e11c03023264208James Dong coef[4] = r3 + r2; 43229a84457aed4c45bc900998b5e11c03023264208James Dong coef[12] = r3 - r2; 43329a84457aed4c45bc900998b5e11c03023264208James Dong coef += 64; 43429a84457aed4c45bc900998b5e11c03023264208James Dong } 43529a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 256; 43629a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 43729a84457aed4c45bc900998b5e11c03023264208James Dong { 43829a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[192]; 43929a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[0] - coef[192]; 44029a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[64] + coef[128]; 44129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[64] - coef[128]; 44229a84457aed4c45bc900998b5e11c03023264208James Dong 44329a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = (r0 + r1) >> 1; 44429a84457aed4c45bc900998b5e11c03023264208James Dong coef[128] = (r0 - r1) >> 1; 44529a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = (r3 + r2) >> 1; 44629a84457aed4c45bc900998b5e11c03023264208James Dong coef[192] = (r3 - r2) >> 1; 44729a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 44829a84457aed4c45bc900998b5e11c03023264208James Dong } 44929a84457aed4c45bc900998b5e11c03023264208James Dong 45029a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 16; 45129a84457aed4c45bc900998b5e11c03023264208James Dong // then quantize DC 45229a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->leveldc; 45329a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->rundc; 45429a84457aed4c45bc900998b5e11c03023264208James Dong 45529a84457aed4c45bc900998b5e11c03023264208James Dong Rq = video->QPy_mod_6; 45629a84457aed4c45bc900998b5e11c03023264208James Dong Qq = video->QPy_div_6; 45729a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][0]; 45829a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 15 + Qq; 45929a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = encvid->qp_const; 46029a84457aed4c45bc900998b5e11c03023264208James Dong 46129a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 46229a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 46329a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 0; k < 16; k++) /* in zigzag scan order */ 46429a84457aed4c45bc900998b5e11c03023264208James Dong { 46529a84457aed4c45bc900998b5e11c03023264208James Dong idx = ZIGZAG2RASTERDC[k]; 46629a84457aed4c45bc900998b5e11c03023264208James Dong data = coef[idx]; 46729a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) // quant 46829a84457aed4c45bc900998b5e11c03023264208James Dong { 46929a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + (qp_const << 1); 47029a84457aed4c45bc900998b5e11c03023264208James Dong } 47129a84457aed4c45bc900998b5e11c03023264208James Dong else 47229a84457aed4c45bc900998b5e11c03023264208James Dong { 47329a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + (qp_const << 1); 47429a84457aed4c45bc900998b5e11c03023264208James Dong } 47529a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= (q_bits + 1); 47629a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) // dequant 47729a84457aed4c45bc900998b5e11c03023264208James Dong { 47829a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 47929a84457aed4c45bc900998b5e11c03023264208James Dong { 48029a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 48129a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = lev; 48229a84457aed4c45bc900998b5e11c03023264208James Dong } 48329a84457aed4c45bc900998b5e11c03023264208James Dong else 48429a84457aed4c45bc900998b5e11c03023264208James Dong { 48529a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 48629a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = -lev; 48729a84457aed4c45bc900998b5e11c03023264208James Dong } 48829a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 48929a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 49029a84457aed4c45bc900998b5e11c03023264208James Dong } 49129a84457aed4c45bc900998b5e11c03023264208James Dong else 49229a84457aed4c45bc900998b5e11c03023264208James Dong { 49329a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 49429a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = 0; 49529a84457aed4c45bc900998b5e11c03023264208James Dong } 49629a84457aed4c45bc900998b5e11c03023264208James Dong } 49729a84457aed4c45bc900998b5e11c03023264208James Dong 49829a84457aed4c45bc900998b5e11c03023264208James Dong /* inverse transform DC */ 49929a84457aed4c45bc900998b5e11c03023264208James Dong encvid->numcoefdc = ncoeff; 50029a84457aed4c45bc900998b5e11c03023264208James Dong if (ncoeff) 50129a84457aed4c45bc900998b5e11c03023264208James Dong { 50229a84457aed4c45bc900998b5e11c03023264208James Dong quant = dequant_coefres[Rq][0]; 50329a84457aed4c45bc900998b5e11c03023264208James Dong 50429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 0; j < 4; j++) 50529a84457aed4c45bc900998b5e11c03023264208James Dong { 50629a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + coef[4]; 50729a84457aed4c45bc900998b5e11c03023264208James Dong m1 = coef[0] - coef[4]; 50829a84457aed4c45bc900998b5e11c03023264208James Dong m2 = coef[8] + coef[12]; 50929a84457aed4c45bc900998b5e11c03023264208James Dong m3 = coef[8] - coef[12]; 51029a84457aed4c45bc900998b5e11c03023264208James Dong 51129a84457aed4c45bc900998b5e11c03023264208James Dong 51229a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = m0 + m2; 51329a84457aed4c45bc900998b5e11c03023264208James Dong coef[4] = m0 - m2; 51429a84457aed4c45bc900998b5e11c03023264208James Dong coef[8] = m1 - m3; 51529a84457aed4c45bc900998b5e11c03023264208James Dong coef[12] = m1 + m3; 51629a84457aed4c45bc900998b5e11c03023264208James Dong coef += 64; 51729a84457aed4c45bc900998b5e11c03023264208James Dong } 51829a84457aed4c45bc900998b5e11c03023264208James Dong 51929a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 256; 52029a84457aed4c45bc900998b5e11c03023264208James Dong 52129a84457aed4c45bc900998b5e11c03023264208James Dong if (Qq >= 2) /* this way should be faster than JM */ 52229a84457aed4c45bc900998b5e11c03023264208James Dong { /* they use (((m4*scale)<<(QPy/6))+2)>>2 for both cases. */ 52329a84457aed4c45bc900998b5e11c03023264208James Dong Qq -= 2; 52429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 0; j < 4; j++) 52529a84457aed4c45bc900998b5e11c03023264208James Dong { 52629a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + coef[64]; 52729a84457aed4c45bc900998b5e11c03023264208James Dong m1 = coef[0] - coef[64]; 52829a84457aed4c45bc900998b5e11c03023264208James Dong m2 = coef[128] + coef[192]; 52929a84457aed4c45bc900998b5e11c03023264208James Dong m3 = coef[128] - coef[192]; 53029a84457aed4c45bc900998b5e11c03023264208James Dong 53129a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = ((m0 + m2) * quant) << Qq; 53229a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = ((m0 - m2) * quant) << Qq; 53329a84457aed4c45bc900998b5e11c03023264208James Dong coef[128] = ((m1 - m3) * quant) << Qq; 53429a84457aed4c45bc900998b5e11c03023264208James Dong coef[192] = ((m1 + m3) * quant) << Qq; 53529a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 53629a84457aed4c45bc900998b5e11c03023264208James Dong } 53729a84457aed4c45bc900998b5e11c03023264208James Dong Qq += 2; /* restore the value */ 53829a84457aed4c45bc900998b5e11c03023264208James Dong } 53929a84457aed4c45bc900998b5e11c03023264208James Dong else 54029a84457aed4c45bc900998b5e11c03023264208James Dong { 54129a84457aed4c45bc900998b5e11c03023264208James Dong Qq = 2 - Qq; 54229a84457aed4c45bc900998b5e11c03023264208James Dong offset = 1 << (Qq - 1); 54329a84457aed4c45bc900998b5e11c03023264208James Dong 54429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 0; j < 4; j++) 54529a84457aed4c45bc900998b5e11c03023264208James Dong { 54629a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + coef[64]; 54729a84457aed4c45bc900998b5e11c03023264208James Dong m1 = coef[0] - coef[64]; 54829a84457aed4c45bc900998b5e11c03023264208James Dong m2 = coef[128] + coef[192]; 54929a84457aed4c45bc900998b5e11c03023264208James Dong m3 = coef[128] - coef[192]; 55029a84457aed4c45bc900998b5e11c03023264208James Dong 55129a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = (((m0 + m2) * quant + offset) >> Qq); 55229a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = (((m0 - m2) * quant + offset) >> Qq); 55329a84457aed4c45bc900998b5e11c03023264208James Dong coef[128] = (((m1 - m3) * quant + offset) >> Qq); 55429a84457aed4c45bc900998b5e11c03023264208James Dong coef[192] = (((m1 + m3) * quant + offset) >> Qq); 55529a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 55629a84457aed4c45bc900998b5e11c03023264208James Dong } 55729a84457aed4c45bc900998b5e11c03023264208James Dong Qq = 2 - Qq; /* restore the value */ 55829a84457aed4c45bc900998b5e11c03023264208James Dong } 55929a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 16; /* back to the origin */ 56029a84457aed4c45bc900998b5e11c03023264208James Dong } 56129a84457aed4c45bc900998b5e11c03023264208James Dong 56229a84457aed4c45bc900998b5e11c03023264208James Dong /* now zigzag scan ac coefs, quant, iquant and itrans */ 56329a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[0]; 56429a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[0]; 56529a84457aed4c45bc900998b5e11c03023264208James Dong 56629a84457aed4c45bc900998b5e11c03023264208James Dong /* offset btw 4x4 block */ 56729a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[0] = 0; 56829a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[1] = (pitch << 2) - 8; 56929a84457aed4c45bc900998b5e11c03023264208James Dong 57029a84457aed4c45bc900998b5e11c03023264208James Dong /* offset btw 8x8 block */ 57129a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[2] = 8 - (pitch << 3); 57229a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[3] = -8; 57329a84457aed4c45bc900998b5e11c03023264208James Dong 57429a84457aed4c45bc900998b5e11c03023264208James Dong /* similarly for pred */ 57529a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[0] = 0; 57629a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[1] = 56; 57729a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[2] = -120; 57829a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[3] = -8; 57929a84457aed4c45bc900998b5e11c03023264208James Dong 58029a84457aed4c45bc900998b5e11c03023264208James Dong currMB->CBP = 0; 58129a84457aed4c45bc900998b5e11c03023264208James Dong 58229a84457aed4c45bc900998b5e11c03023264208James Dong for (b8 = 0; b8 < 4; b8++) 58329a84457aed4c45bc900998b5e11c03023264208James Dong { 58429a84457aed4c45bc900998b5e11c03023264208James Dong for (b4 = 0; b4 < 4; b4++) 58529a84457aed4c45bc900998b5e11c03023264208James Dong { 58629a84457aed4c45bc900998b5e11c03023264208James Dong 58729a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 58829a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 58929a84457aed4c45bc900998b5e11c03023264208James Dong 59029a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 1; k < 16; k++) 59129a84457aed4c45bc900998b5e11c03023264208James Dong { 59229a84457aed4c45bc900998b5e11c03023264208James Dong idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */ 59329a84457aed4c45bc900998b5e11c03023264208James Dong data = coef[idx]; 59429a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][k]; 59529a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 59629a84457aed4c45bc900998b5e11c03023264208James Dong { 59729a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + qp_const; 59829a84457aed4c45bc900998b5e11c03023264208James Dong } 59929a84457aed4c45bc900998b5e11c03023264208James Dong else 60029a84457aed4c45bc900998b5e11c03023264208James Dong { 60129a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + qp_const; 60229a84457aed4c45bc900998b5e11c03023264208James Dong } 60329a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= q_bits; 60429a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 60529a84457aed4c45bc900998b5e11c03023264208James Dong { /* dequant */ 60629a84457aed4c45bc900998b5e11c03023264208James Dong quant = dequant_coefres[Rq][k]; 60729a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 60829a84457aed4c45bc900998b5e11c03023264208James Dong { 60929a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 61029a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (lev * quant) << Qq; 61129a84457aed4c45bc900998b5e11c03023264208James Dong } 61229a84457aed4c45bc900998b5e11c03023264208James Dong else 61329a84457aed4c45bc900998b5e11c03023264208James Dong { 61429a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 61529a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (-lev * quant) << Qq; 61629a84457aed4c45bc900998b5e11c03023264208James Dong } 61729a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 61829a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 61929a84457aed4c45bc900998b5e11c03023264208James Dong } 62029a84457aed4c45bc900998b5e11c03023264208James Dong else 62129a84457aed4c45bc900998b5e11c03023264208James Dong { 62229a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 62329a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = 0; 62429a84457aed4c45bc900998b5e11c03023264208James Dong } 62529a84457aed4c45bc900998b5e11c03023264208James Dong } 62629a84457aed4c45bc900998b5e11c03023264208James Dong 62729a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[blkIdx2blkXY[b8][b4]] = ncoeff; /* in raster scan !!! */ 62829a84457aed4c45bc900998b5e11c03023264208James Dong if (ncoeff) 62929a84457aed4c45bc900998b5e11c03023264208James Dong { 63029a84457aed4c45bc900998b5e11c03023264208James Dong currMB->CBP |= (1 << b8); 63129a84457aed4c45bc900998b5e11c03023264208James Dong 63229a84457aed4c45bc900998b5e11c03023264208James Dong // do inverse transform here 63329a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 63429a84457aed4c45bc900998b5e11c03023264208James Dong { 63529a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[2]; 63629a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[2]; 63729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[1] >> 1) - coef[3]; 63829a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[1] + (coef[3] >> 1); 63929a84457aed4c45bc900998b5e11c03023264208James Dong 64029a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r3; 64129a84457aed4c45bc900998b5e11c03023264208James Dong coef[1] = r1 + r2; 64229a84457aed4c45bc900998b5e11c03023264208James Dong coef[2] = r1 - r2; 64329a84457aed4c45bc900998b5e11c03023264208James Dong coef[3] = r0 - r3; 64429a84457aed4c45bc900998b5e11c03023264208James Dong 64529a84457aed4c45bc900998b5e11c03023264208James Dong coef += 16; 64629a84457aed4c45bc900998b5e11c03023264208James Dong } 64729a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 64; 64829a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 64929a84457aed4c45bc900998b5e11c03023264208James Dong { 65029a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[32]; 65129a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[32]; 65229a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[16] >> 1) - coef[48]; 65329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[16] + (coef[48] >> 1); 65429a84457aed4c45bc900998b5e11c03023264208James Dong 65529a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; 65629a84457aed4c45bc900998b5e11c03023264208James Dong r3 = (r0 - (r3 << 1)); /* r0-r3 */ 65729a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; 65829a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (r1 - (r2 << 1)); /* r1-r2 */ 65929a84457aed4c45bc900998b5e11c03023264208James Dong r0 += 32; 66029a84457aed4c45bc900998b5e11c03023264208James Dong r1 += 32; 66129a84457aed4c45bc900998b5e11c03023264208James Dong r2 += 32; 66229a84457aed4c45bc900998b5e11c03023264208James Dong r3 += 32; 66329a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (r0 >> 6); 66429a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 66529a84457aed4c45bc900998b5e11c03023264208James Dong r1 = pred[16] + (r1 >> 6); 66629a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 66729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = pred[32] + (r2 >> 6); 66829a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 66929a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[48] + (r3 >> 6); 67029a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 67129a84457aed4c45bc900998b5e11c03023264208James Dong *curL = r0; 67229a84457aed4c45bc900998b5e11c03023264208James Dong *(curL += pitch) = r1; 67329a84457aed4c45bc900998b5e11c03023264208James Dong *(curL += pitch) = r2; 67429a84457aed4c45bc900998b5e11c03023264208James Dong curL[pitch] = r3; 67529a84457aed4c45bc900998b5e11c03023264208James Dong curL -= (pitch << 1); 67629a84457aed4c45bc900998b5e11c03023264208James Dong curL++; 67729a84457aed4c45bc900998b5e11c03023264208James Dong pred++; 67829a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 67929a84457aed4c45bc900998b5e11c03023264208James Dong } 68029a84457aed4c45bc900998b5e11c03023264208James Dong } 68129a84457aed4c45bc900998b5e11c03023264208James Dong else // do DC-only inverse 68229a84457aed4c45bc900998b5e11c03023264208James Dong { 68329a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + 32; 68429a84457aed4c45bc900998b5e11c03023264208James Dong 68529a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 68629a84457aed4c45bc900998b5e11c03023264208James Dong { 68729a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (m0 >> 6); 68829a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 68929a84457aed4c45bc900998b5e11c03023264208James Dong r1 = pred[16] + (m0 >> 6); 69029a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 69129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = pred[32] + (m0 >> 6); 69229a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 69329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[48] + (m0 >> 6); 69429a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 69529a84457aed4c45bc900998b5e11c03023264208James Dong *curL = r0; 69629a84457aed4c45bc900998b5e11c03023264208James Dong *(curL += pitch) = r1; 69729a84457aed4c45bc900998b5e11c03023264208James Dong *(curL += pitch) = r2; 69829a84457aed4c45bc900998b5e11c03023264208James Dong curL[pitch] = r3; 69929a84457aed4c45bc900998b5e11c03023264208James Dong curL -= (pitch << 1); 70029a84457aed4c45bc900998b5e11c03023264208James Dong curL++; 70129a84457aed4c45bc900998b5e11c03023264208James Dong pred++; 70229a84457aed4c45bc900998b5e11c03023264208James Dong } 70329a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 70429a84457aed4c45bc900998b5e11c03023264208James Dong } 70529a84457aed4c45bc900998b5e11c03023264208James Dong 70629a84457aed4c45bc900998b5e11c03023264208James Dong run += 16; // follow coding order 70729a84457aed4c45bc900998b5e11c03023264208James Dong level += 16; 70829a84457aed4c45bc900998b5e11c03023264208James Dong curL += offset_cur[b4&1]; 70929a84457aed4c45bc900998b5e11c03023264208James Dong pred += offset_pred[b4&1]; 71029a84457aed4c45bc900998b5e11c03023264208James Dong coef += offset_pred[b4&1]; 71129a84457aed4c45bc900998b5e11c03023264208James Dong } 71229a84457aed4c45bc900998b5e11c03023264208James Dong 71329a84457aed4c45bc900998b5e11c03023264208James Dong curL += offset_cur[2 + (b8&1)]; 71429a84457aed4c45bc900998b5e11c03023264208James Dong pred += offset_pred[2 + (b8&1)]; 71529a84457aed4c45bc900998b5e11c03023264208James Dong coef += offset_pred[2 + (b8&1)]; 71629a84457aed4c45bc900998b5e11c03023264208James Dong } 71729a84457aed4c45bc900998b5e11c03023264208James Dong 71829a84457aed4c45bc900998b5e11c03023264208James Dong return ; 71929a84457aed4c45bc900998b5e11c03023264208James Dong} 72029a84457aed4c45bc900998b5e11c03023264208James Dong 72129a84457aed4c45bc900998b5e11c03023264208James Dong 72229a84457aed4c45bc900998b5e11c03023264208James Dongvoid dct_chroma(AVCEncObject *encvid, uint8 *curC, uint8 *orgC, int cr) 72329a84457aed4c45bc900998b5e11c03023264208James Dong{ 72429a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 72529a84457aed4c45bc900998b5e11c03023264208James Dong AVCMacroblock *currMB = video->currMB; 72629a84457aed4c45bc900998b5e11c03023264208James Dong int org_pitch = (encvid->currInput->pitch) >> 1; 72729a84457aed4c45bc900998b5e11c03023264208James Dong int pitch = (video->currPic->pitch) >> 1; 72829a84457aed4c45bc900998b5e11c03023264208James Dong int pred_pitch = 16; 72929a84457aed4c45bc900998b5e11c03023264208James Dong int16 *coef = video->block + 256; 73029a84457aed4c45bc900998b5e11c03023264208James Dong uint8 *pred = video->pred_block; 73129a84457aed4c45bc900998b5e11c03023264208James Dong int j, blk_x, blk_y, k, idx, b4; 73229a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, m0; 73329a84457aed4c45bc900998b5e11c03023264208James Dong int Qq, Rq, qp_const, q_bits, quant; 73429a84457aed4c45bc900998b5e11c03023264208James Dong int *level, *run, zero_run, ncoeff; 73529a84457aed4c45bc900998b5e11c03023264208James Dong int data, lev; 73629a84457aed4c45bc900998b5e11c03023264208James Dong int offset_cur[2], offset_pred[2], offset_coef[2]; 73729a84457aed4c45bc900998b5e11c03023264208James Dong uint8 nz_temp[4]; 73829a84457aed4c45bc900998b5e11c03023264208James Dong int coeff_cost; 73929a84457aed4c45bc900998b5e11c03023264208James Dong 74029a84457aed4c45bc900998b5e11c03023264208James Dong if (cr) 74129a84457aed4c45bc900998b5e11c03023264208James Dong { 74229a84457aed4c45bc900998b5e11c03023264208James Dong coef += 8; 74329a84457aed4c45bc900998b5e11c03023264208James Dong pred += 8; 74429a84457aed4c45bc900998b5e11c03023264208James Dong } 74529a84457aed4c45bc900998b5e11c03023264208James Dong 74629a84457aed4c45bc900998b5e11c03023264208James Dong if (currMB->mb_intra == 0) // inter mode 74729a84457aed4c45bc900998b5e11c03023264208James Dong { 74829a84457aed4c45bc900998b5e11c03023264208James Dong pred = curC; 74929a84457aed4c45bc900998b5e11c03023264208James Dong pred_pitch = pitch; 75029a84457aed4c45bc900998b5e11c03023264208James Dong } 75129a84457aed4c45bc900998b5e11c03023264208James Dong 75229a84457aed4c45bc900998b5e11c03023264208James Dong /* do 4x4 transform */ 75329a84457aed4c45bc900998b5e11c03023264208James Dong /* horizontal */ 75429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 8; j > 0; j--) 75529a84457aed4c45bc900998b5e11c03023264208James Dong { 75629a84457aed4c45bc900998b5e11c03023264208James Dong for (blk_x = 2; blk_x > 0; blk_x--) 75729a84457aed4c45bc900998b5e11c03023264208James Dong { 75829a84457aed4c45bc900998b5e11c03023264208James Dong /* calculate the residue first */ 75929a84457aed4c45bc900998b5e11c03023264208James Dong r0 = *orgC++ - *pred++; 76029a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *orgC++ - *pred++; 76129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = *orgC++ - *pred++; 76229a84457aed4c45bc900998b5e11c03023264208James Dong r3 = *orgC++ - *pred++; 76329a84457aed4c45bc900998b5e11c03023264208James Dong 76429a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; //ptr[0] + ptr[3]; 76529a84457aed4c45bc900998b5e11c03023264208James Dong r3 = r0 - (r3 << 1); //ptr[0] - ptr[3]; 76629a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; //ptr[1] + ptr[2]; 76729a84457aed4c45bc900998b5e11c03023264208James Dong r2 = r1 - (r2 << 1); //ptr[1] - ptr[2]; 76829a84457aed4c45bc900998b5e11c03023264208James Dong 76929a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r0 + r1; 77029a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = (r3 << 1) + r2; 77129a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r0 - r1; 77229a84457aed4c45bc900998b5e11c03023264208James Dong *coef++ = r3 - (r2 << 1); 77329a84457aed4c45bc900998b5e11c03023264208James Dong 77429a84457aed4c45bc900998b5e11c03023264208James Dong } 77529a84457aed4c45bc900998b5e11c03023264208James Dong coef += 8; // coef pitch is 16 77629a84457aed4c45bc900998b5e11c03023264208James Dong pred += (pred_pitch - 8); // pred_pitch is 16 77729a84457aed4c45bc900998b5e11c03023264208James Dong orgC += (org_pitch - 8); 77829a84457aed4c45bc900998b5e11c03023264208James Dong } 77929a84457aed4c45bc900998b5e11c03023264208James Dong pred -= (pred_pitch << 3); 78029a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 128; 78129a84457aed4c45bc900998b5e11c03023264208James Dong /* vertical */ 78229a84457aed4c45bc900998b5e11c03023264208James Dong for (blk_y = 2; blk_y > 0; blk_y--) 78329a84457aed4c45bc900998b5e11c03023264208James Dong { 78429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 8; j > 0; j--) 78529a84457aed4c45bc900998b5e11c03023264208James Dong { 78629a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[48]; 78729a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[0] - coef[48]; 78829a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[16] + coef[32]; 78929a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[16] - coef[32]; 79029a84457aed4c45bc900998b5e11c03023264208James Dong 79129a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1; 79229a84457aed4c45bc900998b5e11c03023264208James Dong coef[32] = r0 - r1; 79329a84457aed4c45bc900998b5e11c03023264208James Dong coef[16] = (r3 << 1) + r2; 79429a84457aed4c45bc900998b5e11c03023264208James Dong coef[48] = r3 - (r2 << 1); 79529a84457aed4c45bc900998b5e11c03023264208James Dong 79629a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 79729a84457aed4c45bc900998b5e11c03023264208James Dong } 79829a84457aed4c45bc900998b5e11c03023264208James Dong coef += 56; 79929a84457aed4c45bc900998b5e11c03023264208James Dong } 80029a84457aed4c45bc900998b5e11c03023264208James Dong /* then perform DC transform */ 80129a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 128; 80229a84457aed4c45bc900998b5e11c03023264208James Dong 80329a84457aed4c45bc900998b5e11c03023264208James Dong /* 2x2 transform of DC components*/ 80429a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0]; 80529a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[4]; 80629a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[64]; 80729a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[68]; 80829a84457aed4c45bc900998b5e11c03023264208James Dong 80929a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r1 + r2 + r3; 81029a84457aed4c45bc900998b5e11c03023264208James Dong coef[4] = r0 - r1 + r2 - r3; 81129a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = r0 + r1 - r2 - r3; 81229a84457aed4c45bc900998b5e11c03023264208James Dong coef[68] = r0 - r1 - r2 + r3; 81329a84457aed4c45bc900998b5e11c03023264208James Dong 81429a84457aed4c45bc900998b5e11c03023264208James Dong Qq = video->QPc_div_6; 81529a84457aed4c45bc900998b5e11c03023264208James Dong Rq = video->QPc_mod_6; 81629a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][0]; 81729a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 15 + Qq; 81829a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = encvid->qp_const_c; 81929a84457aed4c45bc900998b5e11c03023264208James Dong 82029a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 82129a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 82229a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->runcdc + (cr << 2); 82329a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->levelcdc + (cr << 2); 82429a84457aed4c45bc900998b5e11c03023264208James Dong 82529a84457aed4c45bc900998b5e11c03023264208James Dong /* in zigzag scan order */ 82629a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 0; k < 4; k++) 82729a84457aed4c45bc900998b5e11c03023264208James Dong { 82829a84457aed4c45bc900998b5e11c03023264208James Dong idx = ((k >> 1) << 6) + ((k & 1) << 2); 82929a84457aed4c45bc900998b5e11c03023264208James Dong data = coef[idx]; 83029a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 83129a84457aed4c45bc900998b5e11c03023264208James Dong { 83229a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + (qp_const << 1); 83329a84457aed4c45bc900998b5e11c03023264208James Dong } 83429a84457aed4c45bc900998b5e11c03023264208James Dong else 83529a84457aed4c45bc900998b5e11c03023264208James Dong { 83629a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + (qp_const << 1); 83729a84457aed4c45bc900998b5e11c03023264208James Dong } 83829a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= (q_bits + 1); 83929a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 84029a84457aed4c45bc900998b5e11c03023264208James Dong { 84129a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 84229a84457aed4c45bc900998b5e11c03023264208James Dong { 84329a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 84429a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = lev; 84529a84457aed4c45bc900998b5e11c03023264208James Dong } 84629a84457aed4c45bc900998b5e11c03023264208James Dong else 84729a84457aed4c45bc900998b5e11c03023264208James Dong { 84829a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 84929a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = -lev; 85029a84457aed4c45bc900998b5e11c03023264208James Dong } 85129a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 85229a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 85329a84457aed4c45bc900998b5e11c03023264208James Dong } 85429a84457aed4c45bc900998b5e11c03023264208James Dong else 85529a84457aed4c45bc900998b5e11c03023264208James Dong { 85629a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 85729a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = 0; 85829a84457aed4c45bc900998b5e11c03023264208James Dong } 85929a84457aed4c45bc900998b5e11c03023264208James Dong } 86029a84457aed4c45bc900998b5e11c03023264208James Dong 86129a84457aed4c45bc900998b5e11c03023264208James Dong encvid->numcoefcdc[cr] = ncoeff; 86229a84457aed4c45bc900998b5e11c03023264208James Dong 86329a84457aed4c45bc900998b5e11c03023264208James Dong if (ncoeff) 86429a84457aed4c45bc900998b5e11c03023264208James Dong { 86529a84457aed4c45bc900998b5e11c03023264208James Dong currMB->CBP |= (1 << 4); // DC present 86629a84457aed4c45bc900998b5e11c03023264208James Dong // do inverse transform 86729a84457aed4c45bc900998b5e11c03023264208James Dong quant = dequant_coefres[Rq][0]; 86829a84457aed4c45bc900998b5e11c03023264208James Dong 86929a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[4]; 87029a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[4]; 87129a84457aed4c45bc900998b5e11c03023264208James Dong r2 = coef[64] + coef[68]; 87229a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[64] - coef[68]; 87329a84457aed4c45bc900998b5e11c03023264208James Dong 87429a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r2; 87529a84457aed4c45bc900998b5e11c03023264208James Dong r2 = r0 - (r2 << 1); 87629a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r3; 87729a84457aed4c45bc900998b5e11c03023264208James Dong r3 = r1 - (r3 << 1); 87829a84457aed4c45bc900998b5e11c03023264208James Dong 87929a84457aed4c45bc900998b5e11c03023264208James Dong if (Qq >= 1) 88029a84457aed4c45bc900998b5e11c03023264208James Dong { 88129a84457aed4c45bc900998b5e11c03023264208James Dong Qq -= 1; 88229a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = (r0 * quant) << Qq; 88329a84457aed4c45bc900998b5e11c03023264208James Dong coef[4] = (r1 * quant) << Qq; 88429a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = (r2 * quant) << Qq; 88529a84457aed4c45bc900998b5e11c03023264208James Dong coef[68] = (r3 * quant) << Qq; 88629a84457aed4c45bc900998b5e11c03023264208James Dong Qq++; 88729a84457aed4c45bc900998b5e11c03023264208James Dong } 88829a84457aed4c45bc900998b5e11c03023264208James Dong else 88929a84457aed4c45bc900998b5e11c03023264208James Dong { 89029a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = (r0 * quant) >> 1; 89129a84457aed4c45bc900998b5e11c03023264208James Dong coef[4] = (r1 * quant) >> 1; 89229a84457aed4c45bc900998b5e11c03023264208James Dong coef[64] = (r2 * quant) >> 1; 89329a84457aed4c45bc900998b5e11c03023264208James Dong coef[68] = (r3 * quant) >> 1; 89429a84457aed4c45bc900998b5e11c03023264208James Dong } 89529a84457aed4c45bc900998b5e11c03023264208James Dong } 89629a84457aed4c45bc900998b5e11c03023264208James Dong 89729a84457aed4c45bc900998b5e11c03023264208James Dong /* now do AC zigzag scan, quant, iquant and itrans */ 89829a84457aed4c45bc900998b5e11c03023264208James Dong if (cr) 89929a84457aed4c45bc900998b5e11c03023264208James Dong { 90029a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[20]; 90129a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[20]; 90229a84457aed4c45bc900998b5e11c03023264208James Dong } 90329a84457aed4c45bc900998b5e11c03023264208James Dong else 90429a84457aed4c45bc900998b5e11c03023264208James Dong { 90529a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[16]; 90629a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[16]; 90729a84457aed4c45bc900998b5e11c03023264208James Dong } 90829a84457aed4c45bc900998b5e11c03023264208James Dong 90929a84457aed4c45bc900998b5e11c03023264208James Dong /* offset btw 4x4 block */ 91029a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[0] = 0; 91129a84457aed4c45bc900998b5e11c03023264208James Dong offset_cur[1] = (pitch << 2) - 8; 91229a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[0] = 0; 91329a84457aed4c45bc900998b5e11c03023264208James Dong offset_pred[1] = (pred_pitch << 2) - 8; 91429a84457aed4c45bc900998b5e11c03023264208James Dong offset_coef[0] = 0; 91529a84457aed4c45bc900998b5e11c03023264208James Dong offset_coef[1] = 56; 91629a84457aed4c45bc900998b5e11c03023264208James Dong 91729a84457aed4c45bc900998b5e11c03023264208James Dong coeff_cost = 0; 91829a84457aed4c45bc900998b5e11c03023264208James Dong 91929a84457aed4c45bc900998b5e11c03023264208James Dong for (b4 = 0; b4 < 4; b4++) 92029a84457aed4c45bc900998b5e11c03023264208James Dong { 92129a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 92229a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 92329a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 1; k < 16; k++) /* in zigzag scan order */ 92429a84457aed4c45bc900998b5e11c03023264208James Dong { 92529a84457aed4c45bc900998b5e11c03023264208James Dong idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */ 92629a84457aed4c45bc900998b5e11c03023264208James Dong data = coef[idx]; 92729a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][k]; 92829a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 92929a84457aed4c45bc900998b5e11c03023264208James Dong { 93029a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + qp_const; 93129a84457aed4c45bc900998b5e11c03023264208James Dong } 93229a84457aed4c45bc900998b5e11c03023264208James Dong else 93329a84457aed4c45bc900998b5e11c03023264208James Dong { 93429a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + qp_const; 93529a84457aed4c45bc900998b5e11c03023264208James Dong } 93629a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= q_bits; 93729a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 93829a84457aed4c45bc900998b5e11c03023264208James Dong { 93929a84457aed4c45bc900998b5e11c03023264208James Dong /* for RD performance*/ 94029a84457aed4c45bc900998b5e11c03023264208James Dong if (lev > 1) 94129a84457aed4c45bc900998b5e11c03023264208James Dong coeff_cost += MAX_VALUE; // set high cost, shall not be discarded 94229a84457aed4c45bc900998b5e11c03023264208James Dong else 94329a84457aed4c45bc900998b5e11c03023264208James Dong coeff_cost += COEFF_COST[DISABLE_THRESHOLDING][zero_run]; 94429a84457aed4c45bc900998b5e11c03023264208James Dong 94529a84457aed4c45bc900998b5e11c03023264208James Dong /* dequant */ 94629a84457aed4c45bc900998b5e11c03023264208James Dong quant = dequant_coefres[Rq][k]; 94729a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 94829a84457aed4c45bc900998b5e11c03023264208James Dong { 94929a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 95029a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (lev * quant) << Qq; 95129a84457aed4c45bc900998b5e11c03023264208James Dong } 95229a84457aed4c45bc900998b5e11c03023264208James Dong else 95329a84457aed4c45bc900998b5e11c03023264208James Dong { 95429a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 95529a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = (-lev * quant) << Qq; 95629a84457aed4c45bc900998b5e11c03023264208James Dong } 95729a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 95829a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 95929a84457aed4c45bc900998b5e11c03023264208James Dong } 96029a84457aed4c45bc900998b5e11c03023264208James Dong else 96129a84457aed4c45bc900998b5e11c03023264208James Dong { 96229a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 96329a84457aed4c45bc900998b5e11c03023264208James Dong coef[idx] = 0; 96429a84457aed4c45bc900998b5e11c03023264208James Dong } 96529a84457aed4c45bc900998b5e11c03023264208James Dong } 96629a84457aed4c45bc900998b5e11c03023264208James Dong 96729a84457aed4c45bc900998b5e11c03023264208James Dong nz_temp[b4] = ncoeff; // raster scan 96829a84457aed4c45bc900998b5e11c03023264208James Dong 96929a84457aed4c45bc900998b5e11c03023264208James Dong // just advance the pointers for now, do IDCT later 97029a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 97129a84457aed4c45bc900998b5e11c03023264208James Dong run += 16; 97229a84457aed4c45bc900998b5e11c03023264208James Dong level += 16; 97329a84457aed4c45bc900998b5e11c03023264208James Dong coef += offset_coef[b4&1]; 97429a84457aed4c45bc900998b5e11c03023264208James Dong } 97529a84457aed4c45bc900998b5e11c03023264208James Dong 97629a84457aed4c45bc900998b5e11c03023264208James Dong /* rewind the pointers */ 97729a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 128; 97829a84457aed4c45bc900998b5e11c03023264208James Dong 97929a84457aed4c45bc900998b5e11c03023264208James Dong if (coeff_cost < _CHROMA_COEFF_COST_) 98029a84457aed4c45bc900998b5e11c03023264208James Dong { 98129a84457aed4c45bc900998b5e11c03023264208James Dong /* if it's not efficient to encode any blocks. 98229a84457aed4c45bc900998b5e11c03023264208James Dong Just do DC only */ 98329a84457aed4c45bc900998b5e11c03023264208James Dong /* We can reset level and run also, but setting nz to zero should be enough. */ 98429a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[16+(cr<<1)] = 0; 98529a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[17+(cr<<1)] = 0; 98629a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[20+(cr<<1)] = 0; 98729a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[21+(cr<<1)] = 0; 98829a84457aed4c45bc900998b5e11c03023264208James Dong 98929a84457aed4c45bc900998b5e11c03023264208James Dong for (b4 = 0; b4 < 4; b4++) 99029a84457aed4c45bc900998b5e11c03023264208James Dong { 99129a84457aed4c45bc900998b5e11c03023264208James Dong // do DC-only inverse 99229a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + 32; 99329a84457aed4c45bc900998b5e11c03023264208James Dong 99429a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 99529a84457aed4c45bc900998b5e11c03023264208James Dong { 99629a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (m0 >> 6); 99729a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 99829a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *(pred += pred_pitch) + (m0 >> 6); 99929a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 100029a84457aed4c45bc900998b5e11c03023264208James Dong r2 = pred[pred_pitch] + (m0 >> 6); 100129a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 100229a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[pred_pitch<<1] + (m0 >> 6); 100329a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 100429a84457aed4c45bc900998b5e11c03023264208James Dong *curC = r0; 100529a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r1; 100629a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r2; 100729a84457aed4c45bc900998b5e11c03023264208James Dong curC[pitch] = r3; 100829a84457aed4c45bc900998b5e11c03023264208James Dong curC -= (pitch << 1); 100929a84457aed4c45bc900998b5e11c03023264208James Dong curC++; 101029a84457aed4c45bc900998b5e11c03023264208James Dong pred += (1 - pred_pitch); 101129a84457aed4c45bc900998b5e11c03023264208James Dong } 101229a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 101329a84457aed4c45bc900998b5e11c03023264208James Dong curC += offset_cur[b4&1]; 101429a84457aed4c45bc900998b5e11c03023264208James Dong pred += offset_pred[b4&1]; 101529a84457aed4c45bc900998b5e11c03023264208James Dong coef += offset_coef[b4&1]; 101629a84457aed4c45bc900998b5e11c03023264208James Dong } 101729a84457aed4c45bc900998b5e11c03023264208James Dong } 101829a84457aed4c45bc900998b5e11c03023264208James Dong else // not dropping anything, continue with the IDCT 101929a84457aed4c45bc900998b5e11c03023264208James Dong { 102029a84457aed4c45bc900998b5e11c03023264208James Dong for (b4 = 0; b4 < 4; b4++) 102129a84457aed4c45bc900998b5e11c03023264208James Dong { 102229a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = nz_temp[b4] ; // in raster scan 102329a84457aed4c45bc900998b5e11c03023264208James Dong currMB->nz_coeff[16+(b4&1)+(cr<<1)+((b4>>1)<<2)] = ncoeff; // in raster scan 102429a84457aed4c45bc900998b5e11c03023264208James Dong 102529a84457aed4c45bc900998b5e11c03023264208James Dong if (ncoeff) // do a check on the nonzero-coeff 102629a84457aed4c45bc900998b5e11c03023264208James Dong { 102729a84457aed4c45bc900998b5e11c03023264208James Dong currMB->CBP |= (2 << 4); 102829a84457aed4c45bc900998b5e11c03023264208James Dong 102929a84457aed4c45bc900998b5e11c03023264208James Dong // do inverse transform here 103029a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 103129a84457aed4c45bc900998b5e11c03023264208James Dong { 103229a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[2]; 103329a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[2]; 103429a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[1] >> 1) - coef[3]; 103529a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[1] + (coef[3] >> 1); 103629a84457aed4c45bc900998b5e11c03023264208James Dong 103729a84457aed4c45bc900998b5e11c03023264208James Dong coef[0] = r0 + r3; 103829a84457aed4c45bc900998b5e11c03023264208James Dong coef[1] = r1 + r2; 103929a84457aed4c45bc900998b5e11c03023264208James Dong coef[2] = r1 - r2; 104029a84457aed4c45bc900998b5e11c03023264208James Dong coef[3] = r0 - r3; 104129a84457aed4c45bc900998b5e11c03023264208James Dong 104229a84457aed4c45bc900998b5e11c03023264208James Dong coef += 16; 104329a84457aed4c45bc900998b5e11c03023264208James Dong } 104429a84457aed4c45bc900998b5e11c03023264208James Dong coef -= 64; 104529a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 104629a84457aed4c45bc900998b5e11c03023264208James Dong { 104729a84457aed4c45bc900998b5e11c03023264208James Dong r0 = coef[0] + coef[32]; 104829a84457aed4c45bc900998b5e11c03023264208James Dong r1 = coef[0] - coef[32]; 104929a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (coef[16] >> 1) - coef[48]; 105029a84457aed4c45bc900998b5e11c03023264208James Dong r3 = coef[16] + (coef[48] >> 1); 105129a84457aed4c45bc900998b5e11c03023264208James Dong 105229a84457aed4c45bc900998b5e11c03023264208James Dong r0 += r3; 105329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = (r0 - (r3 << 1)); /* r0-r3 */ 105429a84457aed4c45bc900998b5e11c03023264208James Dong r1 += r2; 105529a84457aed4c45bc900998b5e11c03023264208James Dong r2 = (r1 - (r2 << 1)); /* r1-r2 */ 105629a84457aed4c45bc900998b5e11c03023264208James Dong r0 += 32; 105729a84457aed4c45bc900998b5e11c03023264208James Dong r1 += 32; 105829a84457aed4c45bc900998b5e11c03023264208James Dong r2 += 32; 105929a84457aed4c45bc900998b5e11c03023264208James Dong r3 += 32; 106029a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (r0 >> 6); 106129a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 106229a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *(pred += pred_pitch) + (r1 >> 6); 106329a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 106429a84457aed4c45bc900998b5e11c03023264208James Dong r2 = pred[pred_pitch] + (r2 >> 6); 106529a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 106629a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[pred_pitch<<1] + (r3 >> 6); 106729a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 106829a84457aed4c45bc900998b5e11c03023264208James Dong *curC = r0; 106929a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r1; 107029a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r2; 107129a84457aed4c45bc900998b5e11c03023264208James Dong curC[pitch] = r3; 107229a84457aed4c45bc900998b5e11c03023264208James Dong curC -= (pitch << 1); 107329a84457aed4c45bc900998b5e11c03023264208James Dong curC++; 107429a84457aed4c45bc900998b5e11c03023264208James Dong pred += (1 - pred_pitch); 107529a84457aed4c45bc900998b5e11c03023264208James Dong coef++; 107629a84457aed4c45bc900998b5e11c03023264208James Dong } 107729a84457aed4c45bc900998b5e11c03023264208James Dong } 107829a84457aed4c45bc900998b5e11c03023264208James Dong else 107929a84457aed4c45bc900998b5e11c03023264208James Dong { 108029a84457aed4c45bc900998b5e11c03023264208James Dong // do DC-only inverse 108129a84457aed4c45bc900998b5e11c03023264208James Dong m0 = coef[0] + 32; 108229a84457aed4c45bc900998b5e11c03023264208James Dong 108329a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 4; j > 0; j--) 108429a84457aed4c45bc900998b5e11c03023264208James Dong { 108529a84457aed4c45bc900998b5e11c03023264208James Dong r0 = pred[0] + (m0 >> 6); 108629a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r0 > 0xFF) r0 = 0xFF & (~(r0 >> 31)); /* clip */ 108729a84457aed4c45bc900998b5e11c03023264208James Dong r1 = *(pred += pred_pitch) + (m0 >> 6); 108829a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r1 > 0xFF) r1 = 0xFF & (~(r1 >> 31)); /* clip */ 108929a84457aed4c45bc900998b5e11c03023264208James Dong r2 = pred[pred_pitch] + (m0 >> 6); 109029a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r2 > 0xFF) r2 = 0xFF & (~(r2 >> 31)); /* clip */ 109129a84457aed4c45bc900998b5e11c03023264208James Dong r3 = pred[pred_pitch<<1] + (m0 >> 6); 109229a84457aed4c45bc900998b5e11c03023264208James Dong if ((uint)r3 > 0xFF) r3 = 0xFF & (~(r3 >> 31)); /* clip */ 109329a84457aed4c45bc900998b5e11c03023264208James Dong *curC = r0; 109429a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r1; 109529a84457aed4c45bc900998b5e11c03023264208James Dong *(curC += pitch) = r2; 109629a84457aed4c45bc900998b5e11c03023264208James Dong curC[pitch] = r3; 109729a84457aed4c45bc900998b5e11c03023264208James Dong curC -= (pitch << 1); 109829a84457aed4c45bc900998b5e11c03023264208James Dong curC++; 109929a84457aed4c45bc900998b5e11c03023264208James Dong pred += (1 - pred_pitch); 110029a84457aed4c45bc900998b5e11c03023264208James Dong } 110129a84457aed4c45bc900998b5e11c03023264208James Dong coef += 4; 110229a84457aed4c45bc900998b5e11c03023264208James Dong } 110329a84457aed4c45bc900998b5e11c03023264208James Dong curC += offset_cur[b4&1]; 110429a84457aed4c45bc900998b5e11c03023264208James Dong pred += offset_pred[b4&1]; 110529a84457aed4c45bc900998b5e11c03023264208James Dong coef += offset_coef[b4&1]; 110629a84457aed4c45bc900998b5e11c03023264208James Dong } 110729a84457aed4c45bc900998b5e11c03023264208James Dong } 110829a84457aed4c45bc900998b5e11c03023264208James Dong 110929a84457aed4c45bc900998b5e11c03023264208James Dong return ; 111029a84457aed4c45bc900998b5e11c03023264208James Dong} 111129a84457aed4c45bc900998b5e11c03023264208James Dong 111229a84457aed4c45bc900998b5e11c03023264208James Dong 111329a84457aed4c45bc900998b5e11c03023264208James Dong/* only DC transform */ 111429a84457aed4c45bc900998b5e11c03023264208James Dongint TransQuantIntra16DC(AVCEncObject *encvid) 111529a84457aed4c45bc900998b5e11c03023264208James Dong{ 111629a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 111729a84457aed4c45bc900998b5e11c03023264208James Dong int16 *block = video->block; 111829a84457aed4c45bc900998b5e11c03023264208James Dong int *level = encvid->leveldc; 111929a84457aed4c45bc900998b5e11c03023264208James Dong int *run = encvid->rundc; 112029a84457aed4c45bc900998b5e11c03023264208James Dong int16 *ptr = block; 112129a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3, j; 112229a84457aed4c45bc900998b5e11c03023264208James Dong int Qq = video->QPy_div_6; 112329a84457aed4c45bc900998b5e11c03023264208James Dong int Rq = video->QPy_mod_6; 112429a84457aed4c45bc900998b5e11c03023264208James Dong int q_bits, qp_const, quant; 112529a84457aed4c45bc900998b5e11c03023264208James Dong int data, lev, zero_run; 112629a84457aed4c45bc900998b5e11c03023264208James Dong int k, ncoeff, idx; 112729a84457aed4c45bc900998b5e11c03023264208James Dong 112829a84457aed4c45bc900998b5e11c03023264208James Dong /* DC transform */ 112929a84457aed4c45bc900998b5e11c03023264208James Dong /* horizontal */ 113029a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 113129a84457aed4c45bc900998b5e11c03023264208James Dong while (j) 113229a84457aed4c45bc900998b5e11c03023264208James Dong { 113329a84457aed4c45bc900998b5e11c03023264208James Dong r0 = ptr[0] + ptr[12]; 113429a84457aed4c45bc900998b5e11c03023264208James Dong r3 = ptr[0] - ptr[12]; 113529a84457aed4c45bc900998b5e11c03023264208James Dong r1 = ptr[4] + ptr[8]; 113629a84457aed4c45bc900998b5e11c03023264208James Dong r2 = ptr[4] - ptr[8]; 113729a84457aed4c45bc900998b5e11c03023264208James Dong 113829a84457aed4c45bc900998b5e11c03023264208James Dong ptr[0] = r0 + r1; 113929a84457aed4c45bc900998b5e11c03023264208James Dong ptr[8] = r0 - r1; 114029a84457aed4c45bc900998b5e11c03023264208James Dong ptr[4] = r3 + r2; 114129a84457aed4c45bc900998b5e11c03023264208James Dong ptr[12] = r3 - r2; 114229a84457aed4c45bc900998b5e11c03023264208James Dong ptr += 64; 114329a84457aed4c45bc900998b5e11c03023264208James Dong j--; 114429a84457aed4c45bc900998b5e11c03023264208James Dong } 114529a84457aed4c45bc900998b5e11c03023264208James Dong /* vertical */ 114629a84457aed4c45bc900998b5e11c03023264208James Dong ptr = block; 114729a84457aed4c45bc900998b5e11c03023264208James Dong j = 4; 114829a84457aed4c45bc900998b5e11c03023264208James Dong while (j) 114929a84457aed4c45bc900998b5e11c03023264208James Dong { 115029a84457aed4c45bc900998b5e11c03023264208James Dong r0 = ptr[0] + ptr[192]; 115129a84457aed4c45bc900998b5e11c03023264208James Dong r3 = ptr[0] - ptr[192]; 115229a84457aed4c45bc900998b5e11c03023264208James Dong r1 = ptr[64] + ptr[128]; 115329a84457aed4c45bc900998b5e11c03023264208James Dong r2 = ptr[64] - ptr[128]; 115429a84457aed4c45bc900998b5e11c03023264208James Dong 115529a84457aed4c45bc900998b5e11c03023264208James Dong ptr[0] = (r0 + r1) >> 1; 115629a84457aed4c45bc900998b5e11c03023264208James Dong ptr[128] = (r0 - r1) >> 1; 115729a84457aed4c45bc900998b5e11c03023264208James Dong ptr[64] = (r3 + r2) >> 1; 115829a84457aed4c45bc900998b5e11c03023264208James Dong ptr[192] = (r3 - r2) >> 1; 115929a84457aed4c45bc900998b5e11c03023264208James Dong ptr += 4; 116029a84457aed4c45bc900998b5e11c03023264208James Dong j--; 116129a84457aed4c45bc900998b5e11c03023264208James Dong } 116229a84457aed4c45bc900998b5e11c03023264208James Dong 116329a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][0]; 116429a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 15 + Qq; 116529a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = (1 << q_bits) / 3; // intra 116629a84457aed4c45bc900998b5e11c03023264208James Dong 116729a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 116829a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 116929a84457aed4c45bc900998b5e11c03023264208James Dong 117029a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 0; k < 16; k++) /* in zigzag scan order */ 117129a84457aed4c45bc900998b5e11c03023264208James Dong { 117229a84457aed4c45bc900998b5e11c03023264208James Dong idx = ZIGZAG2RASTERDC[k]; 117329a84457aed4c45bc900998b5e11c03023264208James Dong data = block[idx]; 117429a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 117529a84457aed4c45bc900998b5e11c03023264208James Dong { 117629a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + (qp_const << 1); 117729a84457aed4c45bc900998b5e11c03023264208James Dong } 117829a84457aed4c45bc900998b5e11c03023264208James Dong else 117929a84457aed4c45bc900998b5e11c03023264208James Dong { 118029a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + (qp_const << 1); 118129a84457aed4c45bc900998b5e11c03023264208James Dong } 118229a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= (q_bits + 1); 118329a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 118429a84457aed4c45bc900998b5e11c03023264208James Dong { 118529a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 118629a84457aed4c45bc900998b5e11c03023264208James Dong { 118729a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 118829a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = lev; 118929a84457aed4c45bc900998b5e11c03023264208James Dong } 119029a84457aed4c45bc900998b5e11c03023264208James Dong else 119129a84457aed4c45bc900998b5e11c03023264208James Dong { 119229a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 119329a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = -lev; 119429a84457aed4c45bc900998b5e11c03023264208James Dong } 119529a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 119629a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 119729a84457aed4c45bc900998b5e11c03023264208James Dong } 119829a84457aed4c45bc900998b5e11c03023264208James Dong else 119929a84457aed4c45bc900998b5e11c03023264208James Dong { 120029a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 120129a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = 0; 120229a84457aed4c45bc900998b5e11c03023264208James Dong } 120329a84457aed4c45bc900998b5e11c03023264208James Dong } 120429a84457aed4c45bc900998b5e11c03023264208James Dong return ncoeff; 120529a84457aed4c45bc900998b5e11c03023264208James Dong} 120629a84457aed4c45bc900998b5e11c03023264208James Dong 120729a84457aed4c45bc900998b5e11c03023264208James Dongint TransQuantChromaDC(AVCEncObject *encvid, int16 *block, int slice_type, int cr) 120829a84457aed4c45bc900998b5e11c03023264208James Dong{ 120929a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 121029a84457aed4c45bc900998b5e11c03023264208James Dong int *level, *run; 121129a84457aed4c45bc900998b5e11c03023264208James Dong int r0, r1, r2, r3; 121229a84457aed4c45bc900998b5e11c03023264208James Dong int Qq, Rq, q_bits, qp_const, quant; 121329a84457aed4c45bc900998b5e11c03023264208James Dong int data, lev, zero_run; 121429a84457aed4c45bc900998b5e11c03023264208James Dong int k, ncoeff, idx; 121529a84457aed4c45bc900998b5e11c03023264208James Dong 121629a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->levelcdc + (cr << 2); /* cb or cr */ 121729a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->runcdc + (cr << 2); 121829a84457aed4c45bc900998b5e11c03023264208James Dong 121929a84457aed4c45bc900998b5e11c03023264208James Dong /* 2x2 transform of DC components*/ 122029a84457aed4c45bc900998b5e11c03023264208James Dong r0 = block[0]; 122129a84457aed4c45bc900998b5e11c03023264208James Dong r1 = block[4]; 122229a84457aed4c45bc900998b5e11c03023264208James Dong r2 = block[64]; 122329a84457aed4c45bc900998b5e11c03023264208James Dong r3 = block[68]; 122429a84457aed4c45bc900998b5e11c03023264208James Dong 122529a84457aed4c45bc900998b5e11c03023264208James Dong block[0] = r0 + r1 + r2 + r3; 122629a84457aed4c45bc900998b5e11c03023264208James Dong block[4] = r0 - r1 + r2 - r3; 122729a84457aed4c45bc900998b5e11c03023264208James Dong block[64] = r0 + r1 - r2 - r3; 122829a84457aed4c45bc900998b5e11c03023264208James Dong block[68] = r0 - r1 - r2 + r3; 122929a84457aed4c45bc900998b5e11c03023264208James Dong 123029a84457aed4c45bc900998b5e11c03023264208James Dong Qq = video->QPc_div_6; 123129a84457aed4c45bc900998b5e11c03023264208James Dong Rq = video->QPc_mod_6; 123229a84457aed4c45bc900998b5e11c03023264208James Dong quant = quant_coef[Rq][0]; 123329a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 15 + Qq; 123429a84457aed4c45bc900998b5e11c03023264208James Dong if (slice_type == AVC_I_SLICE) 123529a84457aed4c45bc900998b5e11c03023264208James Dong { 123629a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = (1 << q_bits) / 3; 123729a84457aed4c45bc900998b5e11c03023264208James Dong } 123829a84457aed4c45bc900998b5e11c03023264208James Dong else 123929a84457aed4c45bc900998b5e11c03023264208James Dong { 124029a84457aed4c45bc900998b5e11c03023264208James Dong qp_const = (1 << q_bits) / 6; 124129a84457aed4c45bc900998b5e11c03023264208James Dong } 124229a84457aed4c45bc900998b5e11c03023264208James Dong 124329a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 124429a84457aed4c45bc900998b5e11c03023264208James Dong ncoeff = 0; 124529a84457aed4c45bc900998b5e11c03023264208James Dong 124629a84457aed4c45bc900998b5e11c03023264208James Dong for (k = 0; k < 4; k++) /* in zigzag scan order */ 124729a84457aed4c45bc900998b5e11c03023264208James Dong { 124829a84457aed4c45bc900998b5e11c03023264208James Dong idx = ((k >> 1) << 6) + ((k & 1) << 2); 124929a84457aed4c45bc900998b5e11c03023264208James Dong data = block[idx]; 125029a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 125129a84457aed4c45bc900998b5e11c03023264208James Dong { 125229a84457aed4c45bc900998b5e11c03023264208James Dong lev = data * quant + (qp_const << 1); 125329a84457aed4c45bc900998b5e11c03023264208James Dong } 125429a84457aed4c45bc900998b5e11c03023264208James Dong else 125529a84457aed4c45bc900998b5e11c03023264208James Dong { 125629a84457aed4c45bc900998b5e11c03023264208James Dong lev = -data * quant + (qp_const << 1); 125729a84457aed4c45bc900998b5e11c03023264208James Dong } 125829a84457aed4c45bc900998b5e11c03023264208James Dong lev >>= (q_bits + 1); 125929a84457aed4c45bc900998b5e11c03023264208James Dong if (lev) 126029a84457aed4c45bc900998b5e11c03023264208James Dong { 126129a84457aed4c45bc900998b5e11c03023264208James Dong if (data > 0) 126229a84457aed4c45bc900998b5e11c03023264208James Dong { 126329a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = lev; 126429a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = lev; 126529a84457aed4c45bc900998b5e11c03023264208James Dong } 126629a84457aed4c45bc900998b5e11c03023264208James Dong else 126729a84457aed4c45bc900998b5e11c03023264208James Dong { 126829a84457aed4c45bc900998b5e11c03023264208James Dong level[ncoeff] = -lev; 126929a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = -lev; 127029a84457aed4c45bc900998b5e11c03023264208James Dong } 127129a84457aed4c45bc900998b5e11c03023264208James Dong run[ncoeff++] = zero_run; 127229a84457aed4c45bc900998b5e11c03023264208James Dong zero_run = 0; 127329a84457aed4c45bc900998b5e11c03023264208James Dong } 127429a84457aed4c45bc900998b5e11c03023264208James Dong else 127529a84457aed4c45bc900998b5e11c03023264208James Dong { 127629a84457aed4c45bc900998b5e11c03023264208James Dong zero_run++; 127729a84457aed4c45bc900998b5e11c03023264208James Dong block[idx] = 0; 127829a84457aed4c45bc900998b5e11c03023264208James Dong } 127929a84457aed4c45bc900998b5e11c03023264208James Dong } 128029a84457aed4c45bc900998b5e11c03023264208James Dong return ncoeff; 128129a84457aed4c45bc900998b5e11c03023264208James Dong} 128229a84457aed4c45bc900998b5e11c03023264208James Dong 128329a84457aed4c45bc900998b5e11c03023264208James Dong 1284