1 /******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /**
21 *******************************************************************************
22 * @file
23 * impeg2d_mcu.c
24 *
25 * @brief
26 * Contains MC function definitions for MPEG2 decoder
27 *
28 * @author
29 * Harish
30 *
31 * @par List of Functions:
32 * - impeg2_copy_mb()
33 * - impeg2_interpolate()
34 * - impeg2_mc_halfx_halfy_8x8()
35 * - impeg2_mc_halfx_fully_8x8()
36 * - impeg2_mc_fullx_halfy_8x8()
37 * - impeg2_mc_fullx_fully_8x8()
38 *
39 * @remarks
40 * None
41 *
42 *******************************************************************************
43 */
44
45 #include <stdio.h>
46 #include <string.h>
47 #include "iv_datatypedef.h"
48 #include "iv.h"
49 #include "impeg2_buf_mgr.h"
50 #include "impeg2_disp_mgr.h"
51 #include "impeg2_defs.h"
52 #include "impeg2_platform_macros.h"
53
54 #include "impeg2_inter_pred.h"
55 #include "impeg2_globals.h"
56 #include "impeg2_macros.h"
57 #include "impeg2_idct.h"
58
59 /*******************************************************************************
60 * Function Name : impeg2_copy_mb
61 *
62 * Description : copies 3 components to the frame from mc_buf
63 *
64 * Arguments :
65 * src_buf : Source Buffer
66 * dst_buf : Destination Buffer
67 * src_offset_x : X offset for source
68 * src_offset_y : Y offset for source
69 * dst_offset_x : X offset for destination
70 * dst_offset_y : Y offset for destination
71 * src_wd : Source Width
72 * dst_wd : destination Width
73 * rows : Number of rows
74 * cols : Number of columns
75 *
76 * Values Returned : None
77 *******************************************************************************/
impeg2_copy_mb(yuv_buf_t * ps_src_buf,yuv_buf_t * ps_dst_buf,UWORD32 u4_src_wd,UWORD32 u4_dst_wd)78 void impeg2_copy_mb(yuv_buf_t *ps_src_buf,
79 yuv_buf_t *ps_dst_buf,
80 UWORD32 u4_src_wd,
81 UWORD32 u4_dst_wd)
82 {
83 UWORD8 *pu1_src;
84 UWORD8 *pu1_dst;
85 UWORD32 i;
86 UWORD32 u4_rows = MB_SIZE;
87 UWORD32 u4_cols = MB_SIZE;
88
89 /*******************************************************/
90 /* copy Y */
91 /*******************************************************/
92 pu1_src = ps_src_buf->pu1_y;
93 pu1_dst = ps_dst_buf->pu1_y;
94 for(i = 0; i < u4_rows; i++)
95 {
96 memcpy(pu1_dst, pu1_src, u4_cols);
97 pu1_src += u4_src_wd;
98 pu1_dst += u4_dst_wd;
99 }
100
101 u4_src_wd >>= 1;
102 u4_dst_wd >>= 1;
103 u4_rows >>= 1;
104 u4_cols >>= 1;
105
106 /*******************************************************/
107 /* copy U */
108 /*******************************************************/
109 pu1_src = ps_src_buf->pu1_u;
110 pu1_dst = ps_dst_buf->pu1_u;
111 for(i = 0; i < u4_rows; i++)
112 {
113 memcpy(pu1_dst, pu1_src, u4_cols);
114
115 pu1_src += u4_src_wd;
116 pu1_dst += u4_dst_wd;
117 }
118 /*******************************************************/
119 /* copy V */
120 /*******************************************************/
121 pu1_src = ps_src_buf->pu1_v;
122 pu1_dst = ps_dst_buf->pu1_v;
123 for(i = 0; i < u4_rows; i++)
124 {
125 memcpy(pu1_dst, pu1_src, u4_cols);
126
127 pu1_src += u4_src_wd;
128 pu1_dst += u4_dst_wd;
129 }
130
131 }
132
133 /*****************************************************************************/
134 /* */
135 /* Function Name : impeg2_interpolate */
136 /* */
137 /* Description : averages the contents of buf_src1 and buf_src2 and stores*/
138 /* result in buf_dst */
139 /* */
140 /* Inputs : buf_src1 - First Source */
141 /* buf_src2 - Second Source */
142 /* */
143 /* Globals : None */
144 /* */
145 /* Processing : Avg the values from two sources and store the result in */
146 /* destination buffer */
147 /* */
148 /* Outputs : buf_dst - Avg of contents of buf_src1 and buf_src2 */
149 /* */
150 /* Returns : None */
151 /* */
152 /* Issues : Assumes that all 3 buffers are of same size */
153 /* */
154 /* Revision History: */
155 /* */
156 /* DD MM YYYY Author(s) Changes */
157 /* 14 09 2005 Harish M First Version */
158 /* 15 09 2010 Venkat Added stride */
159 /* */
160 /*****************************************************************************/
impeg2_interpolate(yuv_buf_t * ps_buf_src1,yuv_buf_t * ps_buf_src2,yuv_buf_t * ps_buf_dst,UWORD32 u4_stride)161 void impeg2_interpolate(yuv_buf_t *ps_buf_src1,
162 yuv_buf_t *ps_buf_src2,
163 yuv_buf_t *ps_buf_dst,
164 UWORD32 u4_stride)
165 {
166
167 UWORD32 i,j;
168 UWORD8 *pu1_src1,*pu1_src2,*pu1_dst;
169 pu1_src1 = ps_buf_src1->pu1_y;
170 pu1_src2 = ps_buf_src2->pu1_y;
171 pu1_dst = ps_buf_dst->pu1_y;
172 for(i = MB_SIZE; i > 0; i--)
173 {
174 for(j = MB_SIZE; j > 0; j--)
175 {
176 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
177 }
178
179 pu1_dst += u4_stride - MB_SIZE;
180
181 }
182
183 u4_stride >>= 1;
184
185 pu1_src1 = ps_buf_src1->pu1_u;
186 pu1_src2 = ps_buf_src2->pu1_u;
187 pu1_dst = ps_buf_dst->pu1_u;
188 for(i = MB_CHROMA_SIZE; i > 0 ; i--)
189 {
190 for(j = MB_CHROMA_SIZE; j > 0; j--)
191 {
192 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
193 }
194
195 pu1_dst += u4_stride - MB_CHROMA_SIZE;
196 }
197
198 pu1_src1 = ps_buf_src1->pu1_v;
199 pu1_src2 = ps_buf_src2->pu1_v;
200 pu1_dst = ps_buf_dst->pu1_v;
201 for(i = MB_CHROMA_SIZE; i > 0 ; i--)
202 {
203 for(j = MB_CHROMA_SIZE; j > 0; j--)
204 {
205 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
206 }
207
208 pu1_dst += u4_stride - MB_CHROMA_SIZE;
209 }
210
211 }
212
213 /*****************************************************************************/
214 /* */
215 /* Function Name : impeg2_mc_halfx_halfy_8x8() */
216 /* */
217 /* Description : Gets the buffer from (0.5,0.5) to (8.5,8.5) */
218 /* and the above block of size 8 x 8 will be placed as a */
219 /* block from the current position of out_buf */
220 /* */
221 /* Inputs : ref - Reference frame from which the block will be */
222 /* block will be extracted. */
223 /* ref_wid - WIdth of reference frame */
224 /* out_wid - WIdth of the output frame */
225 /* blk_width - width of the block */
226 /* blk_width - height of the block */
227 /* */
228 /* Globals : None */
229 /* */
230 /* Processing : Point to the (0,0),(1,0),(0,1),(1,1) position in */
231 /* the ref frame.Interpolate these four values to get the */
232 /* value at(0.5,0.5).Repeat this to get an 8 x 8 block */
233 /* using 9 x 9 block from reference frame */
234 /* */
235 /* Outputs : out - Output containing the extracted block */
236 /* */
237 /* Returns : None */
238 /* */
239 /* Issues : None */
240 /* */
241 /* Revision History: */
242 /* */
243 /* DD MM YYYY Author(s) Changes */
244 /* 05 09 2005 Harish M First Version */
245 /* */
246 /*****************************************************************************/
impeg2_mc_halfx_halfy_8x8(UWORD8 * pu1_out,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD32 u4_out_wid)247 void impeg2_mc_halfx_halfy_8x8(UWORD8 *pu1_out,
248 UWORD8 *pu1_ref,
249 UWORD32 u4_ref_wid,
250 UWORD32 u4_out_wid)
251 {
252 UWORD8 *pu1_ref_p0,*pu1_ref_p1,*pu1_ref_p2,*pu1_ref_p3;
253 UWORD32 i,j;
254 /* P0-P3 are the pixels in the reference frame and Q is the value being */
255 /* estimated */
256 /*
257 P0 P1
258 Q
259 P2 P3
260 */
261
262 pu1_ref_p0 = pu1_ref;
263 pu1_ref_p1 = pu1_ref + 1;
264 pu1_ref_p2 = pu1_ref + u4_ref_wid;
265 pu1_ref_p3 = pu1_ref + u4_ref_wid + 1;
266
267 for(i = 0; i < BLK_SIZE; i++)
268 {
269 for(j = 0; j < BLK_SIZE; j++)
270 {
271 *pu1_out++ = (( (*pu1_ref_p0++ )
272 + (*pu1_ref_p1++ )
273 + (*pu1_ref_p2++ )
274 + (*pu1_ref_p3++ ) + 2 ) >> 2);
275 }
276 pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
277 pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
278 pu1_ref_p2 += u4_ref_wid - BLK_SIZE;
279 pu1_ref_p3 += u4_ref_wid - BLK_SIZE;
280
281 pu1_out += u4_out_wid - BLK_SIZE;
282 }
283 return;
284 }
285
286 /*****************************************************************************/
287 /* */
288 /* Function Name : impeg2_mc_halfx_fully_8x8() */
289 /* */
290 /* Description : Gets the buffer from (0.5,0) to (8.5,8) */
291 /* and the above block of size 8 x 8 will be placed as a */
292 /* block from the current position of out_buf */
293 /* */
294 /* Inputs : ref - Reference frame from which the block will be */
295 /* block will be extracted. */
296 /* ref_wid - WIdth of reference frame */
297 /* out_wid - WIdth of the output frame */
298 /* blk_width - width of the block */
299 /* blk_width - height of the block */
300 /* */
301 /* Globals : None */
302 /* */
303 /* Processing : Point to the (0,0) and (1,0) position in the ref frame */
304 /* Interpolate these two values to get the value at(0.5,0) */
305 /* Repeat this to get an 8 x 8 block using 9 x 8 block from */
306 /* reference frame */
307 /* */
308 /* Outputs : out - Output containing the extracted block */
309 /* */
310 /* Returns : None */
311 /* */
312 /* Issues : None */
313 /* */
314 /* Revision History: */
315 /* */
316 /* DD MM YYYY Author(s) Changes */
317 /* 05 09 2005 Harish M First Version */
318 /* */
319 /*****************************************************************************/
impeg2_mc_halfx_fully_8x8(UWORD8 * pu1_out,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD32 u4_out_wid)320 void impeg2_mc_halfx_fully_8x8(UWORD8 *pu1_out,
321 UWORD8 *pu1_ref,
322 UWORD32 u4_ref_wid,
323 UWORD32 u4_out_wid)
324 {
325 UWORD8 *pu1_ref_p0, *pu1_ref_p1;
326 UWORD32 i,j;
327
328 /* P0-P3 are the pixels in the reference frame and Q is the value being */
329 /* estimated */
330 /*
331 P0 Q P1
332 */
333
334 pu1_ref_p0 = pu1_ref;
335 pu1_ref_p1 = pu1_ref + 1;
336
337 for(i = 0; i < BLK_SIZE; i++)
338 {
339 for(j = 0; j < BLK_SIZE; j++)
340 {
341 *pu1_out++ = ((( *pu1_ref_p0++ )
342 + (*pu1_ref_p1++) + 1 ) >> 1);
343 }
344 pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
345 pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
346
347 pu1_out += u4_out_wid - BLK_SIZE;
348 }
349 return;
350 }
351
352 /*****************************************************************************/
353 /* */
354 /* Function Name : impeg2_mc_fullx_halfy_8x8() */
355 /* */
356 /* Description : Gets the buffer from (0,0.5) to (8,8.5) */
357 /* and the above block of size 8 x 8 will be placed as a */
358 /* block from the current position of out_buf */
359 /* */
360 /* Inputs : ref - Reference frame from which the block will be */
361 /* block will be extracted. */
362 /* ref_wid - WIdth of reference frame */
363 /* out_wid - WIdth of the output frame */
364 /* blk_width - width of the block */
365 /* blk_width - height of the block */
366 /* */
367 /* Globals : None */
368 /* */
369 /* Processing : Point to the (0,0) and (0,1) position in the ref frame */
370 /* Interpolate these two values to get the value at(0,0.5) */
371 /* Repeat this to get an 8 x 8 block using 8 x 9 block from */
372 /* reference frame */
373 /* */
374 /* Outputs : out - Output containing the extracted block */
375 /* */
376 /* Returns : None */
377 /* */
378 /* Issues : None */
379 /* */
380 /* Revision History: */
381 /* */
382 /* DD MM YYYY Author(s) Changes */
383 /* 05 09 2005 Harish M First Version */
384 /* */
385 /*****************************************************************************/
impeg2_mc_fullx_halfy_8x8(UWORD8 * pu1_out,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD32 u4_out_wid)386 void impeg2_mc_fullx_halfy_8x8(UWORD8 *pu1_out,
387 UWORD8 *pu1_ref,
388 UWORD32 u4_ref_wid,
389 UWORD32 u4_out_wid)
390 {
391
392 UWORD8 *pu1_ref_p0, *pu1_ref_p1;
393 UWORD32 i,j;
394 /* P0-P3 are the pixels in the reference frame and Q is the value being */
395 /* estimated */
396 /*
397 P0
398 x
399 P1
400 */
401 pu1_ref_p0 = pu1_ref;
402 pu1_ref_p1 = pu1_ref + u4_ref_wid;
403
404 for(i = 0; i < BLK_SIZE; i++)
405 {
406 for(j = 0; j < BLK_SIZE; j++)
407 {
408 *pu1_out++ = ((( *pu1_ref_p0++)
409 + (*pu1_ref_p1++) + 1 ) >> 1);
410 }
411 pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
412 pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
413
414 pu1_out += u4_out_wid - BLK_SIZE;
415 }
416
417 return;
418 }
419
420 /*****************************************************************************/
421 /* */
422 /* Function Name : impeg2_mc_fullx_fully_8x8() */
423 /* */
424 /* Description : Gets the buffer from (x,y) to (x+8,y+8) */
425 /* and the above block of size 8 x 8 will be placed as a */
426 /* block from the current position of out_buf */
427 /* */
428 /* Inputs : ref - Reference frame from which the block will be */
429 /* block will be extracted. */
430 /* ref_wid - WIdth of reference frame */
431 /* out_wid - WIdth of the output frame */
432 /* blk_width - width of the block */
433 /* blk_width - height of the block */
434 /* */
435 /* Globals : None */
436 /* */
437 /* Processing : Point to the (0,0) position in the ref frame */
438 /* Get an 8 x 8 block from reference frame */
439 /* */
440 /* Outputs : out - Output containing the extracted block */
441 /* */
442 /* Returns : None */
443 /* */
444 /* Issues : None */
445 /* */
446 /* Revision History: */
447 /* */
448 /* DD MM YYYY Author(s) Changes */
449 /* 05 09 2005 Harish M First Version */
450 /* */
451 /*****************************************************************************/
impeg2_mc_fullx_fully_8x8(UWORD8 * pu1_out,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD32 u4_out_wid)452 void impeg2_mc_fullx_fully_8x8(UWORD8 *pu1_out,
453 UWORD8 *pu1_ref,
454 UWORD32 u4_ref_wid,
455 UWORD32 u4_out_wid)
456 {
457
458 UWORD32 i;
459
460 for(i = 0; i < BLK_SIZE; i++)
461 {
462 memcpy(pu1_out, pu1_ref, BLK_SIZE);
463 pu1_ref += u4_ref_wid;
464 pu1_out += u4_out_wid;
465 }
466 return;
467 }
468