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
19 #define LOG_TAG "m4v_h263"
20 #include <log/log.h>
21
22 /*
23 ------------------------------------------------------------------------------
24 INPUT AND OUTPUT DEFINITIONS
25
26 Inputs:
27 video = pointer to structure of type VideoDecData
28
29 Local Stores/Buffers/Pointers Needed:
30 roundtab16 = rounding table
31
32 Global Stores/Buffers/Pointers Needed:
33 None
34
35 Outputs:
36 None
37
38 Pointers and Buffers Modified:
39 video->currVop->yChan contents are the newly calculated luminance
40 data
41 video->currVop->uChan contents are the newly calculated chrominance
42 b data
43 video->currVop->vChan contents are the newly calculated chrominance
44 r data
45 video->pstprcTypCur contents are the updated semaphore propagation
46 values
47
48 Local Stores Modified:
49 None
50
51 Global Stores Modified:
52 None
53
54 ------------------------------------------------------------------------------
55 FUNCTION DESCRIPTION
56
57 This function performs high level motion compensation on the luminance and
58 chrominance data. It sets up all the parameters required by the functions
59 that perform luminance and chrominance prediction and it initializes the
60 pointer to the post processing semaphores of a given block. It also checks
61 the motion compensation mode in order to determine which luminance or
62 chrominance prediction functions to call and determines how the post
63 processing semaphores are updated.
64
65 */
66
67
68 /*----------------------------------------------------------------------------
69 ; INCLUDES
70 ----------------------------------------------------------------------------*/
71 #include "mp4dec_lib.h"
72 #include "motion_comp.h"
73 /*----------------------------------------------------------------------------
74 ; MACROS
75 ; Define module specific macros here
76 ----------------------------------------------------------------------------*/
77
78
79 /*----------------------------------------------------------------------------
80 ; DEFINES
81 ; Include all pre-processor statements here. Include conditional
82 ; compile variables also.
83 ----------------------------------------------------------------------------*/
84
85
86 /*----------------------------------------------------------------------------
87 ; LOCAL FUNCTION DEFINITIONS
88 ; Function Prototype declaration
89 ----------------------------------------------------------------------------*/
90
91
92 /*----------------------------------------------------------------------------
93 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
94 ; Variable declaration - defined here and used outside this module
95 ----------------------------------------------------------------------------*/
96 /* 09/29/2000 bring this from mp4def.h */
97 // const static int roundtab4[] = {0,1,1,1};
98 // const static int roundtab8[] = {0,0,1,1,1,1,1,2};
99 /*** 10/30 for TPS */
100 // const static int roundtab12[] = {0,0,0,1,1,1,1,1,1,1,2,2};
101 /* 10/30 for TPS ***/
102 const static int roundtab16[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
103
104
105 /*----------------------------------------------------------------------------
106 ; EXTERNAL FUNCTION REFERENCES
107 ; Declare functions defined elsewhere and referenced in this module
108 ----------------------------------------------------------------------------*/
109
110 /*----------------------------------------------------------------------------
111 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
112 ; Declare variables used in this module but defined elsewhere
113 ----------------------------------------------------------------------------*/
114
115
116 /*----------------------------------------------------------------------------
117 ; FUNCTION CODE
118 ----------------------------------------------------------------------------*/
119
120 /** modified 3 August 2005 to do prediction and put the results in
121 video->mblock->pred_block, no adding with residue */
122
MBMotionComp(VideoDecData * video,int CBP)123 void MBMotionComp(
124 VideoDecData *video,
125 int CBP
126 )
127 {
128
129 /*----------------------------------------------------------------------------
130 ; Define all local variables
131 ----------------------------------------------------------------------------*/
132 /* Previous Video Object Plane */
133 Vop *prev = video->prevVop;
134
135 /* Current Macroblock (MB) in the VOP */
136 int mbnum = video->mbnum;
137
138 /* Number of MB per data row */
139 int MB_in_width = video->nMBPerRow;
140 int ypos, xpos;
141 PIXEL *c_comp, *c_prev;
142 PIXEL *cu_comp, *cu_prev;
143 PIXEL *cv_comp, *cv_prev;
144 int height, width, pred_width;
145 int imv, mvwidth;
146 int32 offset;
147 uint8 mode;
148 uint8 *pred_block, *pred;
149
150 /* Motion vector (dx,dy) in half-pel resolution */
151 int dx, dy;
152
153 MOT px[4], py[4];
154 int xpred, ypred;
155 int xsum;
156 int round1;
157 /*----------------------------------------------------------------------------
158 ; Function body here
159 ----------------------------------------------------------------------------*/
160 /* Set rounding type */
161 /* change from array to single 09/29/2000 */
162 round1 = (int)(1 - video->currVop->roundingType);
163
164 /* width of luminance data in pixels (y axis) */
165 width = video->width;
166
167 /* heigth of luminance data in pixels (x axis) */
168 height = video->height;
169
170 /* number of blocks per row */
171 mvwidth = MB_in_width << 1;
172
173 /* starting y position in current MB; origin of MB */
174 ypos = video->mbnum_row << 4 ;
175 /* starting x position in current MB; origin of MB */
176 xpos = video->mbnum_col << 4 ;
177
178 /* offset to (x,y) position in current luminance MB */
179 /* in pixel resolution */
180 /* ypos*width -> row, +x -> column */
181 offset = (int32)ypos * width + xpos;
182
183 /* get mode for current MB */
184 mode = video->headerInfo.Mode[mbnum];
185
186 /* block index */
187 /* imv = (xpos/8) + ((ypos/8) * mvwidth) */
188 imv = (offset >> 6) - (xpos >> 6) + (xpos >> 3);
189 if (mode & INTER_1VMASK)
190 {
191 dx = px[0] = px[1] = px[2] = px[3] = video->motX[imv];
192 dy = py[0] = py[1] = py[2] = py[3] = video->motY[imv];
193 if ((dx & 3) == 0)
194 {
195 dx = dx >> 1;
196 }
197 else
198 {
199 /* x component of MV is or'ed for rounding (?) */
200 dx = (dx >> 1) | 1;
201 }
202
203 /* y component of motion vector; divide by 2 for to */
204 /* convert to full-pel resolution. */
205 if ((dy & 3) == 0)
206 {
207 dy = dy >> 1;
208 }
209 else
210 {
211 /* y component of MV is or'ed for rounding (?) */
212 dy = (dy >> 1) | 1;
213 }
214 }
215 else
216 {
217 px[0] = video->motX[imv];
218 px[1] = video->motX[imv+1];
219 px[2] = video->motX[imv+mvwidth];
220 px[3] = video->motX[imv+mvwidth+1];
221 xsum = px[0] + px[1] + px[2] + px[3];
222 dx = PV_SIGN(xsum) * (roundtab16[(PV_ABS(xsum)) & 0xF] +
223 (((PV_ABS(xsum)) >> 4) << 1));
224 py[0] = video->motY[imv];
225 py[1] = video->motY[imv+1];
226 py[2] = video->motY[imv+mvwidth];
227 py[3] = video->motY[imv+mvwidth+1];
228 xsum = py[0] + py[1] + py[2] + py[3];
229 dy = PV_SIGN(xsum) * (roundtab16[(PV_ABS(xsum)) & 0xF] +
230 (((PV_ABS(xsum)) >> 4) << 1));
231 }
232
233 /* Pointer to previous luminance frame */
234 c_prev = prev->yChan;
235 if (!c_prev) {
236 ALOGE("b/35269635");
237 android_errorWriteLog(0x534e4554, "35269635");
238 return;
239 }
240
241 pred_block = video->mblock->pred_block;
242
243 /* some blocks have no residue or INTER4V */
244 /*if (mode == MODE_INTER4V) 05/08/15 */
245 /* Motion Compensation for an 8x8 block within a MB */
246 /* (4 MV per MB) */
247
248
249
250 /* Call function that performs luminance prediction */
251 /* luminance_pred_mode_inter4v(xpos, ypos, px, py, c_prev,
252 video->mblock->pred_block, width, height,
253 round1, mvwidth, &xsum, &ysum);*/
254 c_comp = video->currVop->yChan + offset;
255
256
257 xpred = (int)((xpos << 1) + px[0]);
258 ypred = (int)((ypos << 1) + py[0]);
259
260 if ((CBP >> 5)&1)
261 {
262 pred = pred_block;
263 pred_width = 16;
264 }
265 else
266 {
267 pred = c_comp;
268 pred_width = width;
269 }
270
271 /* check whether the MV points outside the frame */
272 if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
273 ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
274 { /*****************************/
275 /* (x,y) is inside the frame */
276 /*****************************/
277 ;
278 GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
279 pred, width, (pred_width << 1) | round1);
280 }
281 else
282 { /******************************/
283 /* (x,y) is outside the frame */
284 /******************************/
285 GetPredOutside(xpred, ypred, c_prev,
286 pred, width, height, round1, pred_width);
287 }
288
289
290 /* Compute prediction values over current luminance MB */
291 /* (blocks 1); add motion vector prior to input; */
292 /* add 8 to x_pos to advance to next block */
293 xpred = (int)(((xpos + B_SIZE) << 1) + px[1]);
294 ypred = (int)((ypos << 1) + py[1]);
295
296 if ((CBP >> 4)&1)
297 {
298 pred = pred_block + 8;
299 pred_width = 16;
300 }
301 else
302 {
303 pred = c_comp + 8;
304 pred_width = width;
305 }
306
307 /* check whether the MV points outside the frame */
308 if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
309 ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
310 { /*****************************/
311 /* (x,y) is inside the frame */
312 /*****************************/
313 GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
314 pred, width, (pred_width << 1) | round1);
315 }
316 else
317 { /******************************/
318 /* (x,y) is outside the frame */
319 /******************************/
320 GetPredOutside(xpred, ypred, c_prev,
321 pred, width, height, round1, pred_width);
322 }
323
324
325
326 /* Compute prediction values over current luminance MB */
327 /* (blocks 2); add motion vector prior to input */
328 /* add 8 to y_pos to advance to block on next row */
329 xpred = (int)((xpos << 1) + px[2]);
330 ypred = (int)(((ypos + B_SIZE) << 1) + py[2]);
331
332 if ((CBP >> 3)&1)
333 {
334 pred = pred_block + 128;
335 pred_width = 16;
336 }
337 else
338 {
339 pred = c_comp + (width << 3);
340 pred_width = width;
341 }
342
343 /* check whether the MV points outside the frame */
344 if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
345 ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
346 { /*****************************/
347 /* (x,y) is inside the frame */
348 /*****************************/
349 GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
350 pred, width, (pred_width << 1) | round1);
351 }
352 else
353 { /******************************/
354 /* (x,y) is outside the frame */
355 /******************************/
356 GetPredOutside(xpred, ypred, c_prev,
357 pred, width, height, round1, pred_width);
358 }
359
360
361
362 /* Compute prediction values over current luminance MB */
363 /* (blocks 3); add motion vector prior to input; */
364 /* add 8 to x_pos and y_pos to advance to next block */
365 /* on next row */
366 xpred = (int)(((xpos + B_SIZE) << 1) + px[3]);
367 ypred = (int)(((ypos + B_SIZE) << 1) + py[3]);
368
369 if ((CBP >> 2)&1)
370 {
371 pred = pred_block + 136;
372 pred_width = 16;
373 }
374 else
375 {
376 pred = c_comp + (width << 3) + 8;
377 pred_width = width;
378 }
379
380 /* check whether the MV points outside the frame */
381 if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) &&
382 ypred >= 0 && ypred <= ((height << 1) - (2*B_SIZE)))
383 { /*****************************/
384 /* (x,y) is inside the frame */
385 /*****************************/
386 GetPredAdvBTable[ypred&1][xpred&1](c_prev + (xpred >> 1) + ((ypred >> 1)*width),
387 pred, width, (pred_width << 1) | round1);
388 }
389 else
390 { /******************************/
391 /* (x,y) is outside the frame */
392 /******************************/
393 GetPredOutside(xpred, ypred, c_prev,
394 pred, width, height, round1, pred_width);
395 }
396 /* Call function to set de-blocking and de-ringing */
397 /* semaphores for luminance */
398
399
400
401 /* xpred and ypred calculation for Chrominance is */
402 /* in full-pel resolution. */
403
404 /* Chrominance */
405 /* width of chrominance data in pixels (y axis) */
406 width >>= 1;
407
408 /* heigth of chrominance data in pixels (x axis) */
409 height >>= 1;
410
411 /* Pointer to previous chrominance b frame */
412 cu_prev = prev->uChan;
413
414 /* Pointer to previous chrominance r frame */
415 cv_prev = prev->vChan;
416
417 /* x position in prediction data offset by motion vector */
418 /* xpred calculation for Chrominance is in full-pel */
419 /* resolution. */
420 xpred = xpos + dx;
421
422 /* y position in prediction data offset by motion vector */
423 /* ypred calculation for Chrominance is in full-pel */
424 /* resolution. */
425 ypred = ypos + dy;
426
427 cu_comp = video->currVop->uChan + (offset >> 2) + (xpos >> 2);
428 cv_comp = video->currVop->vChan + (offset >> 2) + (xpos >> 2);
429
430 /* Call function that performs chrominance prediction */
431 /* chrominance_pred(xpred, ypred, cu_prev, cv_prev,
432 pred_block, width_uv, height_uv,
433 round1);*/
434 if (xpred >= 0 && xpred <= ((width << 1) - (2*B_SIZE)) && ypred >= 0 &&
435 ypred <= ((height << 1) - (2*B_SIZE)))
436 {
437 /*****************************/
438 /* (x,y) is inside the frame */
439 /*****************************/
440 if ((CBP >> 1)&1)
441 {
442 pred = pred_block + 256;
443 pred_width = 16;
444 }
445 else
446 {
447 pred = cu_comp;
448 pred_width = width;
449 }
450
451 /* Compute prediction for Chrominance b (block[4]) */
452 GetPredAdvBTable[ypred&1][xpred&1](cu_prev + (xpred >> 1) + ((ypred >> 1)*width),
453 pred, width, (pred_width << 1) | round1);
454
455 if (CBP&1)
456 {
457 pred = pred_block + 264;
458 pred_width = 16;
459 }
460 else
461 {
462 pred = cv_comp;
463 pred_width = width;
464 }
465 /* Compute prediction for Chrominance r (block[5]) */
466 GetPredAdvBTable[ypred&1][xpred&1](cv_prev + (xpred >> 1) + ((ypred >> 1)*width),
467 pred, width, (pred_width << 1) | round1);
468
469 return ;
470 }
471 else
472 {
473 /******************************/
474 /* (x,y) is outside the frame */
475 /******************************/
476 if ((CBP >> 1)&1)
477 {
478 pred = pred_block + 256;
479 pred_width = 16;
480 }
481 else
482 {
483 pred = cu_comp;
484 pred_width = width;
485 }
486
487 /* Compute prediction for Chrominance b (block[4]) */
488 GetPredOutside(xpred, ypred, cu_prev,
489 pred, width, height, round1, pred_width);
490
491 if (CBP&1)
492 {
493 pred = pred_block + 264;
494 pred_width = 16;
495 }
496 else
497 {
498 pred = cv_comp;
499 pred_width = width;
500 }
501
502 /* Compute prediction for Chrominance r (block[5]) */
503 GetPredOutside(xpred, ypred, cv_prev,
504 pred, width, height, round1, pred_width);
505
506 return ;
507 }
508
509 }
510
511 /*** special function for skipped macroblock, Aug 15, 2005 */
SkippedMBMotionComp(VideoDecData * video)512 void SkippedMBMotionComp(
513 VideoDecData *video
514 )
515 {
516 Vop *prev = video->prevVop;
517 Vop *comp;
518 int ypos, xpos;
519 PIXEL *c_comp, *c_prev;
520 PIXEL *cu_comp, *cu_prev;
521 PIXEL *cv_comp, *cv_prev;
522 int width, width_uv;
523 int32 offset;
524
525 width = video->width;
526 width_uv = width >> 1;
527 ypos = video->mbnum_row << 4 ;
528 xpos = video->mbnum_col << 4 ;
529 offset = (int32)ypos * width + xpos;
530
531
532 /* zero motion compensation for previous frame */
533 /*mby*width + mbx;*/
534 c_prev = prev->yChan;
535 if (!c_prev) {
536 ALOGE("b/35269635");
537 android_errorWriteLog(0x534e4554, "35269635");
538 return;
539 }
540 c_prev += offset;
541
542 /*by*width_uv + bx;*/
543 cu_prev = prev->uChan + (offset >> 2) + (xpos >> 2);
544 /*by*width_uv + bx;*/
545 cv_prev = prev->vChan + (offset >> 2) + (xpos >> 2);
546
547 comp = video->currVop;
548
549 c_comp = comp->yChan + offset;
550 cu_comp = comp->uChan + (offset >> 2) + (xpos >> 2);
551 cv_comp = comp->vChan + (offset >> 2) + (xpos >> 2);
552
553
554 /* Copy previous reconstructed frame into the current frame */
555 PutSKIPPED_MB(c_comp, c_prev, width);
556 PutSKIPPED_B(cu_comp, cu_prev, width_uv);
557 PutSKIPPED_B(cv_comp, cv_prev, width_uv);
558
559 /* 10/24/2000 post_processing semaphore generation */
560 /*----------------------------------------------------------------------------
561 ; Return nothing or data or data pointer
562 ----------------------------------------------------------------------------*/
563
564 return;
565 }
566