1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * Implementation for MPEG4(H263) video transcoder. |
|
17 * Block matching algorithms for MPEG4(H263) video transcoder. |
|
18 * |
|
19 */ |
|
20 |
|
21 |
|
22 |
|
23 #include "biblin.h" |
|
24 #include "common.h" |
|
25 #include "h263dconfig.h" |
|
26 #include "decmbdct.h" |
|
27 #include "vdxint.h" |
|
28 |
|
29 /* |
|
30 * Constants/definitions |
|
31 */ |
|
32 |
|
33 #define DIAMOND_SEARCH_NUMBER 2 |
|
34 |
|
35 |
|
36 const tVLCTable sCBPCIType[9] = |
|
37 { |
|
38 {0x01,0x01}, {0x01,0x03}, {0x02,0x03}, {0x03,0x03}, |
|
39 {0x01,0x04}, {0x01,0x06}, {0x02,0x06}, {0x03,0x06}, |
|
40 {0x01,0x09} |
|
41 }; |
|
42 |
|
43 const tVLCTable sCBPCPType[21] = |
|
44 { |
|
45 {0x01,0x01}, {0x03,0x04}, {0x02,0x04}, {0x05,0x06}, |
|
46 {0x03,0x03}, {0x07,0x07}, {0x06,0x07}, {0x05,0x09}, |
|
47 {0x02,0x03}, {0x05,0x07}, {0x04,0x07}, {0x05,0x08}, |
|
48 {0x03,0x05}, {0x04,0x08}, {0x03,0x08}, {0x03,0x07}, |
|
49 {0x04,0x06}, {0x04,0x09}, {0x03,0x09}, {0x02,0x09}, |
|
50 {0x01,0x09} |
|
51 }; |
|
52 |
|
53 const tVLCTable sCBPY[16] = |
|
54 { |
|
55 {0x03,0x04}, {0x05,0x05}, {0x04,0x05}, {0x09,0x04}, |
|
56 {0x03,0x05}, {0x07,0x04}, {0x02,0x06}, {0x0b,0x04}, |
|
57 {0x02,0x05}, {0x03,0x06}, {0x05,0x04}, {0x0a,0x04}, |
|
58 {0x04,0x04}, {0x08,0x04}, {0x06,0x04}, {0x03,0x02} |
|
59 }; |
|
60 |
|
61 const unsigned int sDquant[5] = |
|
62 { |
|
63 0x01, 0x00, (unsigned int)NOT_VALID, 0x02, 0x03 |
|
64 }; |
|
65 |
|
66 const tVLCTable sMVTab[33] = |
|
67 { |
|
68 {0x01,0x01}, {0x02,0x03}, {0x02,0x04}, {0x02,0x05}, |
|
69 {0x06,0x07}, {0x0a,0x08}, {0x08,0x08}, {0x06,0x08}, |
|
70 {0x16,0x0a}, {0x14,0x0a}, {0x12,0x0a}, {0x22,0x0b}, |
|
71 {0x20,0x0b}, {0x1e,0x0b}, {0x1c,0x0b}, {0x1a,0x0b}, |
|
72 {0x18,0x0b}, {0x16,0x0b}, {0x14,0x0b}, {0x12,0x0b}, |
|
73 {0x10,0x0b}, {0x0e,0x0b}, {0x0c,0x0b}, {0x0a,0x0b}, |
|
74 {0x08,0x0b}, {0x0e,0x0c}, {0x0c,0x0c}, {0x0a,0x0c}, |
|
75 {0x08,0x0c}, {0x06,0x0c}, {0x04,0x0c}, {0x06,0x0d}, |
|
76 {0x04,0x0d} |
|
77 }; |
|
78 |
|
79 const int32 sFixedQuantScale1[32]= |
|
80 { |
|
81 0x0000, 0x7fff, 0x3fff, 0x2aaa, |
|
82 0x1fff, 0x1999, 0x1555, 0x1249, |
|
83 0x0fff, 0x0e38, 0x0ccc, 0x0ba2, |
|
84 0x0aaa, 0x09d8, 0x0924, 0x0888, |
|
85 0x07ff, 0x0787, 0x071c, 0x06bc, |
|
86 0x0666, 0x0618, 0x05d1, 0x1590, |
|
87 0x0555, 0x051e, 0x04ec, 0x04bd, |
|
88 0x0492, 0x0469, 0x0444, 0x0421 |
|
89 }; |
|
90 |
|
91 const u_int16 sPrePostMult[64] = |
|
92 { |
|
93 0x8000, 0xb18a, 0xa73d, 0x9683, |
|
94 0x8000, 0x9683, 0xa73d, 0xb18a, |
|
95 0xb18a, 0xf641, 0xe7f7, 0xd0c3, |
|
96 0xb18a, 0xd0c3, 0xe7f7, 0xf641, |
|
97 0xa73d, 0xe7f7, 0xda82, 0xc4a7, |
|
98 0xa73d, 0xc4a7, 0xda82, 0xe7f7, |
|
99 0x9683, 0xd0c3, 0xc4a7, 0xb0fb, |
|
100 0x9683, 0xb0fb, 0xc4a7, 0xd0c3, |
|
101 0x8000, 0xb18a, 0xa73d, 0x9683, |
|
102 0x8000, 0x9683, 0xa73d, 0xb18a, |
|
103 0x9683, 0xd0c3, 0xc4a7, 0xb0fb, |
|
104 0x9683, 0xb0fb, 0xc4a7, 0xd0c3, |
|
105 0xa73d, 0xe7f7, 0xda82, 0xc4a7, |
|
106 0xa73d, 0xc4a7, 0xda82, 0xe7f7, |
|
107 0xb18a, 0xf641, 0xe7f7, 0xd0c3, |
|
108 0xb18a, 0xd0c3, 0xe7f7, 0xf641 |
|
109 }; |
|
110 |
|
111 |
|
112 |
|
113 /* |
|
114 * Function Declarations |
|
115 */ |
|
116 int32 vlbCodeACCoeffsSVHWithZigZag(int32 coeffStart, int16* block, bibBuffer_t * outBuf, |
|
117 int32 svh, int32 lastPos); |
|
118 void vlbPutBits(bibBuffer_t *base, int32 numBits, u_int32 value); |
|
119 |
|
120 |
|
121 |
|
122 /* |
|
123 * Function Definitions |
|
124 */ |
|
125 |
|
126 /* {{-output"vbmGetH263IMCBPC.txt"}} */ |
|
127 /* |
|
128 * vbmGetH263IMCBPC |
|
129 * |
|
130 * Parameters: |
|
131 * vopCodingType coding type (INTER/INTRA) for the VOP |
|
132 * dQuant quantization parameter |
|
133 * colorEffect indicates color effect to be aplpied (e.g., black & white) |
|
134 * cbpy cbpy value for the macro block |
|
135 * mcbpcVal computed mcbpc value for the macro block |
|
136 * length length of the computed mcbpc value codeword |
|
137 * |
|
138 * Function: |
|
139 * This function evaluates the mcpbc codeword for INTRA macro block |
|
140 * |
|
141 * Returns: |
|
142 * Nothing. |
|
143 * |
|
144 * Error codes: |
|
145 * None. |
|
146 * |
|
147 */ |
|
148 void vbmGetH263IMCBPC(int dQuant, int vopCodingType, int /*colorEffect*/, |
|
149 int cbpy, int& mcbpcVal, int& length) |
|
150 { |
|
151 int index; |
|
152 int len, mcbpc; |
|
153 |
|
154 if(vopCodingType == 1 /* VDX_VOP_TYPE_P */) |
|
155 { |
|
156 index = (dQuant == 0 ? 12 : 16) + mcbpcVal; |
|
157 len = sCBPCPType[index].length + sCBPY[cbpy].length + 1; |
|
158 mcbpc = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code; |
|
159 mcbpcVal = mcbpc; |
|
160 length = len; |
|
161 } |
|
162 else |
|
163 { |
|
164 index = (dQuant == 0 ? 0 : 4) + mcbpcVal; |
|
165 len = sCBPCIType[index].length + sCBPY[cbpy].length ; |
|
166 mcbpc = (sCBPCIType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code; |
|
167 mcbpcVal = mcbpc; |
|
168 length = len; |
|
169 } |
|
170 } |
|
171 |
|
172 |
|
173 |
|
174 /* {{-output"vbmGetH263PMCBPC.txt"}} */ |
|
175 /* |
|
176 * vbmGetH263PMCBPC |
|
177 * |
|
178 * Parameters: |
|
179 * dQuant quantization parameter |
|
180 * colorEffect indicates color effect to be aplpied (e.g., black & white) |
|
181 * cbpy cbpy value for the macro block |
|
182 * mcbpcVal computed mcbpc value for the macro block |
|
183 * length length of the computed mcbpc value codeword |
|
184 * |
|
185 * Function: |
|
186 * This function evaluates the mcpbc codeword for INTER macro block |
|
187 * |
|
188 * Returns: |
|
189 * Nothing. |
|
190 * |
|
191 * Error codes: |
|
192 * None. |
|
193 * |
|
194 */ |
|
195 void vbmGetH263PMCBPC(int dQuant, int /*colorEffect*/, int cbpy, int& mcbpcVal, int& length) |
|
196 { |
|
197 int index; |
|
198 int len, mcbpc; |
|
199 cbpy = (~cbpy) & 0xf; |
|
200 |
|
201 /* only ONE MV in baseline H263 */ |
|
202 index = (dQuant == 0 ? 0 : 4) + mcbpcVal; |
|
203 len = sCBPCPType[index].length + sCBPY[cbpy].length; |
|
204 mcbpc = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code; |
|
205 mcbpcVal = mcbpc; |
|
206 length = len; |
|
207 } |
|
208 |
|
209 |
|
210 |
|
211 /* {{-output"vbmEncodeMVDifferential.txt"}} */ |
|
212 /* |
|
213 * vbmEncodeMVDifferential |
|
214 * |
|
215 * Parameters: |
|
216 * outBuf output buffer |
|
217 * mvdx motion vector difference value in horizontal direction, in half-pixel unit |
|
218 * mvdy motion vector difference value in vertical direction, in half-pixel unit |
|
219 * fCode Fcode value |
|
220 * |
|
221 * Function: |
|
222 * This function encodes the MV difference after prediction into the bitstream |
|
223 * |
|
224 * Returns: |
|
225 * Nothing. |
|
226 * |
|
227 * Error codes: |
|
228 * None. |
|
229 * |
|
230 */ |
|
231 void vbmEncodeMVDifferential(int32 mvdx, int32 mvdy, int32 fCode, |
|
232 bibBuffer_t * outBuf) |
|
233 { |
|
234 int32 mvd[2]; |
|
235 u_int32 i; |
|
236 int32 temp; |
|
237 int32 motioncode; |
|
238 int32 motionresidual; |
|
239 int32 rsize = fCode - 1; |
|
240 u_int32 f = 1 << rsize; |
|
241 int32 high = 32 * f - 1; |
|
242 int32 low = -32 * (int32) f; |
|
243 int32 range = 64 *f; |
|
244 |
|
245 mvd[0] = mvdx; |
|
246 mvd[1] = mvdy; |
|
247 |
|
248 for(i = 0; i < 2; i++) |
|
249 { |
|
250 if (mvd[i] < low) |
|
251 { |
|
252 mvd[i] += range; |
|
253 } |
|
254 else |
|
255 { |
|
256 if (mvd[i] > high) |
|
257 { |
|
258 mvd[i] -= range; |
|
259 } |
|
260 } |
|
261 temp = ABS(mvd[i]) -1 + f; |
|
262 motioncode = temp >> rsize; |
|
263 if(mvd[i] >= 0) |
|
264 { |
|
265 vlbPutBits(outBuf, sMVTab[motioncode].length, sMVTab[motioncode].code); |
|
266 } |
|
267 else |
|
268 { |
|
269 vlbPutBits(outBuf, sMVTab[motioncode].length, (sMVTab[motioncode].code) ^ 1); |
|
270 } |
|
271 if (rsize != 0 && motioncode != 0) |
|
272 { |
|
273 motionresidual = temp & (f - 1); |
|
274 vlbPutBits(outBuf, rsize, motionresidual); |
|
275 } |
|
276 } |
|
277 return; |
|
278 } |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 /* {{-output"vbmMedian3.txt"}} */ |
|
284 /* |
|
285 * vbmMedian3 |
|
286 * |
|
287 * Parameters: |
|
288 * s1 pointer to the first vector |
|
289 * s2 pointer to the second vector |
|
290 * s3 pointer to the third vector |
|
291 * med pointer to store the median vector |
|
292 * |
|
293 * Function: |
|
294 * This function finds the median of three vectors |
|
295 * |
|
296 * Returns: |
|
297 * Nothing. |
|
298 * |
|
299 * Error codes: |
|
300 * None. |
|
301 * |
|
302 */ |
|
303 void vbmMedian3(int16 *s1, int16 *s2, int16 *s3, tMotionVector *med) |
|
304 { |
|
305 int32 temp1; |
|
306 int32 temp2; |
|
307 int32 temp3; |
|
308 |
|
309 temp1 = s1[0]; |
|
310 temp2 = s2[0]; |
|
311 temp3 = s3[0]; |
|
312 |
|
313 if (temp1 > temp2) |
|
314 { |
|
315 temp1 += temp2; |
|
316 temp2 = temp1 - temp2; |
|
317 temp1 -= temp2; |
|
318 } |
|
319 if (temp2 > temp3) |
|
320 { |
|
321 temp2 += temp3; |
|
322 temp3 = temp2 - temp3; |
|
323 temp2 -= temp3; |
|
324 } |
|
325 if (temp1 > temp2) |
|
326 { |
|
327 temp1 += temp2; |
|
328 temp2 = temp1 - temp2; |
|
329 temp1 -= temp2; |
|
330 } |
|
331 |
|
332 med->mvx = (int16) temp2; |
|
333 temp1 = s1[1]; |
|
334 temp2 = s2[1]; |
|
335 temp3 = s3[1]; |
|
336 |
|
337 if (temp1 > temp2) |
|
338 { |
|
339 temp1 += temp2; |
|
340 temp2 = temp1 - temp2; |
|
341 temp1 -= temp2; |
|
342 } |
|
343 if (temp2 > temp3) |
|
344 { |
|
345 temp2 += temp3; |
|
346 temp3 = temp2 - temp3; |
|
347 temp2 -= temp3; |
|
348 } |
|
349 if (temp1 > temp2) |
|
350 { |
|
351 temp1 += temp2; |
|
352 temp2 = temp1 - temp2; |
|
353 temp1 -= temp2; |
|
354 } |
|
355 med->mvy = (int16) temp2; |
|
356 |
|
357 return; |
|
358 } |
|
359 |
|
360 |
|
361 |
|
362 /* {{-output"vbmMvPrediction.txt"}} */ |
|
363 /* |
|
364 * vbmMvPrediction |
|
365 * |
|
366 * Parameters: |
|
367 * mbi macro block info needed for processing |
|
368 * predMV pointer to motion vector predictors |
|
369 * mbinWidth number of MBs per row |
|
370 * mBCnt mecro block number |
|
371 * |
|
372 * Function: |
|
373 * This function performs prediction of MV based on adjacent blocks |
|
374 * |
|
375 * Returns: |
|
376 * Nothing. |
|
377 * |
|
378 * Error codes: |
|
379 * None. |
|
380 * |
|
381 */ |
|
382 void vbmMvPrediction(tMBInfo *mbi, int32 mBCnt, tMotionVector *predMV, int32 mbinWidth) |
|
383 { |
|
384 int16 p[3][2]; |
|
385 int32 zeroFound = 0; |
|
386 int32 zeroPredictors = 0; |
|
387 |
|
388 if (mBCnt % mbinWidth == 0) |
|
389 { |
|
390 p[0][0] = 0; |
|
391 p[0][1] = 0; |
|
392 zeroPredictors++; |
|
393 } |
|
394 else |
|
395 { |
|
396 p[0][0] = (mbi - 1)->MV[0][0]; |
|
397 p[0][1] = (mbi - 1)->MV[0][1]; |
|
398 } |
|
399 |
|
400 if (mBCnt / mbinWidth == 0) |
|
401 { |
|
402 p[1][0] = 0; |
|
403 p[1][1] = 0; |
|
404 zeroPredictors++; |
|
405 zeroFound += 1; |
|
406 } |
|
407 else |
|
408 { |
|
409 p[1][0] = (mbi - mbinWidth)->MV[0][0]; |
|
410 p[1][1] = (mbi - mbinWidth)->MV[0][1]; |
|
411 } |
|
412 |
|
413 if ((mBCnt / mbinWidth == 0) || |
|
414 ((mBCnt % mbinWidth) == (mbinWidth - 1))) |
|
415 { |
|
416 p[2][0] = 0; |
|
417 p[2][1] = 0; |
|
418 zeroPredictors++; |
|
419 zeroFound += 2; |
|
420 } |
|
421 else |
|
422 { |
|
423 p[2][0] = (mbi - mbinWidth + 1)->MV[0][0]; |
|
424 p[2][1] = (mbi - mbinWidth + 1)->MV[0][1]; |
|
425 } |
|
426 |
|
427 if (zeroPredictors == 3) |
|
428 { |
|
429 predMV->mvx = 0; |
|
430 predMV->mvy = 0; |
|
431 } |
|
432 else if (zeroPredictors == 2) |
|
433 { |
|
434 predMV->mvx = p[zeroFound^3][0]; |
|
435 predMV->mvy = p[zeroFound^3][1]; |
|
436 } |
|
437 else |
|
438 { |
|
439 vbmMedian3(p[0], p[1], p[2], predMV); |
|
440 } |
|
441 return; |
|
442 } |
|
443 |
|
444 |
|
445 |
|
446 /* {{-output"vbmMBSAD.txt"}} */ |
|
447 /* |
|
448 * vbmMBSAD |
|
449 * |
|
450 * Parameters: |
|
451 * refFrame pointer to reference frame |
|
452 * currMB pointer to current MB |
|
453 * mv pointer to store the SAD and having motion vector |
|
454 * mbPos pointer to macroblock position structure |
|
455 * vopWidth width of frame/VOP |
|
456 * yWidth width of luminance frame |
|
457 * |
|
458 * Function: |
|
459 * This function computes the SAD (Sum of Absolute Difference) |
|
460 * for a macroblock for integer motion vector |
|
461 * |
|
462 * Returns: |
|
463 * Nothing. |
|
464 * |
|
465 * Error codes: |
|
466 * None. |
|
467 * |
|
468 */ |
|
469 void vbmMBSAD(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth, |
|
470 tMotionVector* mv, const tMBPosition* mbPos) |
|
471 { |
|
472 u_int32 sad = 0; |
|
473 tPixel* refPos; |
|
474 tPixel* currPos; |
|
475 int32 row; |
|
476 int32 col; |
|
477 |
|
478 refPos = refFrame + (mbPos->y + mv->mvy) * vopWidth + (mbPos->x + mv->mvx); |
|
479 currPos = currMB; |
|
480 |
|
481 for(row = 0; row < MB_SIZE; row++) |
|
482 { |
|
483 col = row & 0x1; |
|
484 for(; col < MB_SIZE; col+= 2) |
|
485 { |
|
486 sad += ABS(*(refPos + col) - *(currPos + col)); |
|
487 } |
|
488 refPos += vopWidth; |
|
489 currPos += yWidth; |
|
490 } |
|
491 mv->SAD = (sad << 1); |
|
492 return; |
|
493 } |
|
494 |
|
495 |
|
496 |
|
497 /* {{-output"vbmMVOutsideBound.txt"}} */ |
|
498 /* |
|
499 * vbmMVOutsideBound |
|
500 * |
|
501 * Parameters: |
|
502 * mbPos pointer to macroblock position structure |
|
503 * bestMV pointer to store the best match motion vector |
|
504 * halfPixel flag to indicate whether half pel search is needed |
|
505 * |
|
506 * Function: |
|
507 * This function checks whether the MV is within valid range |
|
508 * |
|
509 * Returns: |
|
510 * Nothing. |
|
511 * |
|
512 * Error codes: |
|
513 * None. |
|
514 * |
|
515 */ |
|
516 tBool vbmMVOutsideBound(tMBPosition *mbPos, tMotionVector* bestMV, tBool halfPixel) |
|
517 { |
|
518 int32 xLeft; |
|
519 int32 xRight; |
|
520 int32 yTop; |
|
521 int32 yBottom; |
|
522 |
|
523 xLeft = (mbPos->x << halfPixel) + bestMV->mvx; |
|
524 xRight = (mbPos->x << halfPixel) + (MB_SIZE << halfPixel) + bestMV->mvx; |
|
525 yTop = (mbPos->y << halfPixel) + bestMV->mvy; |
|
526 yBottom = (mbPos->y << halfPixel) + (MB_SIZE << halfPixel) + bestMV->mvy; |
|
527 |
|
528 if (halfPixel) |
|
529 { |
|
530 return ((xLeft < mbPos->LeftBound) || |
|
531 (xRight > mbPos->RightBound) || |
|
532 (yTop < mbPos->TopBound) || |
|
533 (yBottom > mbPos->BottomBound) || |
|
534 ((bestMV->mvx) < -32 || (bestMV->mvx) > 31) || |
|
535 ((bestMV->mvy) < -32 || (bestMV->mvy) > 31) |
|
536 ); |
|
537 } |
|
538 else |
|
539 { |
|
540 return ((xLeft < mbPos->LeftBound) || |
|
541 (xRight > mbPos->RightBound) || |
|
542 (yTop < mbPos->TopBound) || |
|
543 (yBottom > mbPos->BottomBound)|| |
|
544 ((bestMV->mvx) < -16 || (bestMV->mvx) > 15) || |
|
545 ((bestMV->mvy) < -16 || (bestMV->mvy) > 15) |
|
546 ); |
|
547 } |
|
548 } |
|
549 |
|
550 |
|
551 |
|
552 /* {{-output"vbmEstimateBestPredictor.txt"}} */ |
|
553 /* |
|
554 * vbmEstimateBestPredictor |
|
555 * |
|
556 * Parameters: |
|
557 * refFrame pointer to reference frame |
|
558 * currMB pointer to current MB |
|
559 * initPred pointer to predictor motion vectors, pixel unit |
|
560 * mbPos pointer to macroblock position structure |
|
561 * vopWidth width of frame/VOP |
|
562 * yWidth width of luminance frame |
|
563 * bestMV pointer to store the best match motion vector |
|
564 * noofPredictors number of predictors |
|
565 * |
|
566 * Function: |
|
567 * This function estimates the best predictor among the set |
|
568 * |
|
569 * Returns: |
|
570 * Nothing. |
|
571 * |
|
572 * Error codes: |
|
573 * None. |
|
574 * |
|
575 */ |
|
576 void vbmEstimateBestPredictor(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth, |
|
577 tMotionVector* initPred, tMBPosition* mbPos, |
|
578 int32 noOfPredictors, tMotionVector* bestMV) |
|
579 { |
|
580 int32 i; |
|
581 bestMV->SAD = 65535; |
|
582 for(i = 0; i < noOfPredictors; i++) |
|
583 { |
|
584 if (vbmMVOutsideBound(mbPos, (initPred + i), 0)) |
|
585 { |
|
586 initPred[i].SAD = 65535; |
|
587 } |
|
588 else |
|
589 { |
|
590 vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos); |
|
591 } |
|
592 if(initPred[i].SAD < bestMV->SAD) |
|
593 { |
|
594 bestMV->SAD = initPred[i].SAD; |
|
595 bestMV->mvx = initPred[i].mvx; |
|
596 bestMV->mvy = initPred[i].mvy; |
|
597 } |
|
598 } |
|
599 |
|
600 return; |
|
601 } |
|
602 |
|
603 |
|
604 |
|
605 /* {{-output"vbmEstimateBound.txt"}} */ |
|
606 /* |
|
607 * vbmEstimateBound |
|
608 * |
|
609 * Parameters: |
|
610 * mbPos pointer to macroblock position structure |
|
611 * vopWidth width of frame/VOP |
|
612 * vopHeight height of frame/VOP |
|
613 * searchRange search range |
|
614 * |
|
615 * Function: |
|
616 * This function evaluates the bounds for a macroblock BM search |
|
617 * |
|
618 * Returns: |
|
619 * Nothing. |
|
620 * |
|
621 * Error codes: |
|
622 * None. |
|
623 * |
|
624 */ |
|
625 void vbmEstimateBound(tMBPosition *mbPos,u_int32 vopWidth, u_int32 vopHeight, int32 searchRange) |
|
626 { |
|
627 mbPos->LeftBound = mbPos->x - searchRange; |
|
628 mbPos->RightBound = mbPos->x + 16 + searchRange; |
|
629 mbPos->TopBound = mbPos->y - searchRange; |
|
630 mbPos->BottomBound = mbPos->y + 16 + searchRange; |
|
631 |
|
632 if(mbPos->LeftBound < 0) |
|
633 { |
|
634 mbPos->LeftBound = 0; |
|
635 } |
|
636 if(mbPos->RightBound > (int32)vopWidth) |
|
637 { |
|
638 mbPos->RightBound = vopWidth; |
|
639 } |
|
640 if(mbPos->TopBound < 0 ) |
|
641 { |
|
642 mbPos->TopBound = 0; |
|
643 } |
|
644 if(mbPos->BottomBound > (int32)vopHeight) |
|
645 { |
|
646 mbPos->BottomBound = vopHeight; |
|
647 } |
|
648 |
|
649 return; |
|
650 } |
|
651 |
|
652 |
|
653 |
|
654 /* {{-output"vbmEstimateBoundHalfPel.txt"}} */ |
|
655 /* |
|
656 * vbmEstimateBoundHalfPel |
|
657 * |
|
658 * Parameters: |
|
659 * mbPos pointer to macroblock position structure |
|
660 * vopWidth width of frame/VOP |
|
661 * vopHeight height of frame/VOP |
|
662 * |
|
663 * Function: |
|
664 * This function evaluates the bounds for a macroblock BM search in half pel accuracy |
|
665 * |
|
666 * Returns: |
|
667 * Nothing. |
|
668 * |
|
669 * Error codes: |
|
670 * None. |
|
671 * |
|
672 */ |
|
673 void vbmEstimateBoundHalfPel(tMBPosition *mbPos, u_int32 vopWidth, u_int32 vopHeight) |
|
674 { |
|
675 mbPos->LeftBound = 0; |
|
676 mbPos->RightBound = (vopWidth << 1); |
|
677 mbPos->TopBound = 0; |
|
678 mbPos->BottomBound = (vopHeight << 1); |
|
679 return; |
|
680 } |
|
681 |
|
682 |
|
683 |
|
684 /* {{-output"vbmSmallDiamondSearch.txt"}} */ |
|
685 /* |
|
686 * vbmSmallDiamondSearch |
|
687 * |
|
688 * Parameters: |
|
689 * refFrame pointer to reference frame |
|
690 * currMB pointer to current MB |
|
691 * initPred pointer to predictor motion vectors, pixel unit |
|
692 * mbPos pointer to macroblock position structure |
|
693 * vopWidth width of frame/VOP |
|
694 * yWidth width of luminance frame |
|
695 * bestMV pointer to store the best match motion vector |
|
696 * Function: |
|
697 * This function performs motion estimation for a macroblock using small diamond search |
|
698 * |
|
699 * Returns: |
|
700 * Nothing. |
|
701 * |
|
702 * Error codes: |
|
703 * None. |
|
704 * |
|
705 */ |
|
706 void vbmSmallDiamondSearch(tPixel* refFrame, tPixel* currMB, tMotionVector *initPred, |
|
707 tMotionVector* bestMV, u_int32 vopWidth, tMBPosition* mbPos, |
|
708 u_int32 yWidth) |
|
709 { |
|
710 u_int8 locateSDS[5][5] = |
|
711 { |
|
712 {0,0,0,0,0}, |
|
713 {0,1,1,0,1}, |
|
714 {0,1,1,1,0}, |
|
715 {0,0,1,1,1}, |
|
716 {0,1,0,1,1} |
|
717 }; |
|
718 u_int32 i; |
|
719 int32 stepCount; |
|
720 int32 flag=1; |
|
721 int32 position=0; |
|
722 |
|
723 //form the diamond shap search pattern |
|
724 stepCount = 1; |
|
725 initPred[0].SAD = bestMV->SAD; |
|
726 initPred[1].mvx = (int16)(bestMV->mvx + 1); |
|
727 initPred[1].mvy = bestMV->mvy; |
|
728 initPred[2].mvx = bestMV->mvx; |
|
729 initPred[2].mvy = (int16)(bestMV->mvy - 1); |
|
730 initPred[3].mvx = (int16)(bestMV->mvx - 1); |
|
731 initPred[3].mvy = bestMV->mvy; |
|
732 initPred[4].mvx = bestMV->mvx; |
|
733 initPred[4].mvy = (int16)(bestMV->mvy + 1); |
|
734 |
|
735 for(i = 1; i < 5; i++) |
|
736 { |
|
737 if(vbmMVOutsideBound(mbPos, &initPred[i], 0) ) |
|
738 { |
|
739 initPred[i].SAD = 65535; |
|
740 } |
|
741 else |
|
742 { |
|
743 vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos); |
|
744 } |
|
745 if(initPred[i].SAD < bestMV->SAD) |
|
746 { |
|
747 bestMV->SAD = initPred[i].SAD; |
|
748 bestMV->mvx = initPred[i].mvx; |
|
749 bestMV->mvy = initPred[i].mvy; |
|
750 position = i; |
|
751 } |
|
752 } |
|
753 |
|
754 /* the minimum SAD falls in the center */ |
|
755 if(bestMV->SAD == initPred[0].SAD) |
|
756 { |
|
757 return; |
|
758 } |
|
759 |
|
760 while(flag) |
|
761 { |
|
762 stepCount++; |
|
763 initPred[0].SAD = bestMV->SAD; |
|
764 initPred[1].mvx = (int16)(bestMV->mvx + 1); |
|
765 initPred[1].mvy = bestMV->mvy; |
|
766 initPred[2].mvx = bestMV->mvx; |
|
767 initPred[2].mvy = (int16)(bestMV->mvy - 1); |
|
768 initPred[3].mvx = (int16)(bestMV->mvx - 1); |
|
769 initPred[3].mvy = bestMV->mvy; |
|
770 initPred[4].mvx = bestMV->mvx; |
|
771 initPred[4].mvy = (int16)(bestMV->mvy + 1); |
|
772 |
|
773 for(i = 1; i < 5; i++) |
|
774 { |
|
775 if(locateSDS[position][i] != 0) |
|
776 { |
|
777 if(vbmMVOutsideBound(mbPos, &initPred[i],0)) |
|
778 { |
|
779 initPred[i].SAD = 65535; |
|
780 } |
|
781 else |
|
782 { |
|
783 vbmMBSAD(refFrame, vopWidth, currMB, yWidth, (initPred + i), mbPos); |
|
784 if(initPred[i].SAD < bestMV->SAD) |
|
785 { |
|
786 bestMV->mvx = initPred[i].mvx; |
|
787 bestMV->mvy = initPred[i].mvy; |
|
788 bestMV->SAD = initPred[i].SAD; |
|
789 position = i; |
|
790 } |
|
791 } |
|
792 } |
|
793 } |
|
794 if(bestMV->SAD == initPred[0].SAD) |
|
795 { |
|
796 break; |
|
797 } |
|
798 if(stepCount > DIAMOND_SEARCH_NUMBER) // we only do 2 diamond search here |
|
799 { |
|
800 break; |
|
801 } |
|
802 } |
|
803 |
|
804 return; |
|
805 } |
|
806 |
|
807 |
|
808 |
|
809 /* {{-output"vbmSADHalfPel.txt"}} */ |
|
810 /* |
|
811 * vbmSADHalfPel |
|
812 * |
|
813 * Parameters: |
|
814 * refFrame pointer to reference frame |
|
815 * currMB pointer to current MB |
|
816 * mbPos pointer to macroblock position structure |
|
817 * vopWidth width of frame/VOP |
|
818 * yWidth width of luminance frame |
|
819 * mv pointer to motion vector |
|
820 * roundingControl rounding control value |
|
821 * blockSize block size |
|
822 * Function: |
|
823 * This function evaluates SAD for a macroblock/block for half pel motion vector |
|
824 * |
|
825 * Returns: |
|
826 * Nothing. |
|
827 * |
|
828 * Error codes: |
|
829 * None. |
|
830 * |
|
831 */ |
|
832 void vbmSADHalfPel(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, u_int32 yWidth, |
|
833 tMotionVector* mv, const tMBPosition* mbPos, tBool roundingControl, |
|
834 int32 blockSize) |
|
835 { |
|
836 u_int32 sad = 0; |
|
837 tPixel* refPos; |
|
838 tPixel* currPos; |
|
839 int32 row; |
|
840 int32 col; |
|
841 int32 extendedVOPWidth; |
|
842 int32 temp; |
|
843 |
|
844 extendedVOPWidth = vopWidth ; |
|
845 refPos = refFrame + (mbPos->y + (mv->mvy >> 1)) * extendedVOPWidth + |
|
846 (mbPos->x + (mv->mvx >> 1)); |
|
847 currPos = currMB; |
|
848 |
|
849 if(mv->mvy & 1) |
|
850 { |
|
851 if(mv->mvx & 1) |
|
852 { |
|
853 /* Both horizontal and vertical components are having half pel */ |
|
854 for(row = 0; row < blockSize; row++) |
|
855 { |
|
856 col = row & 0x1; |
|
857 for(; col < blockSize; col += 2) |
|
858 { |
|
859 temp = (refPos[col] + refPos[col + 1] + |
|
860 refPos[col + extendedVOPWidth] + |
|
861 refPos[col + extendedVOPWidth + 1] + |
|
862 2 -roundingControl) >> 2; |
|
863 sad += ABS(temp - currPos[col]); |
|
864 } |
|
865 refPos += extendedVOPWidth; |
|
866 currPos += yWidth; |
|
867 } |
|
868 mv->SAD = (sad << 1); |
|
869 } |
|
870 else |
|
871 { |
|
872 /* Vertical component is having half pel */ |
|
873 for(row = 0; row < blockSize; row++) |
|
874 { |
|
875 col = row & 0x1; |
|
876 for(; col < blockSize; col += 2) |
|
877 { |
|
878 temp = (refPos[col] + refPos[col + extendedVOPWidth]+ |
|
879 1 -roundingControl) >> 1; |
|
880 sad += ABS(temp - currPos[col]); |
|
881 } |
|
882 refPos += extendedVOPWidth; |
|
883 currPos += yWidth; |
|
884 } |
|
885 mv->SAD = (sad << 1); |
|
886 } |
|
887 } |
|
888 else |
|
889 { |
|
890 if(mv->mvx & 1) |
|
891 { |
|
892 /* Horizontal component is having half pel */ |
|
893 for(row = 0; row < blockSize; row++) |
|
894 { |
|
895 col = row & 0x1; |
|
896 for(; col < blockSize; col += 2) |
|
897 { |
|
898 temp = (refPos[col] + refPos[col + 1] + |
|
899 1 -roundingControl) >> 1; |
|
900 sad += ABS(temp - currPos[col]); |
|
901 } |
|
902 refPos += extendedVOPWidth; |
|
903 currPos += yWidth; |
|
904 } |
|
905 mv->SAD = (sad << 1); |
|
906 } |
|
907 else |
|
908 { |
|
909 /* Both horizontal and vertical components are integer pel */ |
|
910 for(row = 0; row < blockSize; row++) |
|
911 { |
|
912 col = row & 0x1; |
|
913 for(; col < blockSize; col += 2) |
|
914 { |
|
915 sad += ABS(refPos[col] - currPos[col]); |
|
916 } |
|
917 refPos += extendedVOPWidth; |
|
918 currPos += yWidth; |
|
919 } |
|
920 mv->SAD = (sad << 1); |
|
921 } |
|
922 } |
|
923 |
|
924 return; |
|
925 } |
|
926 |
|
927 |
|
928 |
|
929 |
|
930 /* {{-output"vbmHalfPelSearchMB.txt"}} */ |
|
931 /* |
|
932 * vbmHalfPelSearchMB |
|
933 * |
|
934 * Parameters: |
|
935 * refFrame pointer to reference frame |
|
936 * currMB pointer to current MB |
|
937 * mbPos pointer to macroblock position structure |
|
938 * vopWidth width of frame/VOP |
|
939 * yWidth width of luminance frame |
|
940 * initPred pointer to predictor motion vectors, pixel unit |
|
941 * bestMV pointer to store the best match motion vector |
|
942 * Function: |
|
943 * This function evaluates the half pel motion vector for a 16x16 block using |
|
944 * the integer pel motion vector |
|
945 * |
|
946 * Returns: |
|
947 * Nothing. |
|
948 * |
|
949 * Error codes: |
|
950 * None. |
|
951 * |
|
952 */ |
|
953 void vbmHalfPelSearchMB(tPixel* refFrame, u_int32 vopWidth, tPixel* currMB, |
|
954 u_int32 yWidth, tMotionVector* initPred, |
|
955 tMotionVector* bestMV, tMBPosition* mbPos) |
|
956 { |
|
957 int32 i; |
|
958 int32 position=0; |
|
959 |
|
960 initPred[0].SAD = bestMV->SAD; |
|
961 initPred[1].mvx = (int16)(bestMV->mvx + 1); |
|
962 initPred[1].mvy = bestMV->mvy; |
|
963 initPred[2].mvx = bestMV->mvx; |
|
964 initPred[2].mvy = (int16)(bestMV->mvy - 1); |
|
965 initPred[3].mvx = (int16)(bestMV->mvx - 1); |
|
966 initPred[3].mvy = bestMV->mvy; |
|
967 initPred[4].mvx = bestMV->mvx; |
|
968 initPred[4].mvy = (int16)(bestMV->mvy + 1); |
|
969 |
|
970 for(i = 1; i < 5; i++) |
|
971 { |
|
972 if(vbmMVOutsideBound(mbPos, &initPred[i], 1)) |
|
973 { |
|
974 initPred[i].SAD = 65535; |
|
975 } |
|
976 else |
|
977 { |
|
978 vbmSADHalfPel(refFrame, vopWidth, currMB, yWidth, |
|
979 (initPred + i), mbPos,(tBool)(0), 16); |
|
980 } |
|
981 |
|
982 if(initPred[i].SAD < bestMV->SAD) |
|
983 { |
|
984 bestMV->mvx = initPred[i].mvx; |
|
985 bestMV->mvy = initPred[i].mvy; |
|
986 bestMV->SAD = initPred[i].SAD; |
|
987 position = i; |
|
988 } |
|
989 } |
|
990 |
|
991 if(1) |
|
992 { |
|
993 if(bestMV->SAD == initPred[0].SAD) |
|
994 { |
|
995 return; |
|
996 } |
|
997 else |
|
998 { |
|
999 switch(position) |
|
1000 { |
|
1001 case 1: case 3: |
|
1002 initPred[5].mvx = bestMV->mvx; |
|
1003 initPred[5].mvy = (int16)(bestMV->mvy - 1); |
|
1004 initPred[6].mvx = bestMV->mvx; |
|
1005 initPred[6].mvy = (int16)(bestMV->mvy + 1); |
|
1006 break; |
|
1007 |
|
1008 case 2: case 4: |
|
1009 initPred[5].mvx = (int16)(bestMV->mvx - 1); |
|
1010 initPred[5].mvy = bestMV->mvy; |
|
1011 initPred[6].mvx = (int16)(bestMV->mvx + 1); |
|
1012 initPred[6].mvy = bestMV->mvy; |
|
1013 break; |
|
1014 |
|
1015 default: |
|
1016 break; |
|
1017 } |
|
1018 |
|
1019 for(i = 5; i < 7; i++) |
|
1020 { |
|
1021 |
|
1022 if(vbmMVOutsideBound(mbPos, &initPred[i],1)) |
|
1023 { |
|
1024 initPred[i].SAD = 65535; |
|
1025 } |
|
1026 else |
|
1027 { |
|
1028 vbmSADHalfPel(refFrame, vopWidth, currMB, yWidth, |
|
1029 (initPred + i), mbPos, (tBool)0, 16); |
|
1030 } |
|
1031 if(initPred[i].SAD < bestMV->SAD) |
|
1032 { |
|
1033 bestMV->mvx = initPred[i].mvx; |
|
1034 bestMV->mvy = initPred[i].mvy; |
|
1035 bestMV->SAD = initPred[i].SAD; |
|
1036 } |
|
1037 } |
|
1038 } |
|
1039 } |
|
1040 |
|
1041 return; |
|
1042 } |
|
1043 |
|
1044 |
|
1045 |
|
1046 /* {{-output"vbmMEMBSpatioTemporalSearch.txt"}} */ |
|
1047 /* |
|
1048 * vbmMEMBSpatioTemporalSearch |
|
1049 * |
|
1050 * Parameters: |
|
1051 * refFrame pointer to reference frame |
|
1052 * currMB pointer to current MB |
|
1053 * mbPos pointer to macroblock position structure |
|
1054 * vopWidth width of frame/VOP |
|
1055 * vopHeight height of frame/VOP |
|
1056 * yWidth width of luminance frame |
|
1057 * initPred pointer to predictor motion vectors, pixel unit |
|
1058 * bestMV pointer to store the best match motion vector |
|
1059 * noOfPredictors number of MV predictors |
|
1060 * searchRange search range |
|
1061 * minSAD minimum SAD |
|
1062 * Function: |
|
1063 * This function performs motion estimation for a macroblock using |
|
1064 * spatio-temporal correlation based search |
|
1065 * |
|
1066 * Returns: |
|
1067 * Nothing. |
|
1068 * |
|
1069 * Error codes: |
|
1070 * None. |
|
1071 * |
|
1072 */ |
|
1073 int32 vbmMEMBSpatioTemporalSearch(tPixel* refFrame, u_int32 vopWidth, u_int32 vopHeight, |
|
1074 tPixel* currMB, u_int32 yWidth, tMBPosition* mbPos, |
|
1075 tMotionVector *initPred, int32 noOfPredictors, |
|
1076 tMotionVector* bestMV, int32 searchRange, u_int32 minSAD) |
|
1077 { |
|
1078 /* estimate the bound of MV for current MB */ |
|
1079 vbmEstimateBound(mbPos, vopWidth, vopHeight, searchRange); |
|
1080 |
|
1081 /* get the best MV predictor from the candidates set */ |
|
1082 vbmEstimateBestPredictor(refFrame, vopWidth, currMB, yWidth, initPred, mbPos, noOfPredictors, bestMV); |
|
1083 |
|
1084 if(bestMV->SAD >= minSAD) |
|
1085 { |
|
1086 /* from the MV predictor, starts the small diamond search */ |
|
1087 vbmSmallDiamondSearch(refFrame, currMB, initPred, bestMV, vopWidth, mbPos, yWidth); |
|
1088 } |
|
1089 |
|
1090 /* adjustment for half-pixel search */ |
|
1091 bestMV->mvx <<= 1; |
|
1092 bestMV->mvy <<= 1; |
|
1093 |
|
1094 /* MV bound in half-pixel */ |
|
1095 vbmEstimateBoundHalfPel(mbPos,vopWidth, vopHeight); |
|
1096 |
|
1097 /* starts the half-pixel search around the integer-pixel MV */ |
|
1098 vbmHalfPelSearchMB(refFrame, vopWidth, currMB, yWidth, |
|
1099 initPred, bestMV, mbPos); |
|
1100 |
|
1101 return bestMV->SAD; |
|
1102 } |
|
1103 |
|
1104 |
|
1105 |
|
1106 /* {{-output"vbmRowDCT.txt"}} */ |
|
1107 /* |
|
1108 * vbmRowDCT |
|
1109 * |
|
1110 * Parameters: |
|
1111 * block array of 64 block coefficients |
|
1112 * Function: |
|
1113 * This function performs row DCT of 8x8 block of data elements |
|
1114 * |
|
1115 * Returns: |
|
1116 * Nothing. |
|
1117 * |
|
1118 * Error codes: |
|
1119 * None. |
|
1120 * |
|
1121 */ |
|
1122 void vbmRowDCT(int16 *block) |
|
1123 { |
|
1124 int32 coeff0, coeff1, coeff2, coeff3; |
|
1125 int32 coeff4, coeff5, coeff6, coeff7; |
|
1126 int32 temp; |
|
1127 u_int16 count; |
|
1128 int32 rowStartIndex; |
|
1129 |
|
1130 for(count = 0; count < BLOCK_SIZE; count++) |
|
1131 { |
|
1132 rowStartIndex = count << LOG_BLOCK_WIDTH; |
|
1133 |
|
1134 /* Stage 1 and up scaling of the input data to improve precision */ |
|
1135 coeff0 = (block[rowStartIndex] + block[rowStartIndex + 7]) << |
|
1136 DCT_KEPT_PRECISION; |
|
1137 coeff7 = (block[rowStartIndex] - block[rowStartIndex + 7]) << |
|
1138 DCT_KEPT_PRECISION; |
|
1139 |
|
1140 coeff1 = (block[rowStartIndex + 1] + block[rowStartIndex + 6]) << |
|
1141 DCT_KEPT_PRECISION; |
|
1142 coeff6 = (block[rowStartIndex + 1] - block[rowStartIndex + 6]) << |
|
1143 DCT_KEPT_PRECISION; |
|
1144 |
|
1145 coeff2 = (block[rowStartIndex + 2] + block[rowStartIndex + 5]) << |
|
1146 DCT_KEPT_PRECISION; |
|
1147 coeff5 = (block[rowStartIndex + 2] - block[rowStartIndex + 5]) << |
|
1148 DCT_KEPT_PRECISION; |
|
1149 |
|
1150 coeff3 = (block[rowStartIndex + 3] + block[rowStartIndex + 4]) << |
|
1151 DCT_KEPT_PRECISION; |
|
1152 coeff4 = (block[rowStartIndex + 3] - block[rowStartIndex + 4]) << |
|
1153 DCT_KEPT_PRECISION; |
|
1154 |
|
1155 /* Stage 2 */ |
|
1156 temp = coeff0 + coeff3; |
|
1157 coeff3 = coeff0 - coeff3; |
|
1158 coeff0 = temp; |
|
1159 |
|
1160 temp = coeff1 + coeff2; |
|
1161 coeff2 = coeff1 - coeff2; |
|
1162 coeff1 = temp; |
|
1163 |
|
1164 temp = ((coeff6 - coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION; |
|
1165 coeff6 = ((coeff6 + coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION; |
|
1166 coeff5 = temp; |
|
1167 |
|
1168 /* Stage 3 */ |
|
1169 temp = coeff0 + coeff1; |
|
1170 coeff1 = coeff0 - coeff1; |
|
1171 coeff0 = temp; |
|
1172 |
|
1173 temp = ((coeff2 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) + coeff3; |
|
1174 coeff3 = ((coeff3 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) - coeff2; |
|
1175 coeff2 = temp; |
|
1176 |
|
1177 temp = coeff4 + coeff5; |
|
1178 coeff5 = coeff4 - coeff5; |
|
1179 coeff4 = temp; |
|
1180 |
|
1181 temp = coeff7 - coeff6; |
|
1182 coeff7 = coeff7 + coeff6; |
|
1183 coeff6 = temp; |
|
1184 |
|
1185 /* Stage 4 */ |
|
1186 temp = ((coeff4 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) + coeff7; |
|
1187 coeff7 = ((coeff7 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) - coeff4; |
|
1188 coeff4 = temp; |
|
1189 |
|
1190 temp = coeff5 + ((coeff6 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION); |
|
1191 coeff6 = coeff6 - ((coeff5 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION); |
|
1192 coeff5 = temp; |
|
1193 |
|
1194 block[rowStartIndex] = (int16)coeff0; |
|
1195 block[rowStartIndex + 4] = (int16)coeff1; |
|
1196 block[rowStartIndex + 2] = (int16)coeff2; |
|
1197 block[rowStartIndex + 6] = (int16)coeff3; |
|
1198 block[rowStartIndex + 1] = (int16)coeff4; |
|
1199 block[rowStartIndex + 5] = (int16)coeff5; |
|
1200 block[rowStartIndex + 3] = (int16)coeff6; |
|
1201 block[rowStartIndex + 7] = (int16)coeff7; |
|
1202 } |
|
1203 |
|
1204 return; |
|
1205 } |
|
1206 |
|
1207 |
|
1208 |
|
1209 /* {{-output"vbmDCTQuantInterSVH.txt"}} */ |
|
1210 /* |
|
1211 * vbmDCTQuantInterSVH |
|
1212 * |
|
1213 * Parameters: |
|
1214 * block array of 64 block coefficients |
|
1215 * mbi contains info about MB quantization scale and coding type |
|
1216 * lastPosition indicates last non zero coefficient |
|
1217 * Function: |
|
1218 * This function performs DCT of a 8x8 block of data elements and |
|
1219 * quantizes the DCT coefficients with short video header flag set |
|
1220 * |
|
1221 * Returns: |
|
1222 * Nothing. |
|
1223 * |
|
1224 * Error codes: |
|
1225 * None. |
|
1226 * |
|
1227 */ |
|
1228 void vbmDCTQuantInterSVH(int16 *block, tMBInfo *mbi, int32* lastPosition) |
|
1229 { |
|
1230 int32 coeff0, coeff1, coeff2, coeff3; |
|
1231 int32 coeff4, coeff5, coeff6, coeff7; |
|
1232 int32 temp; |
|
1233 u_int16 count; |
|
1234 int32 sign; |
|
1235 |
|
1236 vbmRowDCT(block); |
|
1237 |
|
1238 for(count = 0; count < BLOCK_SIZE; count++) |
|
1239 { |
|
1240 /* Stage 1 */ |
|
1241 coeff0 = block[count] + block[count + 56]; |
|
1242 coeff7 = block[count] - block[count + 56]; |
|
1243 |
|
1244 coeff1 = block[count + 8] + block[count + 48]; |
|
1245 coeff6 = block[count + 8] - block[count + 48]; |
|
1246 |
|
1247 coeff2 = block[count + 16] + block[count + 40]; |
|
1248 coeff5 = block[count + 16] - block[count + 40]; |
|
1249 |
|
1250 coeff3 = block[count + 24] + block[count + 32]; |
|
1251 coeff4 = block[count + 24] - block[count + 32]; |
|
1252 |
|
1253 /* Stage 2 */ |
|
1254 temp = coeff0 + coeff3; |
|
1255 coeff3 = coeff0 - coeff3; |
|
1256 coeff0 = temp; |
|
1257 |
|
1258 temp = coeff1 + coeff2; |
|
1259 coeff2 = coeff1 - coeff2; |
|
1260 coeff1 = temp; |
|
1261 |
|
1262 temp = ((coeff6 - coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION; |
|
1263 coeff6 = ((coeff6 + coeff5) * COS_PI_BY_4 + DCT_ROUND) >> DCT_PRECISION; |
|
1264 coeff5 = temp; |
|
1265 |
|
1266 /* Stage 3 */ |
|
1267 temp = coeff0 + coeff1; |
|
1268 coeff1 = coeff0 - coeff1; |
|
1269 coeff0 = temp; |
|
1270 |
|
1271 temp = ((coeff2 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) + coeff3; |
|
1272 coeff3 = ((coeff3 * TAN_PI_BY_8 + DCT_ROUND) >> DCT_PRECISION) - coeff2; |
|
1273 coeff2 = temp; |
|
1274 |
|
1275 temp = coeff4 + coeff5; |
|
1276 coeff5 = coeff4 - coeff5; |
|
1277 coeff4 = temp; |
|
1278 |
|
1279 temp = coeff7 - coeff6; |
|
1280 coeff7 = coeff7 + coeff6; |
|
1281 coeff6 = temp; |
|
1282 |
|
1283 /* Stage 4 */ |
|
1284 temp = ((coeff4 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) + coeff7; |
|
1285 coeff7 = ((coeff7 * TAN_PI_BY_16 + DCT_ROUND) >> DCT_PRECISION) - coeff4; |
|
1286 coeff4 = temp; |
|
1287 |
|
1288 temp = coeff5 + ((coeff6 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION); |
|
1289 coeff6 = coeff6 - ((coeff5 * TAN_3PI_BY_16 + DCT_ROUND) >> DCT_PRECISION); |
|
1290 coeff5 = temp; |
|
1291 |
|
1292 block[count] = (int16) ( (coeff0* sPrePostMult[count] + |
|
1293 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1294 block[count + 32] = (int16) ((coeff1* sPrePostMult[count+32] + |
|
1295 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1296 block[count + 16] = (int16) ((coeff2* sPrePostMult[count+16] + |
|
1297 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1298 block[count + 48] = (int16) ((coeff3* sPrePostMult[count+48] + |
|
1299 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1300 block[count + 8] = (int16) ((coeff4* sPrePostMult[count+8] + |
|
1301 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1302 block[count + 40] = (int16) ((coeff5* sPrePostMult[count+40] + |
|
1303 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1304 block[count + 24] = (int16) ((coeff6* sPrePostMult[count+24] + |
|
1305 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1306 block[count + 56] = (int16) ((coeff7* sPrePostMult[count+56] + |
|
1307 DCT_ROUND_PLUS_KEPT) >> DCT_PRECISION_PLUS_KEPT); |
|
1308 |
|
1309 coeff1 = mbi->QuantScale; |
|
1310 temp= count; |
|
1311 while(temp<64) |
|
1312 { |
|
1313 coeff0 = (int32) block[temp]; |
|
1314 if (coeff0 >= 0) { |
|
1315 sign = 1; |
|
1316 } |
|
1317 else{ |
|
1318 sign = -1; |
|
1319 } |
|
1320 coeff0 = sign * coeff0; |
|
1321 |
|
1322 if (coeff0 < ((coeff1 * 5 ) >> 1)) |
|
1323 { |
|
1324 block[temp] = 0; |
|
1325 } |
|
1326 else |
|
1327 { |
|
1328 coeff0 -= (coeff1 >> 1); |
|
1329 coeff0 += 1; |
|
1330 coeff0 *= sFixedQuantScale1[coeff1]; |
|
1331 coeff0 >>= FIXED_PT_BITS; |
|
1332 coeff0 *= sign; |
|
1333 |
|
1334 if (coeff0 > MAX_SAT_VAL_SVH) |
|
1335 { |
|
1336 coeff0 = MAX_SAT_VAL_SVH; |
|
1337 } |
|
1338 else if (coeff0 < MIN_SAT_VAL_SVH) |
|
1339 { |
|
1340 coeff0 = MIN_SAT_VAL_SVH; |
|
1341 } |
|
1342 |
|
1343 block[temp] = (int16) coeff0; |
|
1344 if( temp > (*lastPosition)) *lastPosition = temp; |
|
1345 } |
|
1346 temp = temp+8; |
|
1347 } |
|
1348 } |
|
1349 |
|
1350 return; |
|
1351 } |
|
1352 |
|
1353 |
|
1354 |
|
1355 /* {{-output"vbmCBPYInter.txt"}} */ |
|
1356 /* |
|
1357 * vbmCBPYInter |
|
1358 * |
|
1359 * Parameters: |
|
1360 * mbi contains info about MB quantization scale and coding type |
|
1361 * lastPosition indicates last non zero coefficient |
|
1362 * Function: |
|
1363 * This function evaluates the coded bit pattern of the Inter MB |
|
1364 * |
|
1365 * Returns: |
|
1366 * Nothing. |
|
1367 * |
|
1368 * Error codes: |
|
1369 * None. |
|
1370 * |
|
1371 */ |
|
1372 void vbmCBPYInter(tMBInfo *mbi, int32* lastPosition) |
|
1373 { |
|
1374 int32 blkCnt; |
|
1375 |
|
1376 mbi->CodedBlockPattern = 0; |
|
1377 for (blkCnt = 0; blkCnt < 6; blkCnt++) |
|
1378 { |
|
1379 mbi->CodedBlockPattern <<= 1; |
|
1380 |
|
1381 if(lastPosition[blkCnt] != -1) |
|
1382 { |
|
1383 mbi->CodedBlockPattern |= 1; |
|
1384 } |
|
1385 } |
|
1386 |
|
1387 return; |
|
1388 } |
|
1389 |
|
1390 |
|
1391 |
|
1392 /* {{-output"vbmCBPYInter.txt"}} */ |
|
1393 /* |
|
1394 * vbmCBPYInter |
|
1395 * |
|
1396 * Parameters: |
|
1397 * refFrame reference frame |
|
1398 * currBlockPos current block |
|
1399 * block block for storing the difference between predicted and |
|
1400 * actual pixel values. |
|
1401 * mv motion vector for the block in half pixel unit |
|
1402 * x x-coordinate for the first pixel of block |
|
1403 * y y-coordinate for the first pixel of block |
|
1404 * refFrameWidth width of the reference frame |
|
1405 * curFrameWidth width of current Frame |
|
1406 * extendVopSize extension of the frame width |
|
1407 * Function: |
|
1408 * This function finds the predicted block from the reference frame and |
|
1409 * copies the predicted frame into the current frame |
|
1410 * |
|
1411 * Returns: |
|
1412 * Nothing. |
|
1413 * |
|
1414 * Error codes: |
|
1415 * None. |
|
1416 * |
|
1417 */ |
|
1418 int32 vbmPredictBlock(tPixel *refFrame, int32 refFrameWidth, u_int32 extendVopSize, |
|
1419 tPixel *currBlockPos, int32 curFrameWidth, |
|
1420 int16 *block, tMotionVector *mv, int32 x, int32 y) |
|
1421 { |
|
1422 int32 count1, count2; |
|
1423 u_int8 *tempFrame, *tempFrame1, *tempFrame2; |
|
1424 int32 tempVal, sad; |
|
1425 int32 extframeWidth; |
|
1426 extframeWidth = refFrameWidth + 2 * extendVopSize; /* Because of padding */ |
|
1427 |
|
1428 /* |
|
1429 * Since the frame is appended by 8 rows and 8 colums on all sides |
|
1430 * 0,0 of referenceframe will now be frameStartPoint |
|
1431 */ |
|
1432 |
|
1433 tempFrame = refFrame + extframeWidth * extendVopSize + extendVopSize |
|
1434 + ((y + (mv->mvy >> 1)) * extframeWidth) + x + (mv->mvx >> 1); |
|
1435 tempFrame2 = currBlockPos; |
|
1436 |
|
1437 if (mv->mvy & 1) /* Motion vector of y has half pel accuracy */ |
|
1438 { |
|
1439 if (mv->mvx & 1) /* MV has half pel value in both coordinates */ |
|
1440 { |
|
1441 tempFrame1 = tempFrame + extframeWidth; |
|
1442 sad=0; |
|
1443 for (count1 = 0; count1 < BLOCK_SIZE; count1++) |
|
1444 { |
|
1445 count2 = 0; |
|
1446 tempVal = (tempFrame[count2] |
|
1447 + tempFrame[count2 + 1] |
|
1448 + tempFrame1[count2] |
|
1449 + tempFrame1[count2 + 1]+ 2) >> 2; |
|
1450 |
|
1451 block[count2] = (int16)(tempFrame2[count2] - tempVal); |
|
1452 sad+=ABS(block[count2]); |
|
1453 tempVal = (tempFrame[count2 + 1] |
|
1454 + tempFrame[count2 + 2] |
|
1455 + tempFrame1[count2 + 1] |
|
1456 + tempFrame1[count2 + 2]+ 2) >> 2; |
|
1457 |
|
1458 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal); |
|
1459 sad+=ABS(block[count2+1]); |
|
1460 tempVal = (tempFrame[count2 + 2] |
|
1461 + tempFrame[count2 + 3] |
|
1462 + tempFrame1[count2 + 2] |
|
1463 + tempFrame1[count2 + 3]+ 2) >> 2; |
|
1464 |
|
1465 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal); |
|
1466 sad+=ABS(block[count2+2]); |
|
1467 tempVal = (tempFrame[count2 + 3] |
|
1468 + tempFrame[count2 + 4] |
|
1469 + tempFrame1[count2 + 3] |
|
1470 + tempFrame1[count2 + 4]+ 2) >> 2; |
|
1471 |
|
1472 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal); |
|
1473 sad+=ABS(block[count2+3]); |
|
1474 tempVal = (tempFrame[count2 + 4] |
|
1475 + tempFrame[count2 + 5] |
|
1476 + tempFrame1[count2 + 4] |
|
1477 + tempFrame1[count2 + 5]+ 2) >> 2; |
|
1478 |
|
1479 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal); |
|
1480 sad+=ABS(block[count2+4]); |
|
1481 tempVal = (tempFrame[count2 + 5] |
|
1482 + tempFrame[count2 + 6] |
|
1483 + tempFrame1[count2 + 5] |
|
1484 + tempFrame1[count2 + 6]+ 2) >> 2; |
|
1485 |
|
1486 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal); |
|
1487 sad+=ABS(block[count2+5]); |
|
1488 tempVal = (tempFrame[count2+ 6] |
|
1489 + tempFrame[count2 + 7] |
|
1490 + tempFrame1[count2 + 6] |
|
1491 + tempFrame1[count2 + 7]+ 2) >> 2; |
|
1492 |
|
1493 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal); |
|
1494 sad+=ABS(block[count2+6]); |
|
1495 tempVal = (tempFrame[count2 + 7] |
|
1496 + tempFrame[count2 + 8] |
|
1497 + tempFrame1[count2 + 7] |
|
1498 + tempFrame1[count2 + 8]+ 2) >> 2; |
|
1499 |
|
1500 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal); |
|
1501 sad+=ABS(block[count2+7]); |
|
1502 block += BLOCK_SIZE; |
|
1503 tempFrame += extframeWidth; |
|
1504 tempFrame1 += extframeWidth; |
|
1505 tempFrame2 += curFrameWidth; |
|
1506 } |
|
1507 } |
|
1508 else /* MV has half pel only in y direction */ |
|
1509 { |
|
1510 tempFrame1 = tempFrame + extframeWidth; |
|
1511 sad=0; |
|
1512 for (count1 = 0; count1 < BLOCK_SIZE; count1++) |
|
1513 { |
|
1514 count2 = 0; |
|
1515 tempVal = (tempFrame[count2] |
|
1516 + tempFrame1[count2]+ 1) >> 1; |
|
1517 |
|
1518 block[count2] = (int16)(tempFrame2[count2] - tempVal); |
|
1519 sad+=ABS(block[count2]); |
|
1520 tempVal = (tempFrame[count2 + 1] |
|
1521 + tempFrame1[count2 + 1]+ 1) >> 1; |
|
1522 |
|
1523 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal); |
|
1524 sad+=ABS(block[count2+1]); |
|
1525 tempVal = (tempFrame[count2 + 2] |
|
1526 + tempFrame1[count2 + 2]+ 1) >> 1; |
|
1527 |
|
1528 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal); |
|
1529 sad+=ABS(block[count2+2]); |
|
1530 tempVal = (tempFrame[count2 + 3]+ tempFrame1[count2 + 3]+1) >> 1; |
|
1531 |
|
1532 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal); |
|
1533 sad+=ABS(block[count2+3]); |
|
1534 tempVal = (tempFrame[count2 + 4] |
|
1535 + tempFrame1[count2 + 4]+ 1) >> 1; |
|
1536 |
|
1537 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal); |
|
1538 sad+=ABS(block[count2+4]); |
|
1539 tempVal = (tempFrame[count2 + 5] |
|
1540 + tempFrame1[count2 + 5]+ 1) >> 1; |
|
1541 |
|
1542 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal); |
|
1543 sad+=ABS(block[count2+5]); |
|
1544 tempVal = (tempFrame[count2+ 6] |
|
1545 + tempFrame1[count2 + 6]+ 1) >> 1; |
|
1546 |
|
1547 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal); |
|
1548 sad+=ABS(block[count2+6]); |
|
1549 tempVal = (tempFrame[count2 + 7] |
|
1550 + tempFrame1[count2 + 7]+ 1) >> 1; |
|
1551 |
|
1552 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal); |
|
1553 sad+=ABS(block[count2+7]); |
|
1554 block += BLOCK_SIZE; |
|
1555 tempFrame += extframeWidth; |
|
1556 tempFrame1 += extframeWidth; |
|
1557 tempFrame2 += curFrameWidth; |
|
1558 } |
|
1559 } |
|
1560 } |
|
1561 else |
|
1562 { |
|
1563 if (mv->mvx & 1) /* MV has half pel only in x direction */ |
|
1564 { |
|
1565 sad=0; |
|
1566 for (count1 = 0; count1 < BLOCK_SIZE; count1++) |
|
1567 { |
|
1568 count2 = 0; |
|
1569 tempVal = (tempFrame[count2] |
|
1570 + tempFrame[count2 + 1]+1) >> 1; |
|
1571 |
|
1572 block[count2] = (int16)(tempFrame2[count2] - tempVal); |
|
1573 sad+=ABS(block[count2]); |
|
1574 tempVal = (tempFrame[count2 + 1] |
|
1575 + tempFrame[count2 + 2]+ 1) >> 1; |
|
1576 |
|
1577 block[count2 + 1] = (int16)(tempFrame2[count2 + 1] - tempVal); |
|
1578 sad+=ABS(block[count2+1]); |
|
1579 tempVal = (tempFrame[count2 + 2] |
|
1580 + tempFrame[count2 + 3]+ 1) >> 1; |
|
1581 |
|
1582 block[count2 + 2] = (int16)(tempFrame2[count2 + 2] - tempVal); |
|
1583 sad+=ABS(block[count2+2]); |
|
1584 tempVal = (tempFrame[count2 + 3] |
|
1585 + tempFrame[count2 + 4]+1) >> 1; |
|
1586 |
|
1587 block[count2 + 3] = (int16)(tempFrame2[count2 + 3] - tempVal); |
|
1588 sad+=ABS(block[count2+3]); |
|
1589 tempVal = (tempFrame[count2 + 4] |
|
1590 + tempFrame[count2 + 5]+ 1) >> 1; |
|
1591 |
|
1592 block[count2 + 4] = (int16)(tempFrame2[count2 + 4] - tempVal); |
|
1593 sad+=ABS(block[count2+4]); |
|
1594 tempVal = (tempFrame[count2 + 5] |
|
1595 + tempFrame[count2 + 6]+ 1) >> 1; |
|
1596 |
|
1597 block[count2 + 5] = (int16)(tempFrame2[count2 + 5] - tempVal); |
|
1598 sad+=ABS(block[count2+5]); |
|
1599 tempVal = (tempFrame[count2+ 6] |
|
1600 + tempFrame[count2 + 7] |
|
1601 + 1) >> 1; |
|
1602 |
|
1603 block[count2 + 6] = (int16)(tempFrame2[count2 + 6] - tempVal); |
|
1604 sad+=ABS(block[count2+6]); |
|
1605 tempVal = (tempFrame[count2 + 7] |
|
1606 + tempFrame[count2 + 8]+ 1) >> 1; |
|
1607 |
|
1608 block[count2 + 7] = (int16)(tempFrame2[count2 + 7] - tempVal); |
|
1609 sad+=ABS(block[count2+7]); |
|
1610 block += BLOCK_SIZE; |
|
1611 tempFrame += extframeWidth; |
|
1612 tempFrame2 += curFrameWidth; |
|
1613 } |
|
1614 } |
|
1615 else /* MV has full pel accuracy in both coordinates */ |
|
1616 { |
|
1617 sad=0; |
|
1618 for (count1 = 0; count1 < BLOCK_SIZE; count1++) |
|
1619 { |
|
1620 for (count2 = 0; count2 < BLOCK_SIZE; count2++) |
|
1621 { |
|
1622 block[count2] = (int16)(tempFrame2[count2]- tempFrame[count2]); |
|
1623 sad+=ABS(block[count2]); |
|
1624 } |
|
1625 block += BLOCK_SIZE; |
|
1626 tempFrame += extframeWidth; |
|
1627 tempFrame2 += curFrameWidth; |
|
1628 } |
|
1629 } |
|
1630 } |
|
1631 return sad; |
|
1632 } |
|
1633 |
|
1634 |
|
1635 |
|
1636 |
|
1637 /* {{-output"vbmPutInterMBSVH.txt"}} */ |
|
1638 /* |
|
1639 * vbmPutInterMBSVH |
|
1640 * |
|
1641 * Parameters: |
|
1642 * outBuf pointer to the output bit-stream buffer structure |
|
1643 * mbData pointer to the macro block data structure |
|
1644 * mbi pointer to macro block information structure. |
|
1645 * numTextureBits pointer to store the number of bits needed to encode macro block |
|
1646 * predMV pointer to the predicted motion vector data |
|
1647 * lastPos pointer to last non-zero position of each block in the macro block |
|
1648 * colorEffect color effect applied |
|
1649 * Function: |
|
1650 * This function encodes INTER macroblock in SVH mode |
|
1651 * |
|
1652 * Returns: |
|
1653 * Nothing. |
|
1654 * |
|
1655 * Error codes: |
|
1656 * None. |
|
1657 * |
|
1658 */ |
|
1659 void vbmPutInterMBSVH(tMacroblockData* mbData, tMBInfo* mbi, bibBuffer_t *outBuf, |
|
1660 int32 *numTextureBits, tMotionVector* predMV, int32* lastPos, |
|
1661 int16 colorEffect) |
|
1662 { |
|
1663 int32 dQuant; |
|
1664 int32 mcbpcVal; |
|
1665 int32 index; |
|
1666 int32 cbpy; |
|
1667 int32 textureBits; |
|
1668 int16* coeff; |
|
1669 int32 len; |
|
1670 |
|
1671 vlbPutBits(outBuf, 1, mbi->SkippedMB); |
|
1672 if(mbi->SkippedMB == ON) |
|
1673 { |
|
1674 *numTextureBits = 0; |
|
1675 return; |
|
1676 } |
|
1677 |
|
1678 dQuant = mbi->dQuant; |
|
1679 mcbpcVal = colorEffect? 0 : (mbi->CodedBlockPattern & 3); |
|
1680 cbpy = (~((mbi->CodedBlockPattern >> 2) & 0xf)) & 0xf; |
|
1681 |
|
1682 /* only ONE MV in baseline H263 */ |
|
1683 index = (dQuant == 0 ? 0 : 4) + mcbpcVal; |
|
1684 len = sCBPCPType[index].length + sCBPY[cbpy].length; |
|
1685 mcbpcVal = (sCBPCPType[index].code << sCBPY[cbpy].length) | sCBPY[cbpy].code; |
|
1686 |
|
1687 vlbPutBits(outBuf, len, mcbpcVal); |
|
1688 |
|
1689 if(dQuant != 0) |
|
1690 { |
|
1691 vlbPutBits(outBuf, 2, sDquant[dQuant + 2]); |
|
1692 } |
|
1693 |
|
1694 /* encode motion vectors */ |
|
1695 { |
|
1696 vbmEncodeMVDifferential(mbi->MV[0][0] - predMV[0].mvx, |
|
1697 mbi->MV[0][1] - predMV[0].mvy, |
|
1698 1, outBuf); |
|
1699 } |
|
1700 |
|
1701 /* encode texture coefficents */ |
|
1702 textureBits = 0; |
|
1703 cbpy = 32; |
|
1704 for (index = 0; index < (colorEffect ? 4 : 6); index++) |
|
1705 { |
|
1706 if(cbpy & mbi->CodedBlockPattern) |
|
1707 { |
|
1708 coeff = mbData->Data + index * 64; |
|
1709 textureBits += vlbCodeACCoeffsSVHWithZigZag(0, coeff, outBuf, ON, lastPos[index]); |
|
1710 } |
|
1711 cbpy >>= 1; |
|
1712 } |
|
1713 *numTextureBits = textureBits; |
|
1714 |
|
1715 return; |
|
1716 } |
|
1717 |
|
1718 /* |
|
1719 ******************************************************************************* |
|
1720 Name : vbmPutInterMB |
|
1721 Description : INTER macroblock is encoded here. |
|
1722 Parameter : |
|
1723 mbData: Pointer to the macro block data structure |
|
1724 mbi: Pointer to the macro block information structure. |
|
1725 vopData: Pointer to the VOP data structure. |
|
1726 currFrame: Pointer to the current frame data |
|
1727 mbNo: The number macro block being encoded. |
|
1728 numTextureBits:Pointer to store the number of bits taken to encode the macro block. |
|
1729 prevQuant: Pointer to the quantization sacle. |
|
1730 blockSAD: Pointer to store the block SAD values. |
|
1731 outBuf: Pointer to the output bit-stream buffer structure |
|
1732 mvi: Pointer to the MV array |
|
1733 Return Value : void |
|
1734 ******************************************************************************* |
|
1735 */ |
|
1736 /* {{-output"vbmPutInterMB.txt"}} */ |
|
1737 /* |
|
1738 * vbmPutInterMB |
|
1739 * |
|
1740 * Parameters: |
|
1741 * outBuf pointer to the output bit-stream buffer structure |
|
1742 * mbPos pointer to macroblock position structure |
|
1743 * paramMB pointer to macroblock parameters structure |
|
1744 * initPred pointer to predictor motion vectors, pixel unit |
|
1745 * noOfPredictors number of MV predictors |
|
1746 * numTextureBits pointer to store the number of bits needed to encode macro block |
|
1747 * colorEffect color effect applied |
|
1748 * vopWidth width of frame/VOP |
|
1749 * vopHeight height of frame/VOP |
|
1750 * mbsinfo pointer to macro block information structure |
|
1751 * searchRange search range |
|
1752 * Function: |
|
1753 * This function encodes INTER macroblock |
|
1754 * |
|
1755 * Returns: |
|
1756 * Nothing. |
|
1757 * |
|
1758 * Error codes: |
|
1759 * None. |
|
1760 * |
|
1761 */ |
|
1762 void vbmPutInterMB(tMBPosition* mbPos, bibBuffer_t *outBuf, dmdPParam_t *paramMB, |
|
1763 tMotionVector *initPred, int32 noOfPredictors, u_int32 vopWidth, |
|
1764 u_int32 vopHeight,int32 searchRange, int32 mbNo, |
|
1765 int32* numTextureBits, int16 colorEffect, tMBInfo *mbsinfo) |
|
1766 { |
|
1767 int32 blkCnt; |
|
1768 tMotionVector predMV[4]; |
|
1769 int32 lastPosition[6] = {-1,-1,-1,-1,-1,-1}; |
|
1770 tPixel *currBlockPos = NULL; |
|
1771 tMotionVector bestMV; |
|
1772 tMacroblockData mbData; |
|
1773 tMBInfo *mbi = mbsinfo + mbNo; |
|
1774 mbi->SkippedMB = OFF; |
|
1775 u_int32 yWidth = paramMB->uvWidth * 2; |
|
1776 |
|
1777 bestMV.mvx = 0; |
|
1778 bestMV.mvy = 0; |
|
1779 bestMV.SAD = MB_SIZE * MB_SIZE / 2; // quich search stop threshold |
|
1780 |
|
1781 vbmMEMBSpatioTemporalSearch(paramMB->refY, vopWidth,vopHeight,paramMB->currYMBInFrame, yWidth, |
|
1782 mbPos, initPred, noOfPredictors, &bestMV, |
|
1783 searchRange, bestMV.SAD); |
|
1784 |
|
1785 /* update MV buffer */ |
|
1786 mbi->MV[0][0] = bestMV.mvx; |
|
1787 mbi->MV[0][1] = bestMV.mvy; |
|
1788 mbi->SAD = bestMV.SAD; |
|
1789 currBlockPos = paramMB->currYMBInFrame; |
|
1790 |
|
1791 for (blkCnt= 0; blkCnt < 4; blkCnt++) |
|
1792 { |
|
1793 int blkPosX, blkPosY; |
|
1794 blkPosX = (blkCnt & 1) ? mbPos->x + 8 : mbPos->x; |
|
1795 blkPosY = (blkCnt & 2) ? mbPos->y + 8 : mbPos->y; |
|
1796 |
|
1797 vbmPredictBlock(paramMB->refY, vopWidth, 0, currBlockPos, yWidth, |
|
1798 &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1799 &bestMV, blkPosX, blkPosY); |
|
1800 vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1801 mbi, &(lastPosition[blkCnt])); |
|
1802 currBlockPos += 8; |
|
1803 if (blkCnt & 1) |
|
1804 currBlockPos += 8 * yWidth - 16; |
|
1805 } |
|
1806 |
|
1807 if (!colorEffect) |
|
1808 { |
|
1809 /* Find the Chrominance Block Motion vectors */ |
|
1810 tMotionVector lChrMv; |
|
1811 |
|
1812 lChrMv.mvx = (int16)(bestMV.mvx % 4 == 0 ? bestMV.mvx >> 1 : (bestMV.mvx >> 1) | 1); |
|
1813 lChrMv.mvy = (int16)(bestMV.mvy % 4 == 0 ? bestMV.mvy >> 1 : (bestMV.mvy >> 1) | 1); |
|
1814 blkCnt = 4; /* U */ |
|
1815 vbmPredictBlock(paramMB->refU, paramMB->uvWidth, 0, paramMB->currUBlkInFrame, paramMB->uvWidth, |
|
1816 &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1817 &lChrMv, mbPos->x >> 1, mbPos->y >> 1); |
|
1818 vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1819 mbi, &(lastPosition[blkCnt])); |
|
1820 blkCnt = 5; /* V */ |
|
1821 vbmPredictBlock(paramMB->refV, paramMB->uvWidth, 0, paramMB->currVBlkInFrame, paramMB->uvWidth, |
|
1822 &mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1823 &lChrMv, mbPos->x >> 1, mbPos->y >> 1); |
|
1824 vbmDCTQuantInterSVH(&mbData.Data[blkCnt * BLOCK_COEFF_SIZE], |
|
1825 mbi, &(lastPosition[blkCnt])); |
|
1826 } |
|
1827 |
|
1828 vbmCBPYInter(mbi, lastPosition); |
|
1829 if((mbi->CodedBlockPattern == 0) && |
|
1830 (mbi->MV[0][0] == 0) && (mbi->MV[0][1] == 0)) |
|
1831 { |
|
1832 mbi->SkippedMB = ON; |
|
1833 } |
|
1834 else //(mbi->SkippedMB == OFF) |
|
1835 { |
|
1836 vbmMvPrediction(mbi, mbNo, predMV, vopWidth / MB_SIZE); |
|
1837 } |
|
1838 vbmPutInterMBSVH(&mbData, mbi, outBuf, |
|
1839 numTextureBits, predMV, lastPosition, colorEffect); |
|
1840 |
|
1841 return; |
|
1842 } |
|
1843 |
|
1844 |
|
1845 /* End of bma.cpp */ |
|
1846 |
|