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 DongAVCEnc_Status EncodeIntraPCM(AVCEncObject *encvid) 2129a84457aed4c45bc900998b5e11c03023264208James Dong{ 2229a84457aed4c45bc900998b5e11c03023264208James Dong AVCEnc_Status status = AVCENC_SUCCESS; 2329a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 2429a84457aed4c45bc900998b5e11c03023264208James Dong AVCFrameIO *currInput = encvid->currInput; 2529a84457aed4c45bc900998b5e11c03023264208James Dong AVCEncBitstream *stream = encvid->bitstream; 2629a84457aed4c45bc900998b5e11c03023264208James Dong int x_position = (video->mb_x << 4); 2729a84457aed4c45bc900998b5e11c03023264208James Dong int y_position = (video->mb_y << 4); 2829a84457aed4c45bc900998b5e11c03023264208James Dong int orgPitch = currInput->pitch; 2929a84457aed4c45bc900998b5e11c03023264208James Dong int offset1 = y_position * orgPitch + x_position; 3029a84457aed4c45bc900998b5e11c03023264208James Dong int i, j; 3129a84457aed4c45bc900998b5e11c03023264208James Dong int offset; 3229a84457aed4c45bc900998b5e11c03023264208James Dong uint8 *pDst, *pSrc; 3329a84457aed4c45bc900998b5e11c03023264208James Dong uint code; 3429a84457aed4c45bc900998b5e11c03023264208James Dong 3529a84457aed4c45bc900998b5e11c03023264208James Dong ue_v(stream, 25); 3629a84457aed4c45bc900998b5e11c03023264208James Dong 3729a84457aed4c45bc900998b5e11c03023264208James Dong i = stream->bit_left & 0x7; 3829a84457aed4c45bc900998b5e11c03023264208James Dong if (i) /* not byte-aligned */ 3929a84457aed4c45bc900998b5e11c03023264208James Dong { 4029a84457aed4c45bc900998b5e11c03023264208James Dong BitstreamWriteBits(stream, 0, i); 4129a84457aed4c45bc900998b5e11c03023264208James Dong } 4229a84457aed4c45bc900998b5e11c03023264208James Dong 4329a84457aed4c45bc900998b5e11c03023264208James Dong pSrc = currInput->YCbCr[0] + offset1; 4429a84457aed4c45bc900998b5e11c03023264208James Dong pDst = video->currPic->Sl + offset1; 4529a84457aed4c45bc900998b5e11c03023264208James Dong offset = video->PicWidthInSamplesL - 16; 4629a84457aed4c45bc900998b5e11c03023264208James Dong 4729a84457aed4c45bc900998b5e11c03023264208James Dong /* at this point bitstream is byte-aligned */ 4829a84457aed4c45bc900998b5e11c03023264208James Dong j = 16; 4929a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 5029a84457aed4c45bc900998b5e11c03023264208James Dong { 5129a84457aed4c45bc900998b5e11c03023264208James Dong#if (WORD_SIZE==32) 5229a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 4; i++) 5329a84457aed4c45bc900998b5e11c03023264208James Dong { 5429a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 5529a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 4; 5629a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 5729a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 4; 5829a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 32, code); 5929a84457aed4c45bc900998b5e11c03023264208James Dong } 6029a84457aed4c45bc900998b5e11c03023264208James Dong#else 6129a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 8; i++) 6229a84457aed4c45bc900998b5e11c03023264208James Dong { 6329a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 6429a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 2; 6529a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 6629a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 2; 6729a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 16, code); 6829a84457aed4c45bc900998b5e11c03023264208James Dong } 6929a84457aed4c45bc900998b5e11c03023264208James Dong#endif 7029a84457aed4c45bc900998b5e11c03023264208James Dong pDst += offset; 7129a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += offset; 7229a84457aed4c45bc900998b5e11c03023264208James Dong j--; 7329a84457aed4c45bc900998b5e11c03023264208James Dong } 7429a84457aed4c45bc900998b5e11c03023264208James Dong if (status != AVCENC_SUCCESS) /* check only once per line */ 7529a84457aed4c45bc900998b5e11c03023264208James Dong return status; 7629a84457aed4c45bc900998b5e11c03023264208James Dong 7729a84457aed4c45bc900998b5e11c03023264208James Dong pDst = video->currPic->Scb + ((offset1 + x_position) >> 2); 7829a84457aed4c45bc900998b5e11c03023264208James Dong pSrc = currInput->YCbCr[1] + ((offset1 + x_position) >> 2); 7929a84457aed4c45bc900998b5e11c03023264208James Dong offset >>= 1; 8029a84457aed4c45bc900998b5e11c03023264208James Dong 8129a84457aed4c45bc900998b5e11c03023264208James Dong j = 8; 8229a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 8329a84457aed4c45bc900998b5e11c03023264208James Dong { 8429a84457aed4c45bc900998b5e11c03023264208James Dong#if (WORD_SIZE==32) 8529a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 2; i++) 8629a84457aed4c45bc900998b5e11c03023264208James Dong { 8729a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 8829a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 4; 8929a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 9029a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 4; 9129a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 32, code); 9229a84457aed4c45bc900998b5e11c03023264208James Dong } 9329a84457aed4c45bc900998b5e11c03023264208James Dong#else 9429a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 4; i++) 9529a84457aed4c45bc900998b5e11c03023264208James Dong { 9629a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 9729a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 2; 9829a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 9929a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 2; 10029a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 16, code); 10129a84457aed4c45bc900998b5e11c03023264208James Dong } 10229a84457aed4c45bc900998b5e11c03023264208James Dong#endif 10329a84457aed4c45bc900998b5e11c03023264208James Dong pDst += offset; 10429a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += offset; 10529a84457aed4c45bc900998b5e11c03023264208James Dong j--; 10629a84457aed4c45bc900998b5e11c03023264208James Dong } 10729a84457aed4c45bc900998b5e11c03023264208James Dong 10829a84457aed4c45bc900998b5e11c03023264208James Dong if (status != AVCENC_SUCCESS) /* check only once per line */ 10929a84457aed4c45bc900998b5e11c03023264208James Dong return status; 11029a84457aed4c45bc900998b5e11c03023264208James Dong 11129a84457aed4c45bc900998b5e11c03023264208James Dong pDst = video->currPic->Scr + ((offset1 + x_position) >> 2); 11229a84457aed4c45bc900998b5e11c03023264208James Dong pSrc = currInput->YCbCr[2] + ((offset1 + x_position) >> 2); 11329a84457aed4c45bc900998b5e11c03023264208James Dong 11429a84457aed4c45bc900998b5e11c03023264208James Dong j = 8; 11529a84457aed4c45bc900998b5e11c03023264208James Dong while (j > 0) 11629a84457aed4c45bc900998b5e11c03023264208James Dong { 11729a84457aed4c45bc900998b5e11c03023264208James Dong#if (WORD_SIZE==32) 11829a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 2; i++) 11929a84457aed4c45bc900998b5e11c03023264208James Dong { 12029a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 12129a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 4; 12229a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 12329a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 4; 12429a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 32, code); 12529a84457aed4c45bc900998b5e11c03023264208James Dong } 12629a84457aed4c45bc900998b5e11c03023264208James Dong#else 12729a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 4; i++) 12829a84457aed4c45bc900998b5e11c03023264208James Dong { 12929a84457aed4c45bc900998b5e11c03023264208James Dong code = *((uint*)pSrc); 13029a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += 2; 13129a84457aed4c45bc900998b5e11c03023264208James Dong *((uint*)pDst) = code; 13229a84457aed4c45bc900998b5e11c03023264208James Dong pDst += 2; 13329a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 16, code); 13429a84457aed4c45bc900998b5e11c03023264208James Dong } 13529a84457aed4c45bc900998b5e11c03023264208James Dong#endif 13629a84457aed4c45bc900998b5e11c03023264208James Dong pDst += offset; 13729a84457aed4c45bc900998b5e11c03023264208James Dong pSrc += offset; 13829a84457aed4c45bc900998b5e11c03023264208James Dong j--; 13929a84457aed4c45bc900998b5e11c03023264208James Dong } 14029a84457aed4c45bc900998b5e11c03023264208James Dong 14129a84457aed4c45bc900998b5e11c03023264208James Dong return status; 14229a84457aed4c45bc900998b5e11c03023264208James Dong} 14329a84457aed4c45bc900998b5e11c03023264208James Dong 14429a84457aed4c45bc900998b5e11c03023264208James Dong 14529a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status enc_residual_block(AVCEncObject *encvid, AVCResidualType type, int cindx, AVCMacroblock *currMB) 14629a84457aed4c45bc900998b5e11c03023264208James Dong{ 14729a84457aed4c45bc900998b5e11c03023264208James Dong AVCEnc_Status status = AVCENC_SUCCESS; 14829a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 14929a84457aed4c45bc900998b5e11c03023264208James Dong int i, maxNumCoeff, nC; 15029a84457aed4c45bc900998b5e11c03023264208James Dong int cdc = 0, cac = 0; 15129a84457aed4c45bc900998b5e11c03023264208James Dong int TrailingOnes; 15229a84457aed4c45bc900998b5e11c03023264208James Dong AVCEncBitstream *stream = encvid->bitstream; 15329a84457aed4c45bc900998b5e11c03023264208James Dong uint trailing_ones_sign_flag; 15429a84457aed4c45bc900998b5e11c03023264208James Dong int zerosLeft; 15529a84457aed4c45bc900998b5e11c03023264208James Dong int *level, *run; 15629a84457aed4c45bc900998b5e11c03023264208James Dong int TotalCoeff; 15729a84457aed4c45bc900998b5e11c03023264208James Dong const static int incVlc[] = {0, 3, 6, 12, 24, 48, 32768}; // maximum vlc = 6 15829a84457aed4c45bc900998b5e11c03023264208James Dong int escape, numPrefix, sufmask, suffix, shift, sign, value, absvalue, vlcnum, level_two_or_higher; 15929a84457aed4c45bc900998b5e11c03023264208James Dong int bindx = blkIdx2blkXY[cindx>>2][cindx&3] ; // raster scan index 16029a84457aed4c45bc900998b5e11c03023264208James Dong 16129a84457aed4c45bc900998b5e11c03023264208James Dong switch (type) 16229a84457aed4c45bc900998b5e11c03023264208James Dong { 16329a84457aed4c45bc900998b5e11c03023264208James Dong case AVC_Luma: 16429a84457aed4c45bc900998b5e11c03023264208James Dong maxNumCoeff = 16; 16529a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[cindx]; 16629a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[cindx]; 16729a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = currMB->nz_coeff[bindx]; 16829a84457aed4c45bc900998b5e11c03023264208James Dong break; 16929a84457aed4c45bc900998b5e11c03023264208James Dong case AVC_Intra16DC: 17029a84457aed4c45bc900998b5e11c03023264208James Dong maxNumCoeff = 16; 17129a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->leveldc; 17229a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->rundc; 17329a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = cindx; /* special case */ 17429a84457aed4c45bc900998b5e11c03023264208James Dong bindx = 0; 17529a84457aed4c45bc900998b5e11c03023264208James Dong cindx = 0; 17629a84457aed4c45bc900998b5e11c03023264208James Dong break; 17729a84457aed4c45bc900998b5e11c03023264208James Dong case AVC_Intra16AC: 17829a84457aed4c45bc900998b5e11c03023264208James Dong maxNumCoeff = 15; 17929a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[cindx]; 18029a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[cindx]; 18129a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = currMB->nz_coeff[bindx]; 18229a84457aed4c45bc900998b5e11c03023264208James Dong break; 18329a84457aed4c45bc900998b5e11c03023264208James Dong case AVC_ChromaDC: /* how to differentiate Cb from Cr */ 18429a84457aed4c45bc900998b5e11c03023264208James Dong maxNumCoeff = 4; 18529a84457aed4c45bc900998b5e11c03023264208James Dong cdc = 1; 18629a84457aed4c45bc900998b5e11c03023264208James Dong if (cindx >= 8) 18729a84457aed4c45bc900998b5e11c03023264208James Dong { 18829a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->levelcdc + 4; 18929a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->runcdc + 4; 19029a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = cindx - 8; /* special case */ 19129a84457aed4c45bc900998b5e11c03023264208James Dong } 19229a84457aed4c45bc900998b5e11c03023264208James Dong else 19329a84457aed4c45bc900998b5e11c03023264208James Dong { 19429a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->levelcdc; 19529a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->runcdc; 19629a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = cindx; /* special case */ 19729a84457aed4c45bc900998b5e11c03023264208James Dong } 19829a84457aed4c45bc900998b5e11c03023264208James Dong break; 19929a84457aed4c45bc900998b5e11c03023264208James Dong case AVC_ChromaAC: 20029a84457aed4c45bc900998b5e11c03023264208James Dong maxNumCoeff = 15; 20129a84457aed4c45bc900998b5e11c03023264208James Dong cac = 1; 20229a84457aed4c45bc900998b5e11c03023264208James Dong level = encvid->level[cindx]; 20329a84457aed4c45bc900998b5e11c03023264208James Dong run = encvid->run[cindx]; 20429a84457aed4c45bc900998b5e11c03023264208James Dong cindx -= 16; 20529a84457aed4c45bc900998b5e11c03023264208James Dong bindx = 16 + blkIdx2blkXY[cindx>>2][cindx&3]; 20629a84457aed4c45bc900998b5e11c03023264208James Dong cindx += 16; 20729a84457aed4c45bc900998b5e11c03023264208James Dong TotalCoeff = currMB->nz_coeff[bindx]; 20829a84457aed4c45bc900998b5e11c03023264208James Dong break; 20929a84457aed4c45bc900998b5e11c03023264208James Dong default: 21029a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_FAIL; 21129a84457aed4c45bc900998b5e11c03023264208James Dong } 21229a84457aed4c45bc900998b5e11c03023264208James Dong 21329a84457aed4c45bc900998b5e11c03023264208James Dong 21429a84457aed4c45bc900998b5e11c03023264208James Dong /* find TrailingOnes */ 21529a84457aed4c45bc900998b5e11c03023264208James Dong TrailingOnes = 0; 21629a84457aed4c45bc900998b5e11c03023264208James Dong zerosLeft = 0; 21729a84457aed4c45bc900998b5e11c03023264208James Dong i = TotalCoeff - 1; 21829a84457aed4c45bc900998b5e11c03023264208James Dong nC = 1; 21929a84457aed4c45bc900998b5e11c03023264208James Dong while (i >= 0) 22029a84457aed4c45bc900998b5e11c03023264208James Dong { 22129a84457aed4c45bc900998b5e11c03023264208James Dong zerosLeft += run[i]; 22229a84457aed4c45bc900998b5e11c03023264208James Dong if (nC && (level[i] == 1 || level[i] == -1)) 22329a84457aed4c45bc900998b5e11c03023264208James Dong { 22429a84457aed4c45bc900998b5e11c03023264208James Dong TrailingOnes++; 22529a84457aed4c45bc900998b5e11c03023264208James Dong } 22629a84457aed4c45bc900998b5e11c03023264208James Dong else 22729a84457aed4c45bc900998b5e11c03023264208James Dong { 22829a84457aed4c45bc900998b5e11c03023264208James Dong nC = 0; 22929a84457aed4c45bc900998b5e11c03023264208James Dong } 23029a84457aed4c45bc900998b5e11c03023264208James Dong i--; 23129a84457aed4c45bc900998b5e11c03023264208James Dong } 23229a84457aed4c45bc900998b5e11c03023264208James Dong if (TrailingOnes > 3) 23329a84457aed4c45bc900998b5e11c03023264208James Dong { 23429a84457aed4c45bc900998b5e11c03023264208James Dong TrailingOnes = 3; /* clip it */ 23529a84457aed4c45bc900998b5e11c03023264208James Dong } 23629a84457aed4c45bc900998b5e11c03023264208James Dong 23729a84457aed4c45bc900998b5e11c03023264208James Dong if (!cdc) 23829a84457aed4c45bc900998b5e11c03023264208James Dong { 23929a84457aed4c45bc900998b5e11c03023264208James Dong if (!cac) /* not chroma */ 24029a84457aed4c45bc900998b5e11c03023264208James Dong { 24129a84457aed4c45bc900998b5e11c03023264208James Dong nC = predict_nnz(video, bindx & 3, bindx >> 2); 24229a84457aed4c45bc900998b5e11c03023264208James Dong } 24329a84457aed4c45bc900998b5e11c03023264208James Dong else /* chroma ac but not chroma dc */ 24429a84457aed4c45bc900998b5e11c03023264208James Dong { 24529a84457aed4c45bc900998b5e11c03023264208James Dong nC = predict_nnz_chroma(video, bindx & 3, bindx >> 2); 24629a84457aed4c45bc900998b5e11c03023264208James Dong } 24729a84457aed4c45bc900998b5e11c03023264208James Dong 24829a84457aed4c45bc900998b5e11c03023264208James Dong status = ce_TotalCoeffTrailingOnes(stream, TrailingOnes, TotalCoeff, nC); 24929a84457aed4c45bc900998b5e11c03023264208James Dong } 25029a84457aed4c45bc900998b5e11c03023264208James Dong else 25129a84457aed4c45bc900998b5e11c03023264208James Dong { 25229a84457aed4c45bc900998b5e11c03023264208James Dong nC = -1; /* Chroma DC level */ 25329a84457aed4c45bc900998b5e11c03023264208James Dong status = ce_TotalCoeffTrailingOnesChromaDC(stream, TrailingOnes, TotalCoeff); 25429a84457aed4c45bc900998b5e11c03023264208James Dong } 25529a84457aed4c45bc900998b5e11c03023264208James Dong 25629a84457aed4c45bc900998b5e11c03023264208James Dong /* This part is done quite differently in ReadCoef4x4_CAVLC() */ 25729a84457aed4c45bc900998b5e11c03023264208James Dong if (TotalCoeff > 0) 25829a84457aed4c45bc900998b5e11c03023264208James Dong { 25929a84457aed4c45bc900998b5e11c03023264208James Dong 26029a84457aed4c45bc900998b5e11c03023264208James Dong i = TotalCoeff - 1; 26129a84457aed4c45bc900998b5e11c03023264208James Dong 26229a84457aed4c45bc900998b5e11c03023264208James Dong if (TrailingOnes) /* keep reading the sign of those trailing ones */ 26329a84457aed4c45bc900998b5e11c03023264208James Dong { 26429a84457aed4c45bc900998b5e11c03023264208James Dong nC = TrailingOnes; 26529a84457aed4c45bc900998b5e11c03023264208James Dong trailing_ones_sign_flag = 0; 26629a84457aed4c45bc900998b5e11c03023264208James Dong while (nC) 26729a84457aed4c45bc900998b5e11c03023264208James Dong { 26829a84457aed4c45bc900998b5e11c03023264208James Dong trailing_ones_sign_flag <<= 1; 26929a84457aed4c45bc900998b5e11c03023264208James Dong trailing_ones_sign_flag |= ((uint32)level[i--] >> 31); /* 0 or positive, 1 for negative */ 27029a84457aed4c45bc900998b5e11c03023264208James Dong nC--; 27129a84457aed4c45bc900998b5e11c03023264208James Dong } 27229a84457aed4c45bc900998b5e11c03023264208James Dong 27329a84457aed4c45bc900998b5e11c03023264208James Dong /* instead of writing one bit at a time, read the whole thing at once */ 27429a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, TrailingOnes, trailing_ones_sign_flag); 27529a84457aed4c45bc900998b5e11c03023264208James Dong } 27629a84457aed4c45bc900998b5e11c03023264208James Dong 27729a84457aed4c45bc900998b5e11c03023264208James Dong level_two_or_higher = 1; 27829a84457aed4c45bc900998b5e11c03023264208James Dong if (TotalCoeff > 3 && TrailingOnes == 3) 27929a84457aed4c45bc900998b5e11c03023264208James Dong { 28029a84457aed4c45bc900998b5e11c03023264208James Dong level_two_or_higher = 0; 28129a84457aed4c45bc900998b5e11c03023264208James Dong } 28229a84457aed4c45bc900998b5e11c03023264208James Dong 28329a84457aed4c45bc900998b5e11c03023264208James Dong if (TotalCoeff > 10 && TrailingOnes < 3) 28429a84457aed4c45bc900998b5e11c03023264208James Dong { 28529a84457aed4c45bc900998b5e11c03023264208James Dong vlcnum = 1; 28629a84457aed4c45bc900998b5e11c03023264208James Dong } 28729a84457aed4c45bc900998b5e11c03023264208James Dong else 28829a84457aed4c45bc900998b5e11c03023264208James Dong { 28929a84457aed4c45bc900998b5e11c03023264208James Dong vlcnum = 0; 29029a84457aed4c45bc900998b5e11c03023264208James Dong } 29129a84457aed4c45bc900998b5e11c03023264208James Dong 29229a84457aed4c45bc900998b5e11c03023264208James Dong /* then do this TotalCoeff-TrailingOnes times */ 29329a84457aed4c45bc900998b5e11c03023264208James Dong for (i = TotalCoeff - TrailingOnes - 1; i >= 0; i--) 29429a84457aed4c45bc900998b5e11c03023264208James Dong { 29529a84457aed4c45bc900998b5e11c03023264208James Dong value = level[i]; 29629a84457aed4c45bc900998b5e11c03023264208James Dong absvalue = (value >= 0) ? value : -value; 29729a84457aed4c45bc900998b5e11c03023264208James Dong 29829a84457aed4c45bc900998b5e11c03023264208James Dong if (level_two_or_higher) 29929a84457aed4c45bc900998b5e11c03023264208James Dong { 30029a84457aed4c45bc900998b5e11c03023264208James Dong if (value > 0) value--; 30129a84457aed4c45bc900998b5e11c03023264208James Dong else value++; 30229a84457aed4c45bc900998b5e11c03023264208James Dong level_two_or_higher = 0; 30329a84457aed4c45bc900998b5e11c03023264208James Dong } 30429a84457aed4c45bc900998b5e11c03023264208James Dong 30529a84457aed4c45bc900998b5e11c03023264208James Dong if (value >= 0) 30629a84457aed4c45bc900998b5e11c03023264208James Dong { 30729a84457aed4c45bc900998b5e11c03023264208James Dong sign = 0; 30829a84457aed4c45bc900998b5e11c03023264208James Dong } 30929a84457aed4c45bc900998b5e11c03023264208James Dong else 31029a84457aed4c45bc900998b5e11c03023264208James Dong { 31129a84457aed4c45bc900998b5e11c03023264208James Dong sign = 1; 31229a84457aed4c45bc900998b5e11c03023264208James Dong value = -value; 31329a84457aed4c45bc900998b5e11c03023264208James Dong } 31429a84457aed4c45bc900998b5e11c03023264208James Dong 31529a84457aed4c45bc900998b5e11c03023264208James Dong if (vlcnum == 0) // VLC1 31629a84457aed4c45bc900998b5e11c03023264208James Dong { 31729a84457aed4c45bc900998b5e11c03023264208James Dong if (value < 8) 31829a84457aed4c45bc900998b5e11c03023264208James Dong { 31929a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, value * 2 + sign - 1, 1); 32029a84457aed4c45bc900998b5e11c03023264208James Dong } 32129a84457aed4c45bc900998b5e11c03023264208James Dong else if (value < 8 + 8) 32229a84457aed4c45bc900998b5e11c03023264208James Dong { 32329a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 14 + 1 + 4, (1 << 4) | ((value - 8) << 1) | sign); 32429a84457aed4c45bc900998b5e11c03023264208James Dong } 32529a84457aed4c45bc900998b5e11c03023264208James Dong else 32629a84457aed4c45bc900998b5e11c03023264208James Dong { 32729a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 14 + 2 + 12, (1 << 12) | ((value - 16) << 1) | sign) ; 32829a84457aed4c45bc900998b5e11c03023264208James Dong } 32929a84457aed4c45bc900998b5e11c03023264208James Dong } 33029a84457aed4c45bc900998b5e11c03023264208James Dong else // VLCN 33129a84457aed4c45bc900998b5e11c03023264208James Dong { 33229a84457aed4c45bc900998b5e11c03023264208James Dong shift = vlcnum - 1; 33329a84457aed4c45bc900998b5e11c03023264208James Dong escape = (15 << shift) + 1; 33429a84457aed4c45bc900998b5e11c03023264208James Dong numPrefix = (value - 1) >> shift; 33529a84457aed4c45bc900998b5e11c03023264208James Dong sufmask = ~((0xffffffff) << shift); 33629a84457aed4c45bc900998b5e11c03023264208James Dong suffix = (value - 1) & sufmask; 33729a84457aed4c45bc900998b5e11c03023264208James Dong if (value < escape) 33829a84457aed4c45bc900998b5e11c03023264208James Dong { 33929a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, numPrefix + vlcnum + 1, (1 << (shift + 1)) | (suffix << 1) | sign); 34029a84457aed4c45bc900998b5e11c03023264208James Dong } 34129a84457aed4c45bc900998b5e11c03023264208James Dong else 34229a84457aed4c45bc900998b5e11c03023264208James Dong { 34329a84457aed4c45bc900998b5e11c03023264208James Dong status = BitstreamWriteBits(stream, 28, (1 << 12) | ((value - escape) << 1) | sign); 34429a84457aed4c45bc900998b5e11c03023264208James Dong } 34529a84457aed4c45bc900998b5e11c03023264208James Dong 34629a84457aed4c45bc900998b5e11c03023264208James Dong } 34729a84457aed4c45bc900998b5e11c03023264208James Dong 34829a84457aed4c45bc900998b5e11c03023264208James Dong if (absvalue > incVlc[vlcnum]) 34929a84457aed4c45bc900998b5e11c03023264208James Dong vlcnum++; 35029a84457aed4c45bc900998b5e11c03023264208James Dong 35129a84457aed4c45bc900998b5e11c03023264208James Dong if (i == TotalCoeff - TrailingOnes - 1 && absvalue > 3) 35229a84457aed4c45bc900998b5e11c03023264208James Dong vlcnum = 2; 35329a84457aed4c45bc900998b5e11c03023264208James Dong } 35429a84457aed4c45bc900998b5e11c03023264208James Dong 35529a84457aed4c45bc900998b5e11c03023264208James Dong if (status != AVCENC_SUCCESS) /* occasionally check the bitstream */ 35629a84457aed4c45bc900998b5e11c03023264208James Dong { 35729a84457aed4c45bc900998b5e11c03023264208James Dong return status; 35829a84457aed4c45bc900998b5e11c03023264208James Dong } 35929a84457aed4c45bc900998b5e11c03023264208James Dong if (TotalCoeff < maxNumCoeff) 36029a84457aed4c45bc900998b5e11c03023264208James Dong { 36129a84457aed4c45bc900998b5e11c03023264208James Dong if (!cdc) 36229a84457aed4c45bc900998b5e11c03023264208James Dong { 36329a84457aed4c45bc900998b5e11c03023264208James Dong ce_TotalZeros(stream, zerosLeft, TotalCoeff); 36429a84457aed4c45bc900998b5e11c03023264208James Dong } 36529a84457aed4c45bc900998b5e11c03023264208James Dong else 36629a84457aed4c45bc900998b5e11c03023264208James Dong { 36729a84457aed4c45bc900998b5e11c03023264208James Dong ce_TotalZerosChromaDC(stream, zerosLeft, TotalCoeff); 36829a84457aed4c45bc900998b5e11c03023264208James Dong } 36929a84457aed4c45bc900998b5e11c03023264208James Dong } 37029a84457aed4c45bc900998b5e11c03023264208James Dong else 37129a84457aed4c45bc900998b5e11c03023264208James Dong { 37229a84457aed4c45bc900998b5e11c03023264208James Dong zerosLeft = 0; 37329a84457aed4c45bc900998b5e11c03023264208James Dong } 37429a84457aed4c45bc900998b5e11c03023264208James Dong 37529a84457aed4c45bc900998b5e11c03023264208James Dong i = TotalCoeff - 1; 37629a84457aed4c45bc900998b5e11c03023264208James Dong while (i > 0) /* don't do the last one */ 37729a84457aed4c45bc900998b5e11c03023264208James Dong { 37829a84457aed4c45bc900998b5e11c03023264208James Dong if (zerosLeft > 0) 37929a84457aed4c45bc900998b5e11c03023264208James Dong { 38029a84457aed4c45bc900998b5e11c03023264208James Dong ce_RunBefore(stream, run[i], zerosLeft); 38129a84457aed4c45bc900998b5e11c03023264208James Dong } 38229a84457aed4c45bc900998b5e11c03023264208James Dong 38329a84457aed4c45bc900998b5e11c03023264208James Dong zerosLeft = zerosLeft - run[i]; 38429a84457aed4c45bc900998b5e11c03023264208James Dong i--; 38529a84457aed4c45bc900998b5e11c03023264208James Dong } 38629a84457aed4c45bc900998b5e11c03023264208James Dong } 38729a84457aed4c45bc900998b5e11c03023264208James Dong 38829a84457aed4c45bc900998b5e11c03023264208James Dong return status; 38929a84457aed4c45bc900998b5e11c03023264208James Dong} 390