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/**
21See algorithm in subclause 9.1, Table 9-1, Table 9-2. */
22AVCEnc_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/**
31See subclause 9.1.1, Table 9-3 */
32AVCEnc_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
51AVCEnc_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/**
67See subclause 9.1, Table 9-1, 9-2. */
68// compute leadingZeros and inforbits
69//codeNum = (1<<leadingZeros)-1+infobits;
70AVCEnc_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. */
98const 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
106AVCEnc_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
125AVCEnc_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
194AVCEnc_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 */
215AVCEnc_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 */
266AVCEnc_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 */
294AVCEnc_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