OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / codecs / m4v_h263 / dec / src / get_pred_outside.cpp
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 ------------------------------------------------------------------------------
20  INPUT AND OUTPUT DEFINITIONS
21
22  Inputs:
23     xpos = x half-pixel of (x,y) coordinates within a VOP; motion
24            compensated coordinates; native data type
25     ypos = y half-pixel of (x,y) coordinates within a VOP; motion
26            compensated coordinates; native data type
27     comp = pointer to 8-bit compensated prediction values within a VOP;
28            computed by this module (i/o); full-pel resolution; 8-bit data
29     c_prev = pointer to previous 8-bit prediction values within a VOP;
30          values range from (0-255); full-pel resolution; 8-bit data
31     sh_d = pointer to residual values used to compensate the predicted
32            value; values range from (-512 to 511); full-pel resolution;
33            native data type
34     width = width of the VOP in pixels (x axis); full-pel resolution;
35         native data type
36     height = height of the VOP in pixels (y axis); full-pel resolution;
37          native data type
38     rnd1 = rounding value for case when one dimension uses half-pel
39            resolution; native data type
40     rnd2 = rounding value for case when two dimensions uses half-pel
41            resolution; native data type
42
43  Outputs:
44     returns 1
45
46  Local Stores/Buffers/Pointers Needed:
47     None
48
49  Global Stores/Buffers/Pointers Needed:
50     None
51
52  Pointers and Buffers Modified:
53     comp = buffer contains newly computed compensated prediction values
54
55  Local Stores Modified:
56     None
57
58  Global Stores Modified:
59     None
60
61 ------------------------------------------------------------------------------
62  FUNCTION DESCRIPTION
63
64  Summary:
65
66  This function performs motion compensated prediction for the case where
67  the motion vector points to a block outside the VOP. The function interpolates
68  the pixels that are outside the VOP using the boundary pixels for the block.
69  Once the values are interpolated, the pixel values are computed for a block
70  in the current VOP. The prediction values are generated by averaging pixel
71  values in the previous VOP; the block position in the previous frame is
72  computed from the current block's motion vector. The computed pixel values
73  are calculated by adding the prediction values to the block residual values.
74
75  Details:
76
77  First, this functions determines which VOP boundary(ies) the motion vector
78  is outside, i.e., left, right, top, bottom. xpos is compared to the left and
79  right boundaries; ypos is compared to the top and bottom boundaries. The number
80  of block pixels inside the the boundary in the x and y directions are stored
81  in endx and endy, respectively. If the entire block is inside the x or y
82  boundary, the respectively end is set to 0.
83
84  After the boundaries are tested, any pixels lying outside a boundary are
85  interpolated from the boundary pixels. For example, if the block is outside the
86  bottom boundary, boundary pixels alone the bottom of the VOP as used to
87  interpolated those pixels lying outside the bottom boundary. The interpolation
88  used is a simple column-wise or row-wise copy of the boundary pixels (inside the
89  block) depending on which boundary the block is outside. In our example, each
90  boundary pixel would be copied column-wise to the pixel beneath it. If the
91  block was outside right boundary, the boundary pixels would be copied row-wise
92  to the pixel to the right of it. If the block was outside both an x and y
93  boundary, the boundary pixels would be copied row-wise for the portion of the
94  block outside the x boundary, and column-wise for the portion of the block
95  outside the y boundary. And so on.
96
97  Once the pixel interpolation is complete, the motion compensated output values
98  (comp[]) are calculed from the motion compensated prediction (pred[])values and
99  the residual values (sh_d[]) of the current frame. The prediction values are
100  generated by averaging pixel values in the previous VOP; the block position in
101  the previous frame is computed from the current block's motion vector. The
102  computed pixel values are calculated by adding the prediction values to the
103  block residual values.
104
105 */
106
107 /*----------------------------------------------------------------------------
108 ; INCLUDES
109 ----------------------------------------------------------------------------*/
110 #include "mp4dec_lib.h"
111 #include "motion_comp.h"
112
113 #define PAD_CORNER {    temp = *prev; \
114             temp |= (temp<<8);  \
115             temp |= (temp<<16); \
116             *((uint32*)ptr) = temp; \
117             *((uint32*)(ptr+4)) = temp;  \
118             *((uint32*)(ptr+=16)) = temp;  \
119             *((uint32*)(ptr+4)) = temp;  \
120             *((uint32*)(ptr+=16)) = temp;  \
121             *((uint32*)(ptr+4)) = temp;  \
122             *((uint32*)(ptr+=16)) = temp;  \
123             *((uint32*)(ptr+4)) = temp;  \
124             *((uint32*)(ptr+=16)) = temp;  \
125             *((uint32*)(ptr+4)) = temp;  \
126             *((uint32*)(ptr+=16)) = temp;  \
127             *((uint32*)(ptr+4)) = temp;  \
128             *((uint32*)(ptr+=16)) = temp;  \
129             *((uint32*)(ptr+4)) = temp;  \
130             *((uint32*)(ptr+=16)) = temp;  \
131             *((uint32*)(ptr+4)) = temp;  }
132
133 #define PAD_ROW  {  temp = *((uint32*)prev); \
134                     temp2 = *((uint32*)(prev+4)); \
135             *((uint32*)ptr) =  temp;\
136             *((uint32*)(ptr+4)) =  temp2; \
137             *((uint32*)(ptr+=16)) = temp; \
138             *((uint32*)(ptr+4)) = temp2;\
139             *((uint32*)(ptr+=16)) = temp; \
140             *((uint32*)(ptr+4)) = temp2;\
141             *((uint32*)(ptr+=16)) = temp; \
142             *((uint32*)(ptr+4)) = temp2;\
143             *((uint32*)(ptr+=16)) = temp; \
144             *((uint32*)(ptr+4)) = temp2;\
145             *((uint32*)(ptr+=16)) = temp; \
146             *((uint32*)(ptr+4)) = temp2;\
147             *((uint32*)(ptr+=16)) = temp; \
148             *((uint32*)(ptr+4)) = temp2;\
149             *((uint32*)(ptr+=16)) = temp; \
150             *((uint32*)(ptr+4)) = temp2;}
151
152 #define PAD_EXTRA_4x8           {   temp = *((uint32*)(prev+8)); \
153                 *((uint32*)ptr) =  temp; \
154                 *((uint32*)(ptr+=16)) = temp; \
155                 *((uint32*)(ptr+=16)) = temp; \
156                 *((uint32*)(ptr+=16)) = temp; \
157                 *((uint32*)(ptr+=16)) = temp; \
158                 *((uint32*)(ptr+=16)) = temp; \
159                 *((uint32*)(ptr+=16)) = temp; \
160                 *((uint32*)(ptr+=16)) = temp; }
161
162 #define PAD_COL { temp = *prev; \
163             temp|=(temp<<8);  temp|=(temp<<16); \
164             *((uint32*)ptr) = temp; \
165             *((uint32*)(ptr+4)) = temp; \
166             temp = *(prev+=16); \
167             temp|=(temp<<8);  temp|=(temp<<16); \
168             *((uint32*)(ptr+=16)) = temp; \
169             *((uint32*)(ptr+4)) = temp; \
170             temp = *(prev+=16); \
171             temp|=(temp<<8);  temp|=(temp<<16); \
172             *((uint32*)(ptr+=16)) = temp; \
173             *((uint32*)(ptr+4)) = temp; \
174             temp = *(prev+=16); \
175             temp|=(temp<<8);  temp|=(temp<<16); \
176             *((uint32*)(ptr+=16)) = temp; \
177             *((uint32*)(ptr+4)) = temp; \
178             temp = *(prev+=16); \
179             temp|=(temp<<8);  temp|=(temp<<16); \
180             *((uint32*)(ptr+=16)) = temp; \
181             *((uint32*)(ptr+4)) = temp; \
182             temp = *(prev+=16); \
183             temp|=(temp<<8);  temp|=(temp<<16); \
184             *((uint32*)(ptr+=16)) = temp; \
185             *((uint32*)(ptr+4)) = temp; \
186             temp = *(prev+=16); \
187             temp|=(temp<<8);  temp|=(temp<<16); \
188             *((uint32*)(ptr+=16)) = temp; \
189             *((uint32*)(ptr+4)) = temp; \
190             temp = *(prev+=16); \
191             temp|=(temp<<8);  temp|=(temp<<16); \
192             *((uint32*)(ptr+=16)) = temp; \
193             *((uint32*)(ptr+4)) = temp;}
194
195 /* copy 8x8 block */
196 #define COPY_BLOCK  {           *((uint32*)ptr) = *((uint32*)prev); \
197             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
198             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
199             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
200             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
201             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
202             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
203             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
204             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
205             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
206             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
207             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
208             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
209             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
210             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
211             *((uint32*)(ptr+4)) = *((uint32*)(prev+4));  }
212
213 #define COPY_12x8       {       *((uint32*)ptr) = *((uint32*)prev); \
214             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
215             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
216             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
217             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
218             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
219             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
220             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
221             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
222             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
223             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
224             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
225             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
226             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
227             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
228             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
229             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
230             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
231             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
232             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
233             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); \
234             *((uint32*)(ptr+=16)) = *((uint32*)(prev+=width)); \
235             *((uint32*)(ptr+4)) = *((uint32*)(prev+4)); \
236             *((uint32*)(ptr+8)) = *((uint32*)(prev+8)); }
237
238 /*----------------------------------------------------------------------------
239 ; FUNCTION CODE
240 ----------------------------------------------------------------------------*/
241 int GetPredOutside(
242     int xpos,       /* i */
243     int ypos,       /* i */
244     uint8 *c_prev,      /* i */
245     uint8 *pred_block,      /* i */
246     int width,      /* i */
247     int height,     /* i */
248     int rnd1,       /* i */
249     int pred_width
250 )
251 {
252     /*----------------------------------------------------------------------------
253     ; Define all local variables
254     ----------------------------------------------------------------------------*/
255     uint8   *prev;      /* pointers to adjacent pixels in the    */
256     uint8   pred[256];  /* storage for padded pixel values, 16x16 */
257     uint8   *ptr;
258     int xoffset;
259     uint32 temp, temp2;
260
261     /*----------------------------------------------------------------------------
262     ; Function body here
263     ----------------------------------------------------------------------------*/
264     /* saturate xpos and ypos */
265     if (xpos < -16) xpos = -16;
266     if (xpos > ((width - 1) << 1)) xpos = (width - 1) << 1;
267     if (ypos < -16) ypos = -16;
268     if (ypos > ((height - 1) << 1)) ypos = (height - 1) << 1;
269
270     if (xpos < 0)
271     {
272         if (ypos < 0) /* pad top left of frame */
273         {
274             /* copy the block */
275             ptr = pred + (8 << 4) + 8;
276             prev = c_prev;
277             COPY_BLOCK
278
279             /* pad the corner */
280             ptr = pred;
281             prev = pred + (8 << 4) + 8;
282             PAD_CORNER
283
284             /* pad top */
285             ptr = pred + 8;
286             prev = pred + (8 << 4) + 8;
287             PAD_ROW
288
289             /* pad left */
290             ptr = pred + (8 << 4);
291             prev = pred + (8 << 4) + 8;
292             PAD_COL
293
294
295             ptr = pred + (((ypos >> 1) + 8) << 4) + (xpos >> 1) + 8;
296
297             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
298
299             return 1;
300         }
301         else if ((ypos >> 1) < (height - B_SIZE)) /* pad left of frame */
302         {
303             /* copy block */
304             ptr = pred + 8;
305             prev = c_prev + (ypos >> 1) * width;
306             COPY_BLOCK
307             /* copy extra line */
308             *((uint32*)(ptr += 16)) = *((uint32*)(prev += width));
309             *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4));
310
311             /* pad left */
312             ptr = pred;
313             prev = pred + 8;
314             PAD_COL
315             /* pad extra line */
316             temp = *(prev += 16);
317             temp |= (temp << 8);
318             temp |= (temp << 16);
319             *((uint32*)(ptr += 16)) = temp;
320             *((uint32*)(ptr + 4)) = temp;
321
322             ptr = pred + 8 + (xpos >> 1);
323
324             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
325
326             return 1;
327         }
328         else /* pad bottom left of frame */
329         {
330             /* copy the block */
331             ptr = pred + 8; /* point to the center */
332             prev = c_prev + width * (height - 8);
333             COPY_BLOCK
334
335             /* pad the corner */
336             ptr = pred + (8 << 4);
337             prev = ptr - 8;
338             PAD_CORNER
339
340             /* pad bottom */
341             ptr = pred + (8 << 4) + 8;
342             prev = ptr - 16;
343             PAD_ROW
344
345             /* pad left */
346             ptr = pred ;
347             prev = ptr + 8;
348             PAD_COL
349
350             ptr = pred + 8 + (((ypos >> 1) - (height - 8)) << 4) + (xpos >> 1);
351
352             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
353
354             return 1;
355         }
356     }
357     else if ((xpos >> 1) < (width - B_SIZE))
358     {
359         if (ypos < 0) /* pad top of frame */
360         {
361             xoffset = xpos >> 1;
362             xoffset = xoffset & 0x3; /* word align ptr */
363
364             /* copy block */
365             ptr = pred + (8 << 4);
366             prev = c_prev + (xpos >> 1) - xoffset;
367
368             if (xoffset || (xpos&1)) /* copy extra 4x8 */
369             {
370                 COPY_12x8
371             }
372             else
373             {
374                 COPY_BLOCK
375             }
376
377             /* pad top */
378             ptr = pred;
379             prev = pred + (8 << 4);
380             PAD_ROW
381             if (xoffset || (xpos&1)) /* pad extra 4x8 */
382             {
383                 ptr = pred + 8;
384                 PAD_EXTRA_4x8
385             }
386
387             ptr = pred + (((ypos >> 1) + 8) << 4) + xoffset;
388
389             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
390
391             return 1;
392         }
393         else /* pad bottom of frame */
394         {
395             xoffset = xpos >> 1;
396             xoffset = xoffset & 0x3; /* word align ptr */
397             /* copy block */
398             ptr = pred ;
399             prev = c_prev + width * (height - 8) + (xpos >> 1) - xoffset;
400             if (xoffset  || (xpos&1))
401             {
402                 COPY_12x8
403             }
404             else
405             {
406                 COPY_BLOCK
407             }
408
409             /* pad bottom */
410             ptr = pred + (8 << 4);
411             prev = ptr - 16;
412             PAD_ROW
413             if (xoffset || (xpos&1))
414             {
415                 ptr = pred + (8 << 4) + 8;
416                 PAD_EXTRA_4x8
417             }
418
419             ptr = pred + (((ypos >> 1) - (height - 8)) << 4) + xoffset;
420
421             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
422
423             return 1;
424         }
425     }
426     else
427     {
428         if (ypos < 0) /* pad top right of frame */
429         {
430             /* copy block */
431             ptr = pred + (8 << 4);
432             prev = c_prev + width - 8;
433             COPY_BLOCK
434
435             /* pad top-right */
436             ptr = pred + 8;
437             prev = pred + (8 << 4) + 7;
438             PAD_CORNER
439
440             /* pad top */
441             ptr = pred ;
442             prev = pred + (8 << 4);
443             PAD_ROW;
444
445             /* pad right */
446             ptr = pred + (8 << 4) + 8;
447             prev = ptr - 1;
448             PAD_COL;
449
450             ptr = pred + ((8 + (ypos >> 1)) << 4) + (8 - (width - (xpos >> 1)));
451
452             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
453
454             return 1;
455         }
456         else if ((ypos >> 1) < (height - B_SIZE)) /* pad right of frame */
457         {
458             /* copy block */
459             ptr = pred;
460             prev = c_prev + (ypos >> 1) * width + width - 8;
461             COPY_BLOCK
462             /* copy extra line */
463             *((uint32*)(ptr += 16)) = *((uint32*)(prev += width));
464             *((uint32*)(ptr + 4)) = *((uint32*)(prev + 4));
465
466             /* pad right */
467             ptr = pred + 8;
468             prev = ptr - 1;
469             PAD_COL;
470             /* pad extra line */
471             temp = *(prev += 16);
472             temp |= (temp << 8);
473             temp |= (temp << 16);
474             *((uint32*)(ptr += 16)) = temp;
475             *((uint32*)(ptr + 4)) = temp;
476
477
478             ptr = pred + 8 - (width - (xpos >> 1));
479
480             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
481
482             return 1;
483
484         }
485         else /* pad bottom right of frame */
486         {
487             /* copy block */
488             ptr = pred;
489             prev = c_prev + width * (height - 8) + width - 8;
490             COPY_BLOCK
491
492             /* pad bottom-right */
493             ptr = pred + (8 << 4) + 8;
494             prev = ptr - 17;
495             PAD_CORNER
496
497             /* pad right */
498             ptr = pred + 8;
499             prev = ptr - 1;
500             PAD_COL
501
502             /* pad bottom */
503             ptr = pred + (8 << 4);
504             prev = ptr - 16;
505             PAD_ROW
506
507             ptr = pred + 8 - (width - (xpos >> 1)) + ((8 - (height - (ypos >> 1))) << 4);
508
509             GetPredAdvBTable[ypos&1][xpos&1](ptr, pred_block, 16, (pred_width << 1) | rnd1);
510
511             return 1;
512         }
513     }
514 }