blob: 019fa5c7812e3192d74ef52c60baf3354e22f41d [file] [log] [blame]
Venkatarama Avadhaniaed24ee2015-03-11 10:08:57 +05301/******************************************************************************
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*******************************************************************************/
78void 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/*****************************************************************************/
161void 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/*****************************************************************************/
247void 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/*****************************************************************************/
320void 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/*****************************************************************************/
386void 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/*****************************************************************************/
452void 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}