159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ------------------------------------------------------------------ 259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Copyright (C) 1998-2009 PacketVideo 359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * you may not use this file except in compliance with the License. 659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * You may obtain a copy of the License at 759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * http://www.apache.org/licenses/LICENSE-2.0 959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 1059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Unless required by applicable law or agreed to in writing, software 1159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 1359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * express or implied. 1459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * See the License for the specific language governing permissions 1559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * and limitations under the License. 1659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * ------------------------------------------------------------------- 1759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */ 1859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4def.h" 1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h" 2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h" 2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "dct.h" 2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h" 2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : CodeMB_H263( ) */ 2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 8/15/2001 */ 2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Perform residue calc (only zero MV), DCT, H263 Quant/Dequant,*/ 2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* IDCT and motion compensation.Modified from FastCodeMB() */ 2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Input : */ 3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* video Video encoder data structure */ 3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* function Approximate DCT function, scaling and threshold */ 3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ncoefblck Array for last nonzero coeff for speedup in VlcEncode */ 3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* QP Combined offset from the origin to the current */ 3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* macroblock and QP for current MB. */ 3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Output : */ 3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* video->outputMB Quantized DCT coefficients. */ 3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* currVop->yChan,uChan,vChan Reconstructed pixels */ 3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* */ 3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 2/26/01 4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -modified threshold based on correlation coeff 0.75 only for mode H.263 4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -ncoefblck[] as input, to keep position of last non-zero coeff*/ 4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 8/10/01 4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -modified threshold based on correlation coeff 0.5 4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -used column threshold to speedup column DCT. 4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -used bitmap zigzag to speedup RunLevel(). */ 4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 5059f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS CodeMB_H263(VideoEncData *video, approxDCT *function, Int QP, Int ncoefblck[]) 5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int sad, k, CBP, mbnum = video->mbnum; 5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Short *output, *dataBlock; 5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar Mode = video->headerInfo.Mode[mbnum]; 5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *bitmapcol, *bitmaprow = video->bitmaprow; 5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt *bitmapzz ; 5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar shortHeader = video->vol[video->currLayer]->shortVideoHeader; 5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int dc_scaler = 8; 5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q); 6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong struct QPstruct QuantParam; 6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int dctMode, DctTh1; 6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ColTh; 6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int(*BlockQuantDequantH263)(Short *, Short *, struct QPstruct *, 6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar[], UChar *, UInt *, Int, Int, Int, UChar); 6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int(*BlockQuantDequantH263DC)(Short *, Short *, struct QPstruct *, 6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *, UInt *, Int, UChar); 6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT1x1)(Short *, UChar *, UChar *, Int); 6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT2x2)(Short *, UChar *, UChar *, Int); 6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT4x4)(Short *, UChar *, UChar *, Int); 7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT8x8)(Short *, UChar *, UChar *, Int); 7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* motion comp. related var. */ 7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vop *currVop = video->currVop; 7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncFrameIO *inputFrame = video->input; 7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ind_x = video->outputMB->mb_x; 7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ind_y = video->outputMB->mb_y; 7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int lx = currVop->pitch; 7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int width = currVop->width; 7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *rec, *input, *pred; 8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int offset = QP >> 5; /* QP is combined offset and QP */ 8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int offsetc = (offset >> 2) + (ind_x << 2); /* offset for chrom */ 8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*****************************/ 8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong OSCL_UNUSED_ARG(function); 8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong output = video->outputMB->block[0]; 8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP = 0; 8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QP = QP & 0x1F; 8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong// M4VENC_MEMSET(output,0,(sizeof(Short)<<6)*6); /* reset quantized coeff. to zero , 7/24/01*/ 9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QuantParam.QPx2 = QP << 1; 9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QuantParam.QP = QP; 9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QuantParam.QPdiv2 = QP >> 1; 9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QuantParam.QPx2plus = QuantParam.QPx2 + QuantParam.QPdiv2; 9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QuantParam.Addition = QP - 1 + (QP & 0x1); 9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1 = &Block1x1DCTIntra; 10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2 = &Block2x2DCT_AANIntra; 10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4 = &Block4x4DCT_AANIntra; 10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8 = &BlockDCT_AANIntra; 10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantH263 = &BlockQuantDequantH263Intra; 10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantH263DC = &BlockQuantDequantH263DCIntra; 10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (shortHeader) 10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = 8; 10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = cal_dc_scalerENC(QP, 1); /* luminance blocks */ 11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = (Int)(dc_scaler * 3);//*1.829 11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ColTh = ColThIntra[QP]; 11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1 = &Block1x1DCTwSub; 11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2 = &Block2x2DCT_AANwSub; 12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4 = &Block4x4DCT_AANwSub; 12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8 = &BlockDCT_AANwSub; 12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantH263 = &BlockQuantDequantH263Inter; 12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantH263DC = &BlockQuantDequantH263DCInter; 12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ColTh = ColThInter[QP]; 12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = (Int)(16 * QP); //9*QP; 12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->yChan + offset; 13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->yChan + offset; 13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 9); /* non-padded offset */ 13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dataBlock = video->dataBlock; 13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred = video->predictedMB; 13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (k = 0; k < 6; k++) 13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP <<= 1; 13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapcol = video->bitmapcol[k]; 14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapzz = video->bitmapzz[k]; /* 7/30/01 */ 14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k < 4) 14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = video->mot[mbnum][k+1].sad; 14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k&1) 14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec += 8; 14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input += 8; 14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (k == 2) 15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = ((width << 3) - 8); 15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input += dctMode; 15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = ((lx << 3) - 8); 15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec += dctMode; 15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k == 4) 16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->uChan + offsetc; 16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->uChan + offsetc; 16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 7); 16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong lx >>= 1; 16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong width >>= 1; 16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = getBlockSum(input, width); 16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (shortHeader) 17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = 8; 17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = cal_dc_scalerENC(QP, 2); /* chrominance blocks */ 17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = (Int)(dc_scaler * 3);//*1.829 17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = Sad8x8(input, pred, width); 17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->vChan + offsetc; 18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->vChan + offsetc; 18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 7); 18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = getBlockSum(input, width); 18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = Sad8x8(input, pred, width); 19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (sad < DctTh1 && !(shortHeader && intra)) /* all-zero */ 19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { /* For shortHeader intra block, DC value cannot be zero */ 19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 0; 19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= 0; 19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 0; 19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (sad < 18*QP/*(QP<<4)*/) /* DC-only */ 20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 1; 20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1(dataBlock, input, pred, width); 20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= (*BlockQuantDequantH263DC)(dataBlock, output, &QuantParam, 20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmaprow + k, bitmapzz, dc_scaler, shortHeader); 20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 1; 20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dataBlock[64] = ColTh; 21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (sad < 22*QP/*(QP<<4)+(QP<<1)*/) /* 2x2 DCT */ 21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 2; 21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2(dataBlock, input, pred, width); 21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 6; 21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (sad < (QP << 5)) /* 4x4 DCT */ 22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 4; 22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4(dataBlock, input, pred, width); 22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 26; 22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* Full-DCT */ 22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 8; 22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8(dataBlock, input, pred, width); 23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 64; 23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= (*BlockQuantDequantH263)(dataBlock, output, &QuantParam, 23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapcol, bitmaprow + k, bitmapzz, dctMode, k, dc_scaler, shortHeader); 23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockIDCTMotionComp(dataBlock, bitmapcol, bitmaprow[k], dctMode, rec, pred, (lx << 1) | intra); 23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong output += 64; 23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (!(k&1)) 23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred += 8; 24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred += 120; 24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->headerInfo.CBP[mbnum] = CBP; /* 5/18/2001 */ 24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT 25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : CodeMB_MPEG( ) */ 25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 8/15/2001 */ 25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Perform residue calc (only zero MV), DCT, MPEG Quant/Dequant,*/ 25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* IDCT and motion compensation.Modified from FastCodeMB() */ 25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Input : */ 25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* video Video encoder data structure */ 26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* function Approximate DCT function, scaling and threshold */ 26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ncoefblck Array for last nonzero coeff for speedup in VlcEncode */ 26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* QP Combined offset from the origin to the current */ 26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* macroblock and QP for current MB. */ 26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Output : */ 26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* video->outputMB Quantized DCT coefficients. */ 26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* currVop->yChan,uChan,vChan Reconstructed pixels */ 26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* */ 26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 2/26/01 27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -modified threshold based on correlation coeff 0.75 only for mode H.263 27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -ncoefblck[] as input, keep position of last non-zero coeff*/ 27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 8/10/01 27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -modified threshold based on correlation coeff 0.5 27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -used column threshold to speedup column DCT. 27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong -used bitmap zigzag to speedup RunLevel(). */ 27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 27959f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS CodeMB_MPEG(VideoEncData *video, approxDCT *function, Int QP, Int ncoefblck[]) 28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int sad, k, CBP, mbnum = video->mbnum; 28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Short *output, *dataBlock; 28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar Mode = video->headerInfo.Mode[mbnum]; 28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *bitmapcol, *bitmaprow = video->bitmaprow; 28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt *bitmapzz ; 28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int dc_scaler = 8; 28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vol *currVol = video->vol[video->currLayer]; 28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q); 28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *qmat; 29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int dctMode, DctTh1, DctTh2, DctTh3, DctTh4; 29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ColTh; 29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int(*BlockQuantDequantMPEG)(Short *, Short *, Int, Int *, 29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar [], UChar *, UInt *, Int, Int, Int); 29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int(*BlockQuantDequantMPEGDC)(Short *, Short *, Int, Int *, 29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar [], UChar *, UInt *, Int); 29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT1x1)(Short *, UChar *, UChar *, Int); 29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT2x2)(Short *, UChar *, UChar *, Int); 30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT4x4)(Short *, UChar *, UChar *, Int); 30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong void (*BlockDCT8x8)(Short *, UChar *, UChar *, Int); 30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* motion comp. related var. */ 30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vop *currVop = video->currVop; 30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncFrameIO *inputFrame = video->input; 30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ind_x = video->outputMB->mb_x; 30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int ind_y = video->outputMB->mb_y; 30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int lx = currVop->pitch; 30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int width = currVop->width; 31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *rec, *input, *pred; 31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int offset = QP >> 5; 31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int offsetc = (offset >> 2) + (ind_x << 2); /* offset for chrom */ 31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*****************************/ 31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong OSCL_UNUSED_ARG(function); 31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong output = video->outputMB->block[0]; 31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP = 0; 31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong QP = QP & 0x1F; 32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong// M4VENC_MEMSET(output,0,(sizeof(Short)<<6)*6); /* reset quantized coeff. to zero , 7/24/01*/ 32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1 = &Block1x1DCTIntra; 32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2 = &Block2x2DCT_AANIntra; 32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4 = &Block4x4DCT_AANIntra; 32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8 = &BlockDCT_AANIntra; 32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantMPEG = &BlockQuantDequantMPEGIntra; 33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantMPEGDC = &BlockQuantDequantMPEGDCIntra; 33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = cal_dc_scalerENC(QP, 1); /* luminance blocks */ 33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong qmat = currVol->iqmat; 33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = (Int)(3 * dc_scaler);//2*dc_scaler); 33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh2 = (Int)((1.25 * QP - 1) * qmat[1] * 0.45);//0.567);//0.567); 33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh3 = (Int)((1.25 * QP - 1) * qmat[2] * 0.55);//1.162); /* 8/2/2001 */ 33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh4 = (Int)((1.25 * QP - 1) * qmat[32] * 0.8);//1.7583);//0.7942); 33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ColTh = ColThIntra[QP]; 33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1 = &Block1x1DCTwSub; 34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2 = &Block2x2DCT_AANwSub; 34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4 = &Block4x4DCT_AANwSub; 34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8 = &BlockDCT_AANwSub; 34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantMPEG = &BlockQuantDequantMPEGInter; 34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockQuantDequantMPEGDC = &BlockQuantDequantMPEGDCInter; 34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong qmat = currVol->niqmat; 34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = (Int)(((QP << 1) - 0.5) * qmat[0] * 0.4);//0.2286);//0.3062); 35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh2 = (Int)(((QP << 1) - 0.5) * qmat[1] * 0.45);//0.567);//0.4); 35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh3 = (Int)(((QP << 1) - 0.5) * qmat[2] * 0.55);//1.162); /* 8/2/2001 */ 35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh4 = (Int)(((QP << 1) - 0.5) * qmat[32] * 0.8);//1.7583);//0.7942); 35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ColTh = ColThInter[QP]; 35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong }// get qmat, DctTh1, DctTh2, DctTh3 35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->yChan + offset; 35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->yChan + offset; 35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 9); /* non-padded offset */ 35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dataBlock = video->dataBlock; 36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred = video->predictedMB; 36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (k = 0; k < 6; k++) 36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP <<= 1; 36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapcol = video->bitmapcol[k]; 36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapzz = video->bitmapzz[k]; /* 8/2/01 */ 36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k < 4) 36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong {//Y block 37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = video->mot[mbnum][k+1].sad; 37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k&1) 37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec += 8; 37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input += 8; 37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (k == 2) 37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = ((width << 3) - 8); 37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input += dctMode; 38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = ((lx << 3) - 8); 38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec += dctMode; 38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong {// U, V block 38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (k == 4) 38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->uChan + offsetc; 38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->uChan + offsetc; 39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 7); 39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong lx >>= 1; 39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong width >>= 1; 39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dc_scaler = cal_dc_scalerENC(QP, 2); /* luminance blocks */ 39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong DctTh1 = dc_scaler * 3; 39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = getBlockSum(input, width); 39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = Sad8x8(input, pred, width); 40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rec = currVop->vChan + offsetc; 40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong input = inputFrame->vChan + offsetc; 40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (lx != width) input -= (ind_y << 7); 40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (intra) 40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = getBlockSum(input, width); 40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = Sad8x8(input, pred, width); 41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (sad < DctTh1) /* all-zero */ 41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 0; 41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= 0; 41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 0; 41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (sad < DctTh2) /* DC-only */ 42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 1; 42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT1x1(dataBlock, input, pred, width); 42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= (*BlockQuantDequantMPEGDC)(dataBlock, output, QP, qmat, 42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapcol, bitmaprow + k, bitmapzz, dc_scaler); 42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 1; 42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dataBlock[64] = ColTh; 43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (sad < DctTh3) /* 2x2-DCT */ 43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 2; 43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT2x2(dataBlock, input, pred, width); 43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 6; 43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (sad < DctTh4) /* 4x4 DCT */ 44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 4; 44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT4x4(dataBlock, input, pred, width); 44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 26; 44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* full-DCT */ 44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 8; 44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockDCT8x8(dataBlock, input, pred, width); 44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ncoefblck[k] = 64; 45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong CBP |= (*BlockQuantDequantMPEG)(dataBlock, output, QP, qmat, 45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bitmapcol, bitmaprow + k, bitmapzz, dctMode, k, dc_scaler); // 45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong dctMode = 8; /* for mismatch handle */ 45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong BlockIDCTMotionComp(dataBlock, bitmapcol, bitmaprow[k], dctMode, rec, pred, (lx << 1) | (intra)); 45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong output += 64; 45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (!(k&1)) 46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred += 8; 46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pred += 120; 46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->headerInfo.CBP[mbnum] = CBP; /* 5/18/2001 */ 47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : getBlockSAV( ) */ 47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 8/10/2000 */ 47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Get SAV for one block */ 47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : block[64] contain one block data */ 48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* can be written in MMX or SSE, 2/22/2001 */ 48459f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt getBlockSAV(Short block[]) 48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int i, val, sav = 0; 48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong i = 8; 48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while (i--) 49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong val = *block++; 51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (val > 0) sav += val; 51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else sav -= val; 51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return sav; 51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : Sad8x8( ) */ 52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 8/10/2000 */ 52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Find SAD between prev block and current block */ 52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : Previous and current frame block pointers, and frame width */ 52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 8/15/01, - do 4 pixel at a time assuming 32 bit register */ 52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 53059f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt Sad8x8(UChar *cur, UChar *prev, Int width) 53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 53259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *end = cur + (width << 3); 53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int sad = 0; 53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *curInt = (Int*) cur; 53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *prevInt = (Int*) prev; 53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int cur1, cur2, prev1, prev2; 53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt mask, sgn_msk = 0x80808080; 53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int sum2 = 0, sum4 = 0; 53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int tmp; 54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong do 54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong mask = ~(0xFF00); 54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = curInt[1]; /* load cur[4..7] */ 54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur2 = curInt[0]; 54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curInt += (width >> 2); /* load cur[0..3] and +=lx */ 54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev1 = prevInt[1]; 54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev2 = prevInt[0]; 54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prevInt += 4; 54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = prev2 ^ cur2; 55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur2 = prev2 - cur2; 55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = tmp ^ cur2; /* (^)^(-) last bit is one if carry */ 55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = sgn_msk & ((UInt)tmp >> 1); /* check the sign of each byte */ 55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (cur2 < 0) tmp = tmp | 0x80000000; /* corcurt sign of first byte */ 55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = (tmp << 8) - tmp; /* carry borrowed bytes are marked with 0x1FE */ 55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur2 = cur2 + (tmp >> 7); /* negative bytes is added with 0xFF, -1 */ 55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur2 = cur2 ^(tmp >> 7); /* take absolute by inverting bits (EOR) */ 55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = prev1 ^ cur1; 56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = prev1 - cur1; 56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = tmp ^ cur1; /* (^)^(-) last bit is one if carry */ 56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = sgn_msk & ((UInt)tmp >> 1); /* check the sign of each byte */ 56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (cur1 < 0) tmp = tmp | 0x80000000; /* corcurt sign of first byte */ 56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong tmp = (tmp << 8) - tmp; /* carry borrowed bytes are marked with 0x1FE */ 56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = cur1 + (tmp >> 7); /* negative bytes is added with 0xFF, -1 */ 56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = cur1 ^(tmp >> 7); /* take absolute by inverting bits (EOR) */ 56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum4 = sum4 + cur1; 56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = cur1 & (mask << 8); /* mask first and third bytes */ 57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum2 = sum2 + ((UInt)cur1 >> 8); 57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum4 = sum4 + cur2; 57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur2 = cur2 & (mask << 8); /* mask first and third bytes */ 57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum2 = sum2 + ((UInt)cur2 >> 8); 57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while ((UInt)curInt < (UInt)end); 57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = sum4 - (sum2 << 8); /* get even-sum */ 57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = cur1 + sum2; /* add 16 bit even-sum and odd-sum*/ 57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong cur1 = cur1 + (cur1 << 16); /* add upper and lower 16 bit sum */ 58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = ((UInt)cur1 >> 16); /* take upper 16 bit */ 58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return sad; 58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : getBlockSum( ) */ 58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 8/10/2000 */ 58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Find summation of value within a block. */ 58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : Pointer to current block in a frame and frame width */ 58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 8/15/01, - SIMD 4 pixels at a time */ 59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 59459f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt getBlockSum(UChar *cur, Int width) 59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int sad = 0, sum4 = 0, sum2 = 0; 59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UChar *end = cur + (width << 3); 59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *curInt = (Int*)cur; 59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong UInt mask = ~(0xFF00); 60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int load1, load2; 60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong do 60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load1 = curInt[1]; 60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load2 = curInt[0]; 60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curInt += (width >> 2); 60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum4 += load1; 60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load1 = load1 & (mask << 8); /* even bytes */ 60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum2 += ((UInt)load1 >> 8); /* sum even bytes, 16 bit */ 61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum4 += load2; 61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load2 = load2 & (mask << 8); /* even bytes */ 61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sum2 += ((UInt)load2 >> 8); /* sum even bytes, 16 bit */ 61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while ((UInt)curInt < (UInt)end); 61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load1 = sum4 - (sum2 << 8); /* get even-sum */ 61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load1 = load1 + sum2; /* add 16 bit even-sum and odd-sum*/ 61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong load1 = load1 + (load1 << 16); /* add upper and lower 16 bit sum */ 61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong sad = ((UInt)load1 >> 16); /* take upper 16 bit */ 61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return sad; 62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 623