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 /** 21 See algorithm in subclause 9.1, Table 9-1, Table 9-2. */ 22 AVCEnc_Status ue_v(AVCEncBitstream *bitstream, uint codeNum) 23 { 24 if (AVCENC_SUCCESS != SetEGBitstring(bitstream, codeNum)) 25 return AVCENC_FAIL; 26 27 return AVCENC_SUCCESS; 28 } 29 30 /** 31 See subclause 9.1.1, Table 9-3 */ 32 AVCEnc_Status se_v(AVCEncBitstream *bitstream, int value) 33 { 34 uint codeNum; 35 AVCEnc_Status status; 36 37 if (value <= 0) 38 { 39 codeNum = -value * 2; 40 } 41 else 42 { 43 codeNum = value * 2 - 1; 44 } 45 46 status = ue_v(bitstream, codeNum); 47 48 return status; 49 } 50 51 AVCEnc_Status te_v(AVCEncBitstream *bitstream, uint value, uint range) 52 { 53 AVCEnc_Status status; 54 55 if (range > 1) 56 { 57 return ue_v(bitstream, value); 58 } 59 else 60 { 61 status = BitstreamWrite1Bit(bitstream, 1 - value); 62 return status; 63 } 64 } 65 66 /** 67 See subclause 9.1, Table 9-1, 9-2. */ 68 // compute leadingZeros and inforbits 69 //codeNum = (1<<leadingZeros)-1+infobits; 70 AVCEnc_Status SetEGBitstring(AVCEncBitstream *bitstream, uint codeNum) 71 { 72 AVCEnc_Status status; 73 int leadingZeros; 74 int infobits; 75 76 if (!codeNum) 77 { 78 status = BitstreamWrite1Bit(bitstream, 1); 79 return status; 80 } 81 82 /* calculate leadingZeros and infobits */ 83 leadingZeros = 1; 84 while ((uint)(1 << leadingZeros) < codeNum + 2) 85 { 86 leadingZeros++; 87 } 88 leadingZeros--; 89 infobits = codeNum - (1 << leadingZeros) + 1; 90 91 status = BitstreamWriteBits(bitstream, leadingZeros, 0); 92 infobits |= (1 << leadingZeros); 93 status = BitstreamWriteBits(bitstream, leadingZeros + 1, infobits); 94 return status; 95 } 96 97 /* see Table 9-4 assignment of codeNum to values of coded_block_pattern. */ 98 const static uint8 MapCBP2code[48][2] = 99 { 100 {3, 0}, {29, 2}, {30, 3}, {17, 7}, {31, 4}, {18, 8}, {37, 17}, {8, 13}, {32, 5}, {38, 18}, {19, 9}, {9, 14}, 101 {20, 10}, {10, 15}, {11, 16}, {2, 11}, {16, 1}, {33, 32}, {34, 33}, {21, 36}, {35, 34}, {22, 37}, {39, 44}, {4, 40}, 102 {36, 35}, {40, 45}, {23, 38}, {5, 41}, {24, 39}, {6, 42}, {7, 43}, {1, 19}, {41, 6}, {42, 24}, {43, 25}, {25, 20}, 103 {44, 26}, {26, 21}, {46, 46}, {12, 28}, {45, 27}, {47, 47}, {27, 22}, {13, 29}, {28, 23}, {14, 30}, {15, 31}, {0, 12} 104 }; 105 106 AVCEnc_Status EncodeCBP(AVCMacroblock *currMB, AVCEncBitstream *stream) 107 { 108 AVCEnc_Status status; 109 uint codeNum; 110 111 if (currMB->mbMode == AVC_I4) 112 { 113 codeNum = MapCBP2code[currMB->CBP][0]; 114 } 115 else 116 { 117 codeNum = MapCBP2code[currMB->CBP][1]; 118 } 119 120 status = ue_v(stream, codeNum); 121 122 return status; 123 } 124 125 AVCEnc_Status ce_TotalCoeffTrailingOnes(AVCEncBitstream *stream, int TrailingOnes, int TotalCoeff, int nC) 126 { 127 const static uint8 totCoeffTrailOne[3][4][17][2] = 128 { 129 { // 0702 130 {{1, 1}, {6, 5}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, {13, 15}, {13, 11}, {13, 8}, {14, 15}, {14, 11}, {15, 15}, {15, 11}, {16, 15}, {16, 11}, {16, 7}, {16, 4}}, 131 {{0, 0}, {2, 1}, {6, 4}, {8, 6}, {9, 6}, {10, 6}, {11, 6}, {13, 14}, {13, 10}, {14, 14}, {14, 10}, {15, 14}, {15, 10}, {15, 1}, {16, 14}, {16, 10}, {16, 6}}, 132 {{0, 0}, {0, 0}, {3, 1}, {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, {13, 13}, {13, 9}, {14, 13}, {14, 9}, {15, 13}, {15, 9}, {16, 13}, {16, 9}, {16, 5}}, 133 {{0, 0}, {0, 0}, {0, 0}, {5, 3}, {6, 3}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, {13, 12}, {14, 12}, {14, 8}, {15, 12}, {15, 8}, {16, 12}, {16, 8}}, 134 }, 135 { 136 {{2, 3}, {6, 11}, {6, 7}, {7, 7}, {8, 7}, {8, 4}, {9, 7}, {11, 15}, {11, 11}, {12, 15}, {12, 11}, {12, 8}, {13, 15}, {13, 11}, {13, 7}, {14, 9}, {14, 7}}, 137 {{0, 0}, {2, 2}, {5, 7}, {6, 10}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {11, 14}, {11, 10}, {12, 14}, {12, 10}, {13, 14}, {13, 10}, {14, 11}, {14, 8}, {14, 6}}, 138 {{0, 0}, {0, 0}, {3, 3}, {6, 9}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {11, 13}, {11, 9}, {12, 13}, {12, 9}, {13, 13}, {13, 9}, {13, 6}, {14, 10}, {14, 5}}, 139 {{0, 0}, {0, 0}, {0, 0}, {4, 5}, {4, 4}, {5, 6}, {6, 8}, {6, 4}, {7, 4}, {9, 4}, {11, 12}, {11, 8}, {12, 12}, {13, 12}, {13, 8}, {13, 1}, {14, 4}}, 140 }, 141 { 142 {{4, 15}, {6, 15}, {6, 11}, {6, 8}, {7, 15}, {7, 11}, {7, 9}, {7, 8}, {8, 15}, {8, 11}, {9, 15}, {9, 11}, {9, 8}, {10, 13}, {10, 9}, {10, 5}, {10, 1}}, 143 {{0, 0}, {4, 14}, {5, 15}, {5, 12}, {5, 10}, {5, 8}, {6, 14}, {6, 10}, {7, 14}, {8, 14}, {8, 10}, {9, 14}, {9, 10}, {9, 7}, {10, 12}, {10, 8}, {10, 4}}, 144 {{0, 0}, {0, 0}, {4, 13}, {5, 14}, {5, 11}, {5, 9}, {6, 13}, {6, 9}, {7, 13}, {7, 10}, {8, 13}, {8, 9}, {9, 13}, {9, 9}, {10, 11}, {10, 7}, {10, 3}}, 145 {{0, 0}, {0, 0}, {0, 0}, {4, 12}, {4, 11}, {4, 10}, {4, 9}, {4, 8}, {5, 13}, {6, 12}, {7, 12}, {8, 12}, {8, 8}, {9, 12}, {10, 10}, {10, 6}, {10, 2}} 146 } 147 }; 148 149 150 AVCEnc_Status status = AVCENC_SUCCESS; 151 uint code, len; 152 int vlcnum; 153 154 if (TrailingOnes > 3) 155 { 156 return AVCENC_TRAILINGONES_FAIL; 157 } 158 159 if (nC >= 8) 160 { 161 if (TotalCoeff) 162 { 163 code = ((TotalCoeff - 1) << 2) | (TrailingOnes); 164 } 165 else 166 { 167 code = 3; 168 } 169 status = BitstreamWriteBits(stream, 6, code); 170 } 171 else 172 { 173 if (nC < 2) 174 { 175 vlcnum = 0; 176 } 177 else if (nC < 4) 178 { 179 vlcnum = 1; 180 } 181 else 182 { 183 vlcnum = 2; 184 } 185 186 len = totCoeffTrailOne[vlcnum][TrailingOnes][TotalCoeff][0]; 187 code = totCoeffTrailOne[vlcnum][TrailingOnes][TotalCoeff][1]; 188 status = BitstreamWriteBits(stream, len, code); 189 } 190 191 return status; 192 } 193 194 AVCEnc_Status ce_TotalCoeffTrailingOnesChromaDC(AVCEncBitstream *stream, int TrailingOnes, int TotalCoeff) 195 { 196 const static uint8 totCoeffTrailOneChrom[4][5][2] = 197 { 198 { {2, 1}, {6, 7}, {6, 4}, {6, 3}, {6, 2}}, 199 { {0, 0}, {1, 1}, {6, 6}, {7, 3}, {8, 3}}, 200 { {0, 0}, {0, 0}, {3, 1}, {7, 2}, {8, 2}}, 201 { {0, 0}, {0, 0}, {0, 0}, {6, 5}, {7, 0}}, 202 }; 203 204 AVCEnc_Status status = AVCENC_SUCCESS; 205 uint code, len; 206 207 len = totCoeffTrailOneChrom[TrailingOnes][TotalCoeff][0]; 208 code = totCoeffTrailOneChrom[TrailingOnes][TotalCoeff][1]; 209 status = BitstreamWriteBits(stream, len, code); 210 211 return status; 212 } 213 214 /* see Table 9-7 and 9-8 */ 215 AVCEnc_Status ce_TotalZeros(AVCEncBitstream *stream, int total_zeros, int TotalCoeff) 216 { 217 const static uint8 lenTotalZeros[15][16] = 218 { 219 { 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9}, 220 { 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6}, 221 { 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6}, 222 { 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5}, 223 { 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5}, 224 { 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6}, 225 { 6, 5, 3, 3, 3, 2, 3, 4, 3, 6}, 226 { 6, 4, 5, 3, 2, 2, 3, 3, 6}, 227 { 6, 6, 4, 2, 2, 3, 2, 5}, 228 { 5, 5, 3, 2, 2, 2, 4}, 229 { 4, 4, 3, 3, 1, 3}, 230 { 4, 4, 2, 1, 3}, 231 { 3, 3, 1, 2}, 232 { 2, 2, 1}, 233 { 1, 1}, 234 }; 235 236 const static uint8 codTotalZeros[15][16] = 237 { 238 {1, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 1}, 239 {7, 6, 5, 4, 3, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0}, 240 {5, 7, 6, 5, 4, 3, 4, 3, 2, 3, 2, 1, 1, 0}, 241 {3, 7, 5, 4, 6, 5, 4, 3, 3, 2, 2, 1, 0}, 242 {5, 4, 3, 7, 6, 5, 4, 3, 2, 1, 1, 0}, 243 {1, 1, 7, 6, 5, 4, 3, 2, 1, 1, 0}, 244 {1, 1, 5, 4, 3, 3, 2, 1, 1, 0}, 245 {1, 1, 1, 3, 3, 2, 2, 1, 0}, 246 {1, 0, 1, 3, 2, 1, 1, 1, }, 247 {1, 0, 1, 3, 2, 1, 1, }, 248 {0, 1, 1, 2, 1, 3}, 249 {0, 1, 1, 1, 1}, 250 {0, 1, 1, 1}, 251 {0, 1, 1}, 252 {0, 1}, 253 }; 254 int len, code; 255 AVCEnc_Status status; 256 257 len = lenTotalZeros[TotalCoeff-1][total_zeros]; 258 code = codTotalZeros[TotalCoeff-1][total_zeros]; 259 260 status = BitstreamWriteBits(stream, len, code); 261 262 return status; 263 } 264 265 /* see Table 9-9 */ 266 AVCEnc_Status ce_TotalZerosChromaDC(AVCEncBitstream *stream, int total_zeros, int TotalCoeff) 267 { 268 const static uint8 lenTotalZerosChromaDC[3][4] = 269 { 270 { 1, 2, 3, 3, }, 271 { 1, 2, 2, 0, }, 272 { 1, 1, 0, 0, }, 273 }; 274 275 const static uint8 codTotalZerosChromaDC[3][4] = 276 { 277 { 1, 1, 1, 0, }, 278 { 1, 1, 0, 0, }, 279 { 1, 0, 0, 0, }, 280 }; 281 282 int len, code; 283 AVCEnc_Status status; 284 285 len = lenTotalZerosChromaDC[TotalCoeff-1][total_zeros]; 286 code = codTotalZerosChromaDC[TotalCoeff-1][total_zeros]; 287 288 status = BitstreamWriteBits(stream, len, code); 289 290 return status; 291 } 292 293 /* see Table 9-10 */ 294 AVCEnc_Status ce_RunBefore(AVCEncBitstream *stream, int run_before, int zerosLeft) 295 { 296 const static uint8 lenRunBefore[7][16] = 297 { 298 {1, 1}, 299 {1, 2, 2}, 300 {2, 2, 2, 2}, 301 {2, 2, 2, 3, 3}, 302 {2, 2, 3, 3, 3, 3}, 303 {2, 3, 3, 3, 3, 3, 3}, 304 {3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 305 }; 306 307 const static uint8 codRunBefore[7][16] = 308 { 309 {1, 0}, 310 {1, 1, 0}, 311 {3, 2, 1, 0}, 312 {3, 2, 1, 1, 0}, 313 {3, 2, 3, 2, 1, 0}, 314 {3, 0, 1, 3, 2, 5, 4}, 315 {7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1}, 316 }; 317 318 int len, code; 319 AVCEnc_Status status; 320 321 if (zerosLeft <= 6) 322 { 323 len = lenRunBefore[zerosLeft-1][run_before]; 324 code = codRunBefore[zerosLeft-1][run_before]; 325 } 326 else 327 { 328 len = lenRunBefore[6][run_before]; 329 code = codRunBefore[6][run_before]; 330 } 331 332 status = BitstreamWriteBits(stream, len, code); 333 334 335 return status; 336 } 337