1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 #include "avcenc_lib.h" 19 20 AVCEnc_Status EncodeIntraPCM(AVCEncObject *encvid) 21 { 22 AVCEnc_Status status = AVCENC_SUCCESS; 23 AVCCommonObj *video = encvid->common; 24 AVCFrameIO *currInput = encvid->currInput; 25 AVCEncBitstream *stream = encvid->bitstream; 26 int x_position = (video->mb_x << 4); 27 int y_position = (video->mb_y << 4); 28 int orgPitch = currInput->pitch; 29 int offset1 = y_position * orgPitch + x_position; 30 int i, j; 31 int offset; 32 uint8 *pDst, *pSrc; 33 uint code; 34 35 ue_v(stream, 25); 36 37 i = stream->bit_left & 0x7; 38 if (i) /* not byte-aligned */ 39 { 40 BitstreamWriteBits(stream, 0, i); 41 } 42 43 pSrc = currInput->YCbCr[0] + offset1; 44 pDst = video->currPic->Sl + offset1; 45 offset = video->PicWidthInSamplesL - 16; 46 47 /* at this point bitstream is byte-aligned */ 48 j = 16; 49 while (j > 0) 50 { 51 #if (WORD_SIZE==32) 52 for (i = 0; i < 4; i++) 53 { 54 code = *((uint*)pSrc); 55 pSrc += 4; 56 *((uint*)pDst) = code; 57 pDst += 4; 58 status = BitstreamWriteBits(stream, 32, code); 59 } 60 #else 61 for (i = 0; i < 8; i++) 62 { 63 code = *((uint*)pSrc); 64 pSrc += 2; 65 *((uint*)pDst) = code; 66 pDst += 2; 67 status = BitstreamWriteBits(stream, 16, code); 68 } 69 #endif 70 pDst += offset; 71 pSrc += offset; 72 j--; 73 } 74 if (status != AVCENC_SUCCESS) /* check only once per line */ 75 return status; 76 77 pDst = video->currPic->Scb + ((offset1 + x_position) >> 2); 78 pSrc = currInput->YCbCr[1] + ((offset1 + x_position) >> 2); 79 offset >>= 1; 80 81 j = 8; 82 while (j > 0) 83 { 84 #if (WORD_SIZE==32) 85 for (i = 0; i < 2; i++) 86 { 87 code = *((uint*)pSrc); 88 pSrc += 4; 89 *((uint*)pDst) = code; 90 pDst += 4; 91 status = BitstreamWriteBits(stream, 32, code); 92 } 93 #else 94 for (i = 0; i < 4; i++) 95 { 96 code = *((uint*)pSrc); 97 pSrc += 2; 98 *((uint*)pDst) = code; 99 pDst += 2; 100 status = BitstreamWriteBits(stream, 16, code); 101 } 102 #endif 103 pDst += offset; 104 pSrc += offset; 105 j--; 106 } 107 108 if (status != AVCENC_SUCCESS) /* check only once per line */ 109 return status; 110 111 pDst = video->currPic->Scr + ((offset1 + x_position) >> 2); 112 pSrc = currInput->YCbCr[2] + ((offset1 + x_position) >> 2); 113 114 j = 8; 115 while (j > 0) 116 { 117 #if (WORD_SIZE==32) 118 for (i = 0; i < 2; i++) 119 { 120 code = *((uint*)pSrc); 121 pSrc += 4; 122 *((uint*)pDst) = code; 123 pDst += 4; 124 status = BitstreamWriteBits(stream, 32, code); 125 } 126 #else 127 for (i = 0; i < 4; i++) 128 { 129 code = *((uint*)pSrc); 130 pSrc += 2; 131 *((uint*)pDst) = code; 132 pDst += 2; 133 status = BitstreamWriteBits(stream, 16, code); 134 } 135 #endif 136 pDst += offset; 137 pSrc += offset; 138 j--; 139 } 140 141 return status; 142 } 143 144 145 AVCEnc_Status enc_residual_block(AVCEncObject *encvid, AVCResidualType type, int cindx, AVCMacroblock *currMB) 146 { 147 AVCEnc_Status status = AVCENC_SUCCESS; 148 AVCCommonObj *video = encvid->common; 149 int i, maxNumCoeff, nC; 150 int cdc = 0, cac = 0; 151 int TrailingOnes; 152 AVCEncBitstream *stream = encvid->bitstream; 153 uint trailing_ones_sign_flag; 154 int zerosLeft; 155 int *level, *run; 156 int TotalCoeff; 157 const static int incVlc[] = {0, 3, 6, 12, 24, 48, 32768}; // maximum vlc = 6 158 int escape, numPrefix, sufmask, suffix, shift, sign, value, absvalue, vlcnum, level_two_or_higher; 159 int bindx = blkIdx2blkXY[cindx>>2][cindx&3] ; // raster scan index 160 161 switch (type) 162 { 163 case AVC_Luma: 164 maxNumCoeff = 16; 165 level = encvid->level[cindx]; 166 run = encvid->run[cindx]; 167 TotalCoeff = currMB->nz_coeff[bindx]; 168 break; 169 case AVC_Intra16DC: 170 maxNumCoeff = 16; 171 level = encvid->leveldc; 172 run = encvid->rundc; 173 TotalCoeff = cindx; /* special case */ 174 bindx = 0; 175 cindx = 0; 176 break; 177 case AVC_Intra16AC: 178 maxNumCoeff = 15; 179 level = encvid->level[cindx]; 180 run = encvid->run[cindx]; 181 TotalCoeff = currMB->nz_coeff[bindx]; 182 break; 183 case AVC_ChromaDC: /* how to differentiate Cb from Cr */ 184 maxNumCoeff = 4; 185 cdc = 1; 186 if (cindx >= 8) 187 { 188 level = encvid->levelcdc + 4; 189 run = encvid->runcdc + 4; 190 TotalCoeff = cindx - 8; /* special case */ 191 } 192 else 193 { 194 level = encvid->levelcdc; 195 run = encvid->runcdc; 196 TotalCoeff = cindx; /* special case */ 197 } 198 break; 199 case AVC_ChromaAC: 200 maxNumCoeff = 15; 201 cac = 1; 202 level = encvid->level[cindx]; 203 run = encvid->run[cindx]; 204 cindx -= 16; 205 bindx = 16 + blkIdx2blkXY[cindx>>2][cindx&3]; 206 cindx += 16; 207 TotalCoeff = currMB->nz_coeff[bindx]; 208 break; 209 default: 210 return AVCENC_FAIL; 211 } 212 213 214 /* find TrailingOnes */ 215 TrailingOnes = 0; 216 zerosLeft = 0; 217 i = TotalCoeff - 1; 218 nC = 1; 219 while (i >= 0) 220 { 221 zerosLeft += run[i]; 222 if (nC && (level[i] == 1 || level[i] == -1)) 223 { 224 TrailingOnes++; 225 } 226 else 227 { 228 nC = 0; 229 } 230 i--; 231 } 232 if (TrailingOnes > 3) 233 { 234 TrailingOnes = 3; /* clip it */ 235 } 236 237 if (!cdc) 238 { 239 if (!cac) /* not chroma */ 240 { 241 nC = predict_nnz(video, bindx & 3, bindx >> 2); 242 } 243 else /* chroma ac but not chroma dc */ 244 { 245 nC = predict_nnz_chroma(video, bindx & 3, bindx >> 2); 246 } 247 248 status = ce_TotalCoeffTrailingOnes(stream, TrailingOnes, TotalCoeff, nC); 249 } 250 else 251 { 252 nC = -1; /* Chroma DC level */ 253 status = ce_TotalCoeffTrailingOnesChromaDC(stream, TrailingOnes, TotalCoeff); 254 } 255 256 /* This part is done quite differently in ReadCoef4x4_CAVLC() */ 257 if (TotalCoeff > 0) 258 { 259 260 i = TotalCoeff - 1; 261 262 if (TrailingOnes) /* keep reading the sign of those trailing ones */ 263 { 264 nC = TrailingOnes; 265 trailing_ones_sign_flag = 0; 266 while (nC) 267 { 268 trailing_ones_sign_flag <<= 1; 269 trailing_ones_sign_flag |= ((uint32)level[i--] >> 31); /* 0 or positive, 1 for negative */ 270 nC--; 271 } 272 273 /* instead of writing one bit at a time, read the whole thing at once */ 274 status = BitstreamWriteBits(stream, TrailingOnes, trailing_ones_sign_flag); 275 } 276 277 level_two_or_higher = 1; 278 if (TotalCoeff > 3 && TrailingOnes == 3) 279 { 280 level_two_or_higher = 0; 281 } 282 283 if (TotalCoeff > 10 && TrailingOnes < 3) 284 { 285 vlcnum = 1; 286 } 287 else 288 { 289 vlcnum = 0; 290 } 291 292 /* then do this TotalCoeff-TrailingOnes times */ 293 for (i = TotalCoeff - TrailingOnes - 1; i >= 0; i--) 294 { 295 value = level[i]; 296 absvalue = (value >= 0) ? value : -value; 297 298 if (level_two_or_higher) 299 { 300 if (value > 0) value--; 301 else value++; 302 level_two_or_higher = 0; 303 } 304 305 if (value >= 0) 306 { 307 sign = 0; 308 } 309 else 310 { 311 sign = 1; 312 value = -value; 313 } 314 315 if (vlcnum == 0) // VLC1 316 { 317 if (value < 8) 318 { 319 status = BitstreamWriteBits(stream, value * 2 + sign - 1, 1); 320 } 321 else if (value < 8 + 8) 322 { 323 status = BitstreamWriteBits(stream, 14 + 1 + 4, (1 << 4) | ((value - 8) << 1) | sign); 324 } 325 else 326 { 327 status = BitstreamWriteBits(stream, 14 + 2 + 12, (1 << 12) | ((value - 16) << 1) | sign) ; 328 } 329 } 330 else // VLCN 331 { 332 shift = vlcnum - 1; 333 escape = (15 << shift) + 1; 334 numPrefix = (value - 1) >> shift; 335 sufmask = ~((0xffffffff) << shift); 336 suffix = (value - 1) & sufmask; 337 if (value < escape) 338 { 339 status = BitstreamWriteBits(stream, numPrefix + vlcnum + 1, (1 << (shift + 1)) | (suffix << 1) | sign); 340 } 341 else 342 { 343 status = BitstreamWriteBits(stream, 28, (1 << 12) | ((value - escape) << 1) | sign); 344 } 345 346 } 347 348 if (absvalue > incVlc[vlcnum]) 349 vlcnum++; 350 351 if (i == TotalCoeff - TrailingOnes - 1 && absvalue > 3) 352 vlcnum = 2; 353 } 354 355 if (status != AVCENC_SUCCESS) /* occasionally check the bitstream */ 356 { 357 return status; 358 } 359 if (TotalCoeff < maxNumCoeff) 360 { 361 if (!cdc) 362 { 363 ce_TotalZeros(stream, zerosLeft, TotalCoeff); 364 } 365 else 366 { 367 ce_TotalZerosChromaDC(stream, zerosLeft, TotalCoeff); 368 } 369 } 370 else 371 { 372 zerosLeft = 0; 373 } 374 375 i = TotalCoeff - 1; 376 while (i > 0) /* don't do the last one */ 377 { 378 if (zerosLeft > 0) 379 { 380 ce_RunBefore(stream, run[i], zerosLeft); 381 } 382 383 zerosLeft = zerosLeft - run[i]; 384 i--; 385 } 386 } 387 388 return status; 389 } 390