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_mc.c
24 *
25 * @brief
26 *  Contains MC function definitions for MPEG2 decoder
27 *
28 * @author
29 *  Harish
30 *
31 * @par List of Functions:
32 * - impeg2d_motion_comp()
33 * - impeg2d_motion_comp_recon_buf()
34 * - impeg2d_mc_1mv()
35 * - impeg2d_mc_fw_or_bk_mb()
36 * - impeg2d_mc_frm_dual_prime()
37 * - impeg2d_mc_fld_dual_prime()
38 * - impeg2d_mc_4mv()
39 * - impeg2d_mc_2mv()
40 * - impeg2d_dec_intra_mb()
41 * - impeg2d_dec_skip_p_mb()
42 * - impeg2d_dec_skip_b_mb()
43 * - impeg2d_dec_skip_mbs()
44 * - impeg2d_dec_0mv_coded_mb()
45 * - impeg2d_mc_halfx_halfy()
46 * - impeg2d_mc_halfx_fully()
47 * - impeg2d_mc_fullx_halfy()
48 * - impeg2d_mc_fullx_fully()
49 * - impeg2d_set_mc_params()
50 *
51 * @remarks
52 *  None
53 *
54 *******************************************************************************
55 */
56 #include <string.h>
57 
58 #include "iv_datatypedef.h"
59 #include "iv.h"
60 
61 #include "impeg2_buf_mgr.h"
62 #include "impeg2_disp_mgr.h"
63 #include "impeg2_defs.h"
64 #include "impeg2_platform_macros.h"
65 #include "impeg2_inter_pred.h"
66 #include "impeg2_idct.h"
67 #include "impeg2_globals.h"
68 #include "impeg2_mem_func.h"
69 #include "impeg2_format_conv.h"
70 #include "impeg2_macros.h"
71 
72 #include "ivd.h"
73 #include "impeg2d.h"
74 #include "impeg2d_bitstream.h"
75 #include "impeg2d_structs.h"
76 #include "impeg2d_globals.h"
77 #include "impeg2d_pic_proc.h"
78 #include "impeg2d_debug.h"
79 #include "impeg2d_mv_dec.h"
80 #include "impeg2d_mc.h"
81 
82 /*****************************************************************************/
83 /*                                                                           */
84 /*  Function Name : impeg2d_motion_comp                                      */
85 /*                                                                           */
86 /*  Description   : Perform motion compensation and store the resulting block*/
87 /*                  in the buf                                               */
88 /*                                                                           */
89 /*  Inputs        : params - Parameters required to do motion compensation   */
90 /*                                                                           */
91 /*  Globals       :                                                          */
92 /*                                                                           */
93 /*  Processing    : Calls appropriate functions depending on the mode of     */
94 /*                  compensation                                             */
95 /*                                                                           */
96 /*  Outputs       : buf       - Buffer for the motion compensation result    */
97 /*                                                                           */
98 /*  Returns       : None                                                     */
99 /*                                                                           */
100 /*  Issues        : None                                                     */
101 /*                                                                           */
102 /*  Revision History:                                                        */
103 /*                                                                           */
104 /*         DD MM YYYY   Author(s)       Changes                              */
105 /*         14 09 2005   Hairsh M        First Version                        */
106 /*                                                                           */
107 /*****************************************************************************/
impeg2d_motion_comp(dec_state_t * ps_dec,mb_mc_params_t * ps_params,yuv_buf_t * ps_buf)108 void impeg2d_motion_comp(dec_state_t *ps_dec, mb_mc_params_t *ps_params,yuv_buf_t *ps_buf)
109 {
110 
111     PROFILE_DISABLE_MC_RETURN;
112 
113     /* Perform motion compensation for Y */
114     ps_dec->pf_mc[ps_params->s_luma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_y + ps_params->s_luma.u4_src_offset,
115                 ps_params->s_luma.u4_src_wd,
116                 ps_buf->pu1_y + ps_params->s_luma.u4_dst_offset_res_buf,
117                 ps_params->s_luma.u4_dst_wd_res_buf,
118                 ps_params->s_luma.u4_cols,
119                 ps_params->s_luma.u4_rows);
120     /* Perform motion compensation for U */
121     ps_dec->pf_mc[ps_params->s_chroma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_u + ps_params->s_chroma.u4_src_offset,
122                 ps_params->s_chroma.u4_src_wd,
123                 ps_buf->pu1_u + ps_params->s_chroma.u4_dst_offset_res_buf,
124                 ps_params->s_chroma.u4_dst_wd_res_buf,
125                 ps_params->s_chroma.u4_cols,
126                 ps_params->s_chroma.u4_rows);
127 
128     /* Perform motion compensation for V */
129     ps_dec->pf_mc[ps_params->s_chroma.u4_mode]((void *)ps_dec, ps_params->s_ref.pu1_v + ps_params->s_chroma.u4_src_offset,
130                 ps_params->s_chroma.u4_src_wd,
131                 ps_buf->pu1_v + ps_params->s_chroma.u4_dst_offset_res_buf,
132                 ps_params->s_chroma.u4_dst_wd_res_buf,
133                 ps_params->s_chroma.u4_cols,
134                 ps_params->s_chroma.u4_rows);
135 }
136 
137 
138 
139 /*****************************************************************************/
140 /*                                                                           */
141 /*  Function Name : impeg2d_motion_comp_recon_buf                          */
142 /*                                                                           */
143 /*  Description   : Perform motion compensation and store the resulting block*/
144 /*                  in the buf                                               */
145 /*                                                                           */
146 /*  Inputs        : params - Parameters required to do motion compensation   */
147 /*                                                                           */
148 /*  Globals       :                                                          */
149 /*                                                                           */
150 /*  Processing    : Calls appropriate functions depending on the mode of     */
151 /*                  compensation                                             */
152 /*                                                                           */
153 /*  Outputs       : buf       - Buffer for the motion compensation result    */
154 /*                                                                           */
155 /*  Returns       : None                                                     */
156 /*                                                                           */
157 /*  Issues        : None                                                     */
158 /*                                                                           */
159 /*  Revision History:                                                        */
160 /*                                                                           */
161 /*         DD MM YYYY   Author(s)       Changes                              */
162 /*         14 09 2005   Harish M        First Version                        */
163 /*                                                                           */
164 /*****************************************************************************/
impeg2d_motion_comp_recon_buf(dec_state_t * ps_dec,mb_mc_params_t * ps_params,yuv_buf_t * ps_dest_buf)165 void impeg2d_motion_comp_recon_buf(dec_state_t *ps_dec,
166                                      mb_mc_params_t *ps_params,
167                                      yuv_buf_t *ps_dest_buf)
168 {
169 
170     PROFILE_DISABLE_MC_RETURN;
171 
172     /* Perform motion compensation for Y */
173     ps_dec->pf_mc[ps_params->s_luma.u4_mode](ps_dec, ps_params->s_ref.pu1_y + ps_params->s_luma.u4_src_offset,
174                                         ps_params->s_luma.u4_src_wd,
175                                         ps_dest_buf->pu1_y + ps_params->s_luma.u4_dst_offset_cur_frm,
176                                         ps_params->s_luma.u4_dst_wd_cur_frm,
177                                         ps_params->s_luma.u4_cols,
178                                         ps_params->s_luma.u4_rows);
179 
180     /* Perform motion compensation for U */
181 
182     ps_dec->pf_mc[ps_params->s_chroma.u4_mode](ps_dec, ps_params->s_ref.pu1_u + ps_params->s_chroma.u4_src_offset,
183                                         ps_params->s_chroma.u4_src_wd,
184                                         ps_dest_buf->pu1_u + ps_params->s_chroma.u4_dst_offset_cur_frm,
185                                         ps_params->s_chroma.u4_dst_wd_cur_frm,
186                                         ps_params->s_chroma.u4_cols,
187                                         ps_params->s_chroma.u4_rows);
188 
189     /* Perform motion compensation for V */
190     ps_dec->pf_mc[ps_params->s_chroma.u4_mode](ps_dec, ps_params->s_ref.pu1_v + ps_params->s_chroma.u4_src_offset,
191                                         ps_params->s_chroma.u4_src_wd,
192                                         ps_dest_buf->pu1_v + ps_params->s_chroma.u4_dst_offset_cur_frm,
193                                         ps_params->s_chroma.u4_dst_wd_cur_frm,
194                                         ps_params->s_chroma.u4_cols,
195                                         ps_params->s_chroma.u4_rows);
196 }
197 
198 
199 
200 /*****************************************************************************/
201 /*                                                                           */
202 /*  Function Name : impeg2d_mc_1mv                                           */
203 /*                                                                           */
204 /*  Description   : Perform motion compensation and store the resulting block*/
205 /*                  in the buf                                               */
206 /*                                                                           */
207 /*  Inputs        : params - Parameters required to do motion compensation   */
208 /*                                                                           */
209 /*  Globals       :                                                          */
210 /*                                                                           */
211 /*  Processing    : Calls appropriate functions depending on the mode of     */
212 /*                  compensation                                             */
213 /*                                                                           */
214 /*  Outputs       : buf       - Buffer for the motion compensation result    */
215 /*                                                                           */
216 /*  Returns       : None                                                     */
217 /*                                                                           */
218 /*  Issues        : None                                                     */
219 /*                                                                           */
220 /*  Revision History:                                                        */
221 /*                                                                           */
222 /*         DD MM YYYY   Author(s)       Changes                              */
223 /*         14 09 2005   Hairsh M        First Version                        */
224 /*                                                                           */
225 /*****************************************************************************/
impeg2d_mc_1mv(dec_state_t * ps_dec)226 void impeg2d_mc_1mv(dec_state_t *ps_dec)
227 {
228 
229     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[ps_dec->e_mb_pred][FIRST], &ps_dec->s_dest_buf);
230 }
231 
232 
233 
234 /*****************************************************************************/
235 /*                                                                           */
236 /*  Function Name : impeg2d_mc_fw_or_bk_mb                                   */
237 /*                                                                           */
238 /*  Description   : Perform motion compensation and store the resulting block*/
239 /*                  in the buf                                               */
240 /*                                                                           */
241 /*  Inputs        : params - Parameters required to do motion compensation   */
242 /*                                                                           */
243 /*  Globals       :                                                          */
244 /*                                                                           */
245 /*  Processing    : Calls appropriate functions depending on the mode of     */
246 /*                  compensation                                             */
247 /*                                                                           */
248 /*  Outputs       : buf       - Buffer for the motion compensation result    */
249 /*                                                                           */
250 /*  Returns       : None                                                     */
251 /*                                                                           */
252 /*  Issues        : None                                                     */
253 /*                                                                           */
254 /*  Revision History:                                                        */
255 /*                                                                           */
256 /*         DD MM YYYY   Author(s)       Changes                              */
257 /*         14 09 2005   Hairsh M        First Version                        */
258 /*                                                                           */
259 /*****************************************************************************/
impeg2d_mc_fw_or_bk_mb(dec_state_t * ps_dec)260 void impeg2d_mc_fw_or_bk_mb(dec_state_t *ps_dec)
261 {
262     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_dest_buf);
263     impeg2d_motion_comp_recon_buf(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_dest_buf);
264 }
265 
266 
267 
268 /*****************************************************************************/
269 /*                                                                           */
270 /*  Function Name : impeg2d_mc_frm_dual_prime                                */
271 /*                                                                           */
272 /*  Description   : Perform motion compensation and store the resulting block*/
273 /*                  in the buf                                               */
274 /*                                                                           */
275 /*  Inputs        : params - Parameters required to do motion compensation   */
276 /*                                                                           */
277 /*  Globals       :                                                          */
278 /*                                                                           */
279 /*  Processing    : Calls appropriate functions depending on the mode of     */
280 /*                  compensation                                             */
281 /*                                                                           */
282 /*  Outputs       : buf       - Buffer for the motion compensation result    */
283 /*                                                                           */
284 /*  Returns       : None                                                     */
285 /*                                                                           */
286 /*  Issues        : None                                                     */
287 /*                                                                           */
288 /*  Revision History:                                                        */
289 /*                                                                           */
290 /*         DD MM YYYY   Author(s)       Changes                              */
291 /*         14 09 2005   Hairsh M        First Version                        */
292 /*                                                                           */
293 /*****************************************************************************/
impeg2d_mc_frm_dual_prime(dec_state_t * ps_dec)294 void impeg2d_mc_frm_dual_prime(dec_state_t *ps_dec)
295 {
296     /************************************************************************/
297     /* Perform Motion Compensation                                          */
298     /************************************************************************/
299     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
300     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
301 
302     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_fw_buf);
303     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][SECOND], &ps_dec->s_mc_bk_buf);
304 
305 
306 
307     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
308 }
309 
310 
311 
312 /*****************************************************************************/
313 /*                                                                           */
314 /*  Function Name : impeg2d_mc_fld_dual_prime                                */
315 /*                                                                           */
316 /*  Description   : Perform motion compensation and store the resulting block*/
317 /*                  in the buf                                               */
318 /*                                                                           */
319 /*  Inputs        : params - Parameters required to do motion compensation   */
320 /*                                                                           */
321 /*  Globals       :                                                          */
322 /*                                                                           */
323 /*  Processing    : Calls appropriate functions depending on the mode of     */
324 /*                  compensation                                             */
325 /*                                                                           */
326 /*  Outputs       : buf       - Buffer for the motion compensation result    */
327 /*                                                                           */
328 /*  Returns       : None                                                     */
329 /*                                                                           */
330 /*  Issues        : None                                                     */
331 /*                                                                           */
332 /*  Revision History:                                                        */
333 /*                                                                           */
334 /*         DD MM YYYY   Author(s)       Changes                              */
335 /*         14 09 2005   Hairsh M        First Version                        */
336 /*                                                                           */
337 /*****************************************************************************/
impeg2d_mc_fld_dual_prime(dec_state_t * ps_dec)338 void impeg2d_mc_fld_dual_prime(dec_state_t *ps_dec)
339 {
340     /************************************************************************/
341     /* Perform Motion Compensation                                          */
342     /************************************************************************/
343     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
344     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_bk_buf);
345 
346 
347     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
348 }
349 
350 
351 
352 
353 
354 /*****************************************************************************/
355 /*                                                                           */
356 /*  Function Name : impeg2d_mc_4mv                                      */
357 /*                                                                           */
358 /*  Description   : Perform motion compensation and store the resulting block*/
359 /*                  in the buf                                               */
360 /*                                                                           */
361 /*  Inputs        : params - Parameters required to do motion compensation   */
362 /*                                                                           */
363 /*  Globals       :                                                          */
364 /*                                                                           */
365 /*  Processing    : Calls appropriate functions depending on the mode of     */
366 /*                  compensation                                             */
367 /*                                                                           */
368 /*  Outputs       : buf       - Buffer for the motion compensation result    */
369 /*                                                                           */
370 /*  Returns       : None                                                     */
371 /*                                                                           */
372 /*  Issues        : None                                                     */
373 /*                                                                           */
374 /*  Revision History:                                                        */
375 /*                                                                           */
376 /*         DD MM YYYY   Author(s)       Changes                              */
377 /*         14 09 2005   Hairsh M        First Version                        */
378 /*                                                                           */
379 /*****************************************************************************/
impeg2d_mc_4mv(dec_state_t * ps_dec)380 void impeg2d_mc_4mv(dec_state_t *ps_dec)
381 {
382     /************************************************************************/
383     /* Perform Motion Compensation                                          */
384     /************************************************************************/
385     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
386     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
387     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][SECOND], &ps_dec->s_mc_fw_buf);
388     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][SECOND], &ps_dec->s_mc_bk_buf);
389 
390     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
391 }
392 
393 /*****************************************************************************/
394 /*                                                                           */
395 /*  Function Name : impeg2d_mc_2mv                                         */
396 /*                                                                           */
397 /*  Description   : Perform motion compensation and store the resulting block*/
398 /*                  in the buf                                               */
399 /*                                                                           */
400 /*  Inputs        : params - Parameters required to do motion compensation   */
401 /*                                                                           */
402 /*  Globals       :                                                          */
403 /*                                                                           */
404 /*  Processing    : Calls appropriate functions depending on the mode of     */
405 /*                  compensation                                             */
406 /*                                                                           */
407 /*  Outputs       : buf       - Buffer for the motion compensation result    */
408 /*                                                                           */
409 /*  Returns       : None                                                     */
410 /*                                                                           */
411 /*  Issues        : None                                                     */
412 /*                                                                           */
413 /*  Revision History:                                                        */
414 /*                                                                           */
415 /*         DD MM YYYY   Author(s)       Changes                              */
416 /*         14 09 2005   Hairsh M        First Version                        */
417 /*                                                                           */
418 /*****************************************************************************/
impeg2d_mc_2mv(dec_state_t * ps_dec)419 void impeg2d_mc_2mv(dec_state_t *ps_dec)
420 {
421    /************************************************************************/
422     /* Perform Motion Compensation                                          */
423     /************************************************************************/
424     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
425     impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
426 
427     ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&ps_dec->s_dest_buf,ps_dec->u2_picture_width);
428 }
429 
430 /*****************************************************************************
431 *  Function Name   : impeg2d_dec_intra_mb
432 *
433 *  Description     : Performs decoding of Intra MB
434 *
435 *  Arguments       :
436 *  dec             : Decoder state
437 *
438 *  Values Returned : None
439 *****************************************************************************/
impeg2d_dec_intra_mb(dec_state_t * ps_dec)440 void impeg2d_dec_intra_mb(dec_state_t *ps_dec)
441 {
442 
443     ps_dec->u2_cbp = 0x3F;
444     if(ps_dec->u2_concealment_motion_vectors)
445     {
446 
447         stream_t *ps_stream;
448 
449         ps_stream = &ps_dec->s_bit_stream;
450         /* Decode the concealment motion vector */
451         impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[FORW][FIRST],ps_dec->ai2_mv[FORW][FIRST],
452         ps_dec->au2_f_code[FORW],0,ps_dec->u2_fld_pic);
453 
454 
455         /* Set the second motion vector predictor */
456         ps_dec->ai2_pred_mv[FORW][SECOND][MV_X] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X];
457         ps_dec->ai2_pred_mv[FORW][SECOND][MV_Y] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y];
458 
459         /* Flush the marker bit */
460         if(0 == (impeg2d_bit_stream_get(ps_stream,1)))
461         {
462             /* Ignore marker bit error */
463         }
464     }
465     else
466     {
467         /* Reset the motion vector predictors */
468         memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
469     }
470 }
471 
472 /*****************************************************************************
473 *  Function Name   : impeg2d_dec_skip_p_mb
474 *
475 *  Description     : Performs decoding needed for Skipped MB encountered in
476 *                    P Pictures and B Pictures with previous MB not bi-predicted
477 *
478 *  Arguments       :
479 *  dec             : Decoder state
480 *
481 *  Values Returned : None
482 *****************************************************************************/
impeg2d_dec_skip_p_mb(dec_state_t * ps_dec,WORD32 u4_num_of_mbs)483 void impeg2d_dec_skip_p_mb(dec_state_t *ps_dec, WORD32 u4_num_of_mbs)
484 {
485     WORD16  *pi2_mv;
486 
487     e_mb_type_t e_mb_type;
488     mb_mc_params_t *ps_mc;
489 
490 
491     WORD32 i4_iter;
492     UWORD32 u4_dst_wd;
493     UWORD32  u4_dst_offset_x;
494     UWORD32  u4_dst_offset_y;
495     UWORD32 u4_frm_offset = 0;
496     yuv_buf_t s_dst;
497 
498     u4_dst_wd = ps_dec->u2_frame_width;
499 
500     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
501     {
502         u4_dst_wd <<= 1;
503         if(ps_dec->u2_picture_structure == BOTTOM_FIELD)
504         {
505             u4_frm_offset = ps_dec->u2_frame_width;
506         }
507     }
508 
509     for (i4_iter = u4_num_of_mbs; i4_iter > 0; i4_iter--)
510     {
511         if(ps_dec->u2_picture_structure == FRAME_PICTURE)
512         {
513             e_mb_type = MC_FRM_FW_AND_BK_2MV;
514         }
515         else
516         {
517             e_mb_type = MC_FLD_FW_AND_BK_2MV;
518         }
519 
520         ps_dec->u2_prev_intra_mb = 0;
521         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]);
522 
523         /* Reset the motion vector predictors */
524         if(ps_dec->e_pic_type == P_PIC)
525         {
526             memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
527             pi2_mv[MV_X]    = pi2_mv[MV_Y] = 0;
528 
529             ps_dec->u2_cbp     = 0;
530 
531             pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
532             ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
533             ps_mc->s_ref      = ps_dec->as_ref_buf[ps_dec->e_mb_pred][ps_dec->u2_fld_parity];
534 
535             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
536                       pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
537 
538 
539             u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
540             u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
541 
542             s_dst.pu1_y = ps_dec->s_cur_frm_buf.pu1_y + u4_dst_offset_x + u4_dst_offset_y;
543 
544             u4_dst_offset_x = u4_dst_offset_x >> 1;
545             u4_dst_offset_y = u4_dst_offset_y >> 2;
546 
547             s_dst.pu1_u = ps_dec->s_cur_frm_buf.pu1_u + u4_dst_offset_x + u4_dst_offset_y;
548             s_dst.pu1_v = ps_dec->s_cur_frm_buf.pu1_v + u4_dst_offset_x + u4_dst_offset_y;
549 
550 
551             ps_mc->s_ref.pu1_y += ps_mc->s_luma.u4_src_offset;
552             ps_mc->s_ref.pu1_u += ps_mc->s_chroma.u4_src_offset;
553             ps_mc->s_ref.pu1_v += ps_mc->s_chroma.u4_src_offset;
554 
555             ps_dec->pf_copy_mb(&ps_mc->s_ref, &s_dst, ps_mc->s_luma.u4_src_wd, u4_dst_wd);
556         }
557 
558         else
559         {
560             pi2_mv[MV_X]    = ps_dec->ai2_pred_mv[ps_dec->e_mb_pred][FIRST][MV_X];
561             pi2_mv[MV_Y]    = ps_dec->ai2_pred_mv[ps_dec->e_mb_pred][FIRST][MV_Y];
562 
563             ps_dec->u2_cbp     = 0;
564 
565             pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
566             ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
567             ps_mc->s_ref      = ps_dec->as_ref_buf[ps_dec->e_mb_pred][ps_dec->u2_fld_parity];
568 
569             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
570                       pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
571 
572             u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
573             u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
574 
575             ps_mc->s_luma.u4_dst_offset_res_buf = u4_dst_offset_x + u4_dst_offset_y;
576             ps_mc->s_luma.u4_dst_wd_res_buf = u4_dst_wd;
577 
578             u4_dst_offset_x = u4_dst_offset_x >> 1;
579             u4_dst_offset_y = u4_dst_offset_y >> 2;
580 
581             ps_mc->s_chroma.u4_dst_offset_res_buf = u4_dst_offset_x + u4_dst_offset_y;
582             ps_mc->s_chroma.u4_dst_wd_res_buf = u4_dst_wd >> 1;
583 
584             impeg2d_motion_comp(ps_dec, ps_mc, &ps_dec->s_cur_frm_buf);
585         }
586 
587 
588         /********************************************************************/
589         /* Common MB processing tasks                                       */
590         /********************************************************************/
591         ps_dec->u2_mb_x++;
592         ps_dec->u2_num_mbs_left--;
593 
594         if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb)
595         {
596             ps_dec->u2_mb_x = 0;
597             ps_dec->u2_mb_y++;
598         }
599     }
600 
601 }
602 
603 /*******************************************************************************
604 *  Function Name   : impeg2d_dec_skip_b_mb
605 *
606 *  Description     : Performs processing needed for Skipped MB encountered in
607 *                    B Pictures with previous MB bi-predicted.
608 *
609 *  Arguments       :
610 *  dec             : Decoder state
611 *
612 *  Values Returned : None
613 *******************************************************************************/
impeg2d_dec_skip_b_mb(dec_state_t * ps_dec,WORD32 u4_num_of_mbs)614 void impeg2d_dec_skip_b_mb(dec_state_t *ps_dec, WORD32 u4_num_of_mbs)
615 {
616 
617 
618     WORD16  *pi2_mv;
619 
620     UWORD32 i;
621     e_mb_type_t e_mb_type;
622     mb_mc_params_t *ps_mc;
623 
624     WORD32 i4_iter;
625     UWORD32 u4_dst_wd;
626     yuv_buf_t s_dst;
627     UWORD32  u4_dst_offset_x;
628     UWORD32  u4_dst_offset_y;
629     UWORD32 u4_frm_offset = 0;
630 
631     u4_dst_wd = ps_dec->u2_frame_width;
632     s_dst = ps_dec->s_cur_frm_buf;
633 
634     if(ps_dec->u2_picture_structure != FRAME_PICTURE)
635     {
636         u4_dst_wd <<= 1;
637         if(ps_dec->u2_picture_structure == BOTTOM_FIELD)
638         {
639             u4_frm_offset = ps_dec->u2_frame_width;
640         }
641     }
642 
643     for (i4_iter = u4_num_of_mbs; i4_iter > 0; i4_iter--)
644     {
645         ps_dec->u2_prev_intra_mb = 0;
646 
647         if(ps_dec->u2_picture_structure == FRAME_PICTURE)
648         {
649             e_mb_type = MC_FRM_FW_AND_BK_2MV;
650         }
651         else
652         {
653             e_mb_type = MC_FLD_FW_AND_BK_2MV;
654         }
655 
656         /************************************************************************/
657         /* Setting of first motion vector for B MB                              */
658         /************************************************************************/
659         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]);
660         {
661             pi2_mv[MV_X]         = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X];
662             pi2_mv[MV_Y]         = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y];
663         }
664         /************************************************************************/
665         /* Setting of second motion vector for B MB                             */
666         /************************************************************************/
667         pi2_mv               = (WORD16 *)&(ps_dec->ai2_mv[BACK][FIRST]);
668         {
669             pi2_mv[MV_X]         = ps_dec->ai2_pred_mv[BACK][FIRST][MV_X];
670             pi2_mv[MV_Y]         = ps_dec->ai2_pred_mv[BACK][FIRST][MV_Y];
671         }
672         ps_dec->u2_cbp  = 0;
673 
674         for(i = 0; i < 2; i++)
675         {
676             pi2_mv          = (WORD16 *)&ps_dec->ai2_mv[i][FIRST];
677             ps_mc          = &ps_dec->as_mb_mc_params[i][FIRST];
678             ps_mc->s_ref     = ps_dec->as_ref_buf[i][ps_dec->u2_fld_parity];
679 
680             impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0, pi2_mv, ps_dec->u2_mb_x,
681                           ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
682         }
683 
684         impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[FORW][FIRST], &ps_dec->s_mc_fw_buf);
685         impeg2d_motion_comp(ps_dec, &ps_dec->as_mb_mc_params[BACK][FIRST], &ps_dec->s_mc_bk_buf);
686 
687         u4_dst_offset_x = (ps_dec->u2_mb_x << 4) + u4_frm_offset;
688         u4_dst_offset_y = (ps_dec->u2_mb_y << 4) * u4_dst_wd;
689 
690         s_dst.pu1_y = ps_dec->s_cur_frm_buf.pu1_y + u4_dst_offset_x + u4_dst_offset_y;
691 
692         u4_dst_offset_x = u4_dst_offset_x >> 1;
693         u4_dst_offset_y = u4_dst_offset_y >> 2;
694 
695         s_dst.pu1_u = ps_dec->s_cur_frm_buf.pu1_u + u4_dst_offset_x + u4_dst_offset_y;
696         s_dst.pu1_v = ps_dec->s_cur_frm_buf.pu1_v + u4_dst_offset_x + u4_dst_offset_y;
697 
698         ps_dec->pf_interpolate(&ps_dec->s_mc_fw_buf,&ps_dec->s_mc_bk_buf,&s_dst, u4_dst_wd);
699 //        dec->pf_copy_mb(&dec->mc_buf, &dst, MB_SIZE, dst_wd);
700 
701         /********************************************************************/
702         /* Common MB processing tasks                                       */
703         /********************************************************************/
704         ps_dec->u2_mb_x++;
705         ps_dec->u2_num_mbs_left--;
706 
707         if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb)
708         {
709             ps_dec->u2_mb_x = 0;
710             ps_dec->u2_mb_y++;
711         }
712     }
713 }
714 /*******************************************************************************
715 *  Function Name   : impeg2d_dec_skip_mbs
716 *
717 *  Description     : Performs processing needed for Skipped MB encountered in
718 *                    B Pictures with previous MB bi-predicted.
719 *
720 *  Arguments       :
721 *  dec             : Decoder state
722 *
723 *  Values Returned : None
724 *******************************************************************************/
impeg2d_dec_skip_mbs(dec_state_t * ps_dec,UWORD16 u2_num_skip_mbs)725 void impeg2d_dec_skip_mbs(dec_state_t *ps_dec, UWORD16 u2_num_skip_mbs)
726 {
727     PROFILE_DISABLE_SKIP_MB();
728 
729     if(ps_dec->e_mb_pred == BIDIRECT)
730     {
731         impeg2d_dec_skip_b_mb(ps_dec, u2_num_skip_mbs);
732     }
733     else
734     {
735         impeg2d_dec_skip_p_mb(ps_dec, u2_num_skip_mbs);
736     }
737 
738     ps_dec->u2_def_dc_pred[Y_LUMA] = 128 << ps_dec->u2_intra_dc_precision;
739     ps_dec->u2_def_dc_pred[U_CHROMA] = 128 << ps_dec->u2_intra_dc_precision;
740     ps_dec->u2_def_dc_pred[V_CHROMA] = 128 << ps_dec->u2_intra_dc_precision;
741 }
742 
743 
744 
745 
746 /*****************************************************************************
747 *  Function Name   : impeg2d_dec_0mv_coded_mb
748 *
749 *  Description     : Decodes the MB with 0 MV but coded. This can occur in P
750 *                    pictures only
751 *
752 *  Arguments       :
753 *  dec             : Decoder state
754 *
755 *  Values Returned : None
756 *****************************************************************************/
impeg2d_dec_0mv_coded_mb(dec_state_t * ps_dec)757 void impeg2d_dec_0mv_coded_mb(dec_state_t *ps_dec)
758 {
759 
760 
761     WORD16   *pi2_mv;
762     e_mb_type_t e_mb_type;
763     mb_mc_params_t *ps_mc;
764 
765     if(ps_dec->u2_picture_structure == FRAME_PICTURE)
766     {
767         e_mb_type = MC_FRM_FW_AND_BK_2MV;
768     }
769     else
770     {
771         e_mb_type = MC_FLD_FW_AND_BK_2MV;
772     }
773 
774 
775 
776 
777     /* Reset the motion vector predictors */
778     memset(ps_dec->ai2_pred_mv,0,sizeof(ps_dec->ai2_pred_mv));
779 
780     pi2_mv           = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST];
781     ps_mc           = &ps_dec->as_mb_mc_params[FORW][FIRST];
782     ps_mc->s_ref      = ps_dec->as_ref_buf[FORW][ps_dec->u2_fld_parity];
783 
784     pi2_mv[MV_X] = 0;
785     pi2_mv[MV_Y] = 0;
786 
787     impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, e_mb_type, 0,
788               pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width);
789 }
790 
791 /*****************************************************************************/
792 /*                                                                           */
793 /*  Function Name : impeg2d_mc_halfx_halfy()                                 */
794 /*                                                                           */
795 /*  Description   : Gets the buffer from (0.5,0.5) to (8.5,8.5)              */
796 /*                  and the above block of size 8 x 8 will be placed as a    */
797 /*                  block from the current position of out_buf               */
798 /*                                                                           */
799 /*  Inputs        : ref - Reference frame from which the block will be       */
800 /*                        block will be extracted.                           */
801 /*                  ref_wid - WIdth of reference frame                       */
802 /*                  out_wid - WIdth of the output frame                      */
803 /*                  blk_width  - width of the block                          */
804 /*                  blk_width  - height of the block                         */
805 /*                                                                           */
806 /*  Globals       : None                                                     */
807 /*                                                                           */
808 /*  Processing    : Point to the (0,0),(1,0),(0,1),(1,1) position in         */
809 /*                  the ref frame.Interpolate these four values to get the   */
810 /*                  value at(0.5,0.5).Repeat this to get an 8 x 8 block      */
811 /*                  using 9 x 9 block from reference frame                   */
812 /*                                                                           */
813 /*  Outputs       : out -  Output containing the extracted block             */
814 /*                                                                           */
815 /*  Returns       : None                                                     */
816 /*                                                                           */
817 /*  Issues        : None                                                     */
818 /*                                                                           */
819 /*  Revision History:                                                        */
820 /*                                                                           */
821 /*         DD MM YYYY   Author(s)       Changes                              */
822 /*         05 09 2005   Harish M        First Version                        */
823 /*                                                                           */
824 /*****************************************************************************/
impeg2d_mc_halfx_halfy(void * pv_dec,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD8 * pu1_out,UWORD32 u4_out_wid,UWORD32 u4_blk_width,UWORD32 u4_blk_height)825 void impeg2d_mc_halfx_halfy(void *pv_dec,
826                            UWORD8 *pu1_ref,
827                            UWORD32 u4_ref_wid,
828                            UWORD8 *pu1_out,
829                            UWORD32 u4_out_wid,
830                            UWORD32 u4_blk_width,
831                            UWORD32 u4_blk_height)
832 {
833    UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
834    dec_state_t *ps_dec = (dec_state_t *)pv_dec;
835 
836         pu1_out_ptr = pu1_out;
837         pu1_ref_ptr = pu1_ref;
838 
839     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
840     {
841 
842         /*luma 16 x 16*/
843 
844         /*block 0*/
845         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
846 
847         /*block1*/
848         pu1_out_ptr = (pu1_out + BLK_SIZE);
849         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
850         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
851 
852         /*block 2*/
853         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
854         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
855         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
856 
857         /*block 3*/
858         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
859         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
860         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
861 
862 
863 
864 
865     }
866     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
867     {
868         /*chroma 8 x 8*/
869         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
870     }
871     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
872     {
873         /*block 0*/
874         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
875 
876         /*block 1*/
877         pu1_out_ptr = (pu1_out + BLK_SIZE);
878         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
879         ps_dec->pf_halfx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
880 
881     }
882 
883     else
884     {
885         UWORD8 *ref_p0,*ref_p1,*ref_p2,*ref_p3;
886         UWORD32 i,j;
887         /* P0-P3 are the pixels in the reference frame and Q is the value being */
888         /* estimated                                                            */
889         /*
890            P0 P1
891              Q
892            P2 P3
893         */
894 
895         ref_p0 = pu1_ref;
896         ref_p1 = pu1_ref + 1;
897         ref_p2 = pu1_ref + u4_ref_wid;
898         ref_p3 = pu1_ref + u4_ref_wid + 1;
899 
900         for(i = 0; i < u4_blk_height; i++)
901         {
902             for(j = 0; j < u4_blk_width; j++)
903             {
904                 *pu1_out++ =   (( (*ref_p0++ )
905                             + (*ref_p1++ )
906                             + (*ref_p2++ )
907                             + (*ref_p3++ ) + 2 ) >> 2);
908             }
909             ref_p0 += u4_ref_wid - u4_blk_width;
910             ref_p1 += u4_ref_wid - u4_blk_width;
911             ref_p2 += u4_ref_wid - u4_blk_width;
912             ref_p3 += u4_ref_wid - u4_blk_width;
913 
914             pu1_out    += u4_out_wid - u4_blk_width;
915         }
916     }
917     return;
918 }
919 
920 /*****************************************************************************/
921 /*                                                                           */
922 /*  Function Name : impeg2d_mc_halfx_fully()                                 */
923 /*                                                                           */
924 /*  Description   : Gets the buffer from (0.5,0) to (8.5,8)                  */
925 /*                  and the above block of size 8 x 8 will be placed as a    */
926 /*                  block from the current position of out_buf               */
927 /*                                                                           */
928 /*  Inputs        : ref - Reference frame from which the block will be       */
929 /*                        block will be extracted.                           */
930 /*                  ref_wid - WIdth of reference frame                       */
931 /*                  out_wid - WIdth of the output frame                      */
932 /*                  blk_width  - width of the block                          */
933 /*                  blk_width  - height of the block                         */
934 /*                                                                           */
935 /*  Globals       : None                                                     */
936 /*                                                                           */
937 /*  Processing    : Point to the (0,0) and (1,0) position in the ref frame   */
938 /*                  Interpolate these two values to get the value at(0.5,0)  */
939 /*                  Repeat this to get an 8 x 8 block using 9 x 8 block from */
940 /*                  reference frame                                          */
941 /*                                                                           */
942 /*  Outputs       : out -  Output containing the extracted block             */
943 /*                                                                           */
944 /*  Returns       : None                                                     */
945 /*                                                                           */
946 /*  Issues        : None                                                     */
947 /*                                                                           */
948 /*  Revision History:                                                        */
949 /*                                                                           */
950 /*         DD MM YYYY   Author(s)       Changes                              */
951 /*         05 09 2005   Harish M        First Version                        */
952 /*                                                                           */
953 /*****************************************************************************/
954 
impeg2d_mc_halfx_fully(void * pv_dec,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD8 * pu1_out,UWORD32 u4_out_wid,UWORD32 u4_blk_width,UWORD32 u4_blk_height)955 void impeg2d_mc_halfx_fully(void *pv_dec,
956                             UWORD8 *pu1_ref,
957                             UWORD32 u4_ref_wid,
958                             UWORD8 *pu1_out,
959                             UWORD32 u4_out_wid,
960                             UWORD32 u4_blk_width,
961                             UWORD32 u4_blk_height)
962 {
963     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
964     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
965 
966         pu1_out_ptr = pu1_out;
967         pu1_ref_ptr = pu1_ref;
968 
969     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
970     {
971 
972         /*luma 16 x 16*/
973 
974         /*block 0*/
975         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
976 
977         /*block1*/
978         pu1_out_ptr = (pu1_out + BLK_SIZE);
979         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
980         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
981 
982         /*block 2*/
983         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
984         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
985         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
986 
987         /*block 3*/
988         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
989         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
990         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
991 
992 
993 
994 
995     }
996     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
997     {
998         /*chroma 8 x 8*/
999         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1000     }
1001     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
1002     {
1003         /*block 0*/
1004         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1005 
1006         /*block 1*/
1007         pu1_out_ptr = (pu1_out + BLK_SIZE);
1008         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
1009         ps_dec->pf_halfx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1010 
1011     }
1012 
1013     else
1014     {
1015         UWORD8 *ref_p0,*ref_p1;
1016         UWORD32 i,j;
1017 
1018         /* P0-P3 are the pixels in the reference frame and Q is the value being */
1019         /* estimated                                                            */
1020         /*
1021            P0 Q P1
1022         */
1023 
1024         ref_p0 = pu1_ref;
1025         ref_p1 = pu1_ref + 1;
1026 
1027         for(i = 0; i < u4_blk_height; i++)
1028         {
1029             for(j = 0; j < u4_blk_width; j++)
1030             {
1031                 *pu1_out++ =   ((( *ref_p0++ )
1032                             + (*ref_p1++) + 1 ) >> 1);
1033             }
1034             ref_p0 += u4_ref_wid - u4_blk_width;
1035             ref_p1 += u4_ref_wid - u4_blk_width;
1036 
1037             pu1_out    += u4_out_wid - u4_blk_width;
1038         }
1039     }
1040     return;
1041 }
1042 
1043 
1044 /*****************************************************************************/
1045 /*                                                                           */
1046 /*  Function Name : impeg2d_mc_fullx_halfy()                                 */
1047 /*                                                                           */
1048 /*  Description   : Gets the buffer from (0,0.5) to (8,8.5)                  */
1049 /*                  and the above block of size 8 x 8 will be placed as a    */
1050 /*                  block from the current position of out_buf               */
1051 /*                                                                           */
1052 /*  Inputs        : ref - Reference frame from which the block will be       */
1053 /*                        block will be extracted.                           */
1054 /*                  ref_wid - WIdth of reference frame                       */
1055 /*                  out_wid - WIdth of the output frame                      */
1056 /*                  blk_width  - width of the block                          */
1057 /*                  blk_width  - height of the block                         */
1058 /*                                                                           */
1059 /*  Globals       : None                                                     */
1060 /*                                                                           */
1061 /*  Processing    : Point to the (0,0) and (0,1)   position in the ref frame */
1062 /*                  Interpolate these two values to get the value at(0,0.5)  */
1063 /*                  Repeat this to get an 8 x 8 block using 8 x 9 block from */
1064 /*                  reference frame                                          */
1065 /*                                                                           */
1066 /*  Outputs       : out -  Output containing the extracted block             */
1067 /*                                                                           */
1068 /*  Returns       : None                                                     */
1069 /*                                                                           */
1070 /*  Issues        : None                                                     */
1071 /*                                                                           */
1072 /*  Revision History:                                                        */
1073 /*                                                                           */
1074 /*         DD MM YYYY   Author(s)       Changes                              */
1075 /*         05 09 2005   Harish M        First Version                        */
1076 /*                                                                           */
1077 /*****************************************************************************/
impeg2d_mc_fullx_halfy(void * pv_dec,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD8 * pu1_out,UWORD32 u4_out_wid,UWORD32 u4_blk_width,UWORD32 u4_blk_height)1078 void impeg2d_mc_fullx_halfy(void *pv_dec,
1079                             UWORD8 *pu1_ref,
1080                             UWORD32 u4_ref_wid,
1081                             UWORD8 *pu1_out,
1082                             UWORD32 u4_out_wid,
1083                             UWORD32 u4_blk_width,
1084                             UWORD32 u4_blk_height)
1085 {
1086 
1087     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
1088     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
1089         pu1_out_ptr = pu1_out;
1090         pu1_ref_ptr = pu1_ref;
1091 
1092     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
1093     {
1094 
1095         /*luma 16 x 16*/
1096 
1097         /*block 0*/
1098         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1099 
1100         /*block1*/
1101         pu1_out_ptr = (pu1_out + BLK_SIZE);
1102         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
1103         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1104 
1105         /*block 2*/
1106         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
1107         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
1108         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1109 
1110         /*block 3*/
1111         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
1112         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
1113         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1114 
1115 
1116 
1117 
1118     }
1119     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
1120     {
1121         /*chroma 8 x 8*/
1122         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1123     }
1124     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
1125     {
1126         /*block 0*/
1127         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1128 
1129         /*block 1*/
1130         pu1_out_ptr = (pu1_out + BLK_SIZE);
1131         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
1132         ps_dec->pf_fullx_halfy_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1133 
1134     }
1135 
1136     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == (BLK_SIZE / 2)))
1137     {
1138         UWORD8 *ref_p0,*ref_p1;
1139         UWORD32 i,j;
1140         /* P0-P3 are the pixels in the reference frame and Q is the value being */
1141         /* estimated                                                            */
1142         /*
1143            P0
1144             x
1145            P1
1146         */
1147         ref_p0 = pu1_ref;
1148         ref_p1 = pu1_ref + u4_ref_wid;
1149 
1150         for(i = 0; i < u4_blk_height; i++)
1151         {
1152             for(j = 0; j < u4_blk_width; j++)
1153             {
1154                 *pu1_out++ =   ((( *ref_p0++)
1155                             + (*ref_p1++) + 1 ) >> 1);
1156             }
1157             ref_p0 += u4_ref_wid - u4_blk_width;
1158             ref_p1 += u4_ref_wid - u4_blk_width;
1159 
1160             pu1_out    += u4_out_wid - u4_blk_width;
1161         }
1162     }
1163     return;
1164 }
1165 
1166 /*****************************************************************************/
1167 /*                                                                           */
1168 /*  Function Name : impeg2d_mc_fullx_fully()                                 */
1169 /*                                                                           */
1170 /*  Description   : Gets the buffer from (x,y) to (x+8,y+8)                  */
1171 /*                  and the above block of size 8 x 8 will be placed as a    */
1172 /*                  block from the current position of out_buf               */
1173 /*                                                                           */
1174 /*  Inputs        : ref - Reference frame from which the block will be       */
1175 /*                        block will be extracted.                           */
1176 /*                  ref_wid - WIdth of reference frame                       */
1177 /*                  out_wid - WIdth of the output frame                      */
1178 /*                  blk_width  - width of the block                          */
1179 /*                  blk_width  - height of the block                         */
1180 /*                                                                           */
1181 /*  Globals       : None                                                     */
1182 /*                                                                           */
1183 /*  Processing    : Point to the (0,0) position in the ref frame             */
1184 /*                  Get an 8 x 8 block from reference frame                  */
1185 /*                                                                           */
1186 /*  Outputs       : out -  Output containing the extracted block             */
1187 /*                                                                           */
1188 /*  Returns       : None                                                     */
1189 /*                                                                           */
1190 /*  Issues        : None                                                     */
1191 /*                                                                           */
1192 /*  Revision History:                                                        */
1193 /*                                                                           */
1194 /*         DD MM YYYY   Author(s)       Changes                              */
1195 /*         05 09 2005   Harish M        First Version                        */
1196 /*                                                                           */
1197 /*****************************************************************************/
1198 
impeg2d_mc_fullx_fully(void * pv_dec,UWORD8 * pu1_ref,UWORD32 u4_ref_wid,UWORD8 * pu1_out,UWORD32 u4_out_wid,UWORD32 u4_blk_width,UWORD32 u4_blk_height)1199 void impeg2d_mc_fullx_fully(void *pv_dec,
1200                             UWORD8 *pu1_ref,
1201                             UWORD32 u4_ref_wid,
1202                             UWORD8 *pu1_out,
1203                             UWORD32 u4_out_wid,
1204                             UWORD32 u4_blk_width,
1205                             UWORD32 u4_blk_height)
1206 {
1207 
1208     UWORD8 *pu1_out_ptr,*pu1_ref_ptr;
1209     dec_state_t *ps_dec = (dec_state_t *)pv_dec;
1210 
1211         pu1_out_ptr = pu1_out;
1212         pu1_ref_ptr = pu1_ref;
1213 
1214     if((u4_blk_width == MB_SIZE) && (u4_blk_height == MB_SIZE))
1215     {
1216 
1217         /*luma 16 x 16*/
1218 
1219         /*block 0*/
1220         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1221 
1222         /*block1*/
1223         pu1_out_ptr = (pu1_out + BLK_SIZE);
1224         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
1225         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1226 
1227         /*block 2*/
1228         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid;
1229         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid;
1230         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1231 
1232         /*block 3*/
1233         pu1_out_ptr = pu1_out + BLK_SIZE * u4_out_wid + BLK_SIZE;
1234         pu1_ref_ptr = pu1_ref + BLK_SIZE * u4_ref_wid + BLK_SIZE;
1235         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1236 
1237 
1238 
1239 
1240     }
1241     else if ((u4_blk_width == BLK_SIZE) && (u4_blk_height == BLK_SIZE))
1242     {
1243         /*chroma 8 x 8*/
1244         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1245     }
1246     else if ((u4_blk_width == MB_SIZE) && (u4_blk_height == BLK_SIZE))
1247     {
1248         /*block 0*/
1249         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1250 
1251         /*block 1*/
1252         pu1_out_ptr = (pu1_out + BLK_SIZE);
1253         pu1_ref_ptr = (pu1_ref + BLK_SIZE);
1254         ps_dec->pf_fullx_fully_8x8(pu1_out_ptr,pu1_ref_ptr,u4_ref_wid,u4_out_wid);
1255 
1256     }
1257     else
1258     {
1259         UWORD32 i;
1260 
1261         for(i = 0; i < u4_blk_height; i++)
1262         {
1263             memcpy(pu1_out, pu1_ref, u4_blk_width);
1264             pu1_ref += u4_ref_wid;
1265             pu1_out += u4_out_wid;
1266         }
1267     }
1268     return;
1269 }
1270 
1271 /*******************************************************************************
1272 *  Function Name   : impeg2d_set_mc_params
1273 *
1274 *  Description     : Sets the parameters for Motion Compensation
1275 *
1276 *  Arguments       :
1277 *  luma            : Parameters for luma blocks
1278 *  chroma          : Parameters for chroma blocks
1279 *  type            : Motion compensation type
1280 *  mv_num          : Number of motion vectors
1281 *  mv              : Motion Vectors
1282 *  mb_x            : X co-ordinate of MB
1283 *  mb_y            : Y co-ordinate of MB
1284 *  frm_wd          : Width of the frame
1285 *
1286 *  Values Returned : None
1287 *******************************************************************************/
impeg2d_set_mc_params(comp_mc_params_t * ps_luma,comp_mc_params_t * ps_chroma,e_mb_type_t e_type,UWORD16 u2_mv_num,WORD16 ai2_mv[],UWORD16 u2_mb_x,UWORD16 u2_mb_y,UWORD16 u2_frm_wd,UWORD16 u2_frm_ht,UWORD16 u2_picture_width)1288 void impeg2d_set_mc_params(comp_mc_params_t *ps_luma,
1289                            comp_mc_params_t *ps_chroma,
1290                            e_mb_type_t e_type,
1291                            UWORD16 u2_mv_num,
1292                            WORD16 ai2_mv[],
1293                            UWORD16 u2_mb_x,
1294                            UWORD16 u2_mb_y,
1295                            UWORD16 u2_frm_wd,
1296                            UWORD16 u2_frm_ht,
1297                            UWORD16 u2_picture_width)
1298 {
1299     WORD16 i2_mvy_round;
1300     WORD16 i2_mvx_round;
1301     const mc_type_consts_t *ps_mc_params;
1302     WORD16 i2_mvx_fullp_round;
1303     WORD16 i2_mvy_fullp_round;
1304     UWORD32 u4_frm_chroma_wd;
1305     WORD16 i2_pix_x, i2_pix_y;
1306 
1307     ps_mc_params = &gas_impeg2d_mc_params_luma[e_type][u2_mv_num];
1308     /****************************************************************************/
1309     /* get luma mc params                                                       */
1310     /****************************************************************************/
1311     i2_pix_x = MB_SIZE * u2_mb_x + (ai2_mv[MV_X]>>1);
1312     i2_pix_y = (MB_SIZE * u2_mb_y  +
1313         (ai2_mv[MV_Y]>>1) * ps_mc_params->mvy_cf + u2_mv_num * ps_mc_params->mv_num_cf) * ps_mc_params->frm_wd_cf;
1314 
1315     // clip pix_x and pix_y so as it falls inside the frame boundary
1316     CLIP(i2_pix_x, (u2_frm_wd-16), 0);
1317     CLIP(i2_pix_y, (u2_frm_ht-16), 0);
1318 
1319     ps_luma->u4_src_offset = i2_pix_x +  i2_pix_y * u2_frm_wd;
1320 
1321 
1322     /* keep offset  in full pel */
1323     ps_luma->u4_rows          = ps_mc_params->rows;
1324     ps_luma->u4_cols          = MB_SIZE;
1325     ps_luma->u4_dst_wd_res_buf        = ps_mc_params->dst_wd;
1326     ps_luma->u4_src_wd        = u2_frm_wd * ps_mc_params->src_wd_cf;
1327     ps_luma->u4_dst_offset_res_buf    = ps_mc_params->dst_offset_scale * MB_SIZE;
1328     ps_luma->u4_dst_offset_cur_frm    = ps_mc_params->dst_offset_scale * u2_picture_width;
1329     ps_luma->u4_mode          = ((ai2_mv[MV_X] & 1) << 1) | (ai2_mv[MV_Y] & 1);
1330 
1331     /****************************************************************************/
1332     /* get chroma mc params                                                     */
1333     /****************************************************************************/
1334     ps_mc_params   = &gas_impeg2d_mc_params_chroma[e_type][u2_mv_num];
1335     i2_mvx_round   = ((ai2_mv[MV_X] + IS_NEG(ai2_mv[MV_X]))>>1);
1336     i2_mvy_round   = ((ai2_mv[MV_Y] + IS_NEG(ai2_mv[MV_Y]))>>1);
1337 
1338     i2_mvx_fullp_round = (i2_mvx_round>>1);
1339     i2_mvy_fullp_round = (i2_mvy_round>>1)*ps_mc_params->mvy_cf;
1340 
1341     u4_frm_chroma_wd = (u2_frm_wd>>1);
1342 
1343     i2_pix_x = (MB_SIZE/2) * u2_mb_x + i2_mvx_fullp_round;
1344     i2_pix_y = ((MB_SIZE/2) * u2_mb_y + i2_mvy_fullp_round + u2_mv_num *
1345                            ps_mc_params->mv_num_cf)*ps_mc_params->frm_wd_cf;
1346 
1347     CLIP(i2_pix_x, ((u2_frm_wd / 2)-8), 0);
1348     CLIP(i2_pix_y, ((u2_frm_ht / 2)-8), 0);
1349     ps_chroma->u4_src_offset = i2_pix_x + i2_pix_y * u4_frm_chroma_wd;
1350 
1351 
1352     /* keep offset  in full pel */
1353     ps_chroma->u4_rows = ps_mc_params->rows;
1354     ps_chroma->u4_cols        = (MB_SIZE >> 1);
1355     ps_chroma->u4_dst_wd_res_buf = ps_mc_params->dst_wd;
1356     ps_chroma->u4_src_wd = (u2_frm_wd>>1) * ps_mc_params->src_wd_cf;
1357     ps_chroma->u4_dst_offset_res_buf = ps_mc_params->dst_offset_scale * MB_CHROMA_SIZE;
1358     ps_chroma->u4_dst_offset_cur_frm = ps_mc_params->dst_offset_scale * (u2_picture_width >> 1);
1359     ps_chroma->u4_mode = ((i2_mvx_round & 1) << 1) | (i2_mvy_round & 1);
1360 
1361 
1362 
1363     ps_luma->u4_dst_wd_cur_frm = u2_picture_width;
1364     ps_chroma->u4_dst_wd_cur_frm = u2_picture_width >> 1;
1365 
1366     if(ps_luma->u4_dst_wd_res_buf == MB_SIZE * 2)
1367     {
1368         ps_luma->u4_dst_wd_cur_frm = u2_frm_wd << 1;
1369         ps_chroma->u4_dst_wd_cur_frm = u2_frm_wd;
1370     }
1371 }
1372 
1373 
1374