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
EncodeIntraPCM(AVCEncObject * encvid)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
enc_residual_block(AVCEncObject * encvid,AVCResidualType type,int cindx,AVCMacroblock * currMB)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