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/*****************************************************************************/
108void 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/*****************************************************************************/
165void 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/*****************************************************************************/
226void 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/*****************************************************************************/
260void 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/*****************************************************************************/
294void 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/*****************************************************************************/
338void 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/*****************************************************************************/
380void 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/*****************************************************************************/
419void 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*****************************************************************************/
440void 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*****************************************************************************/
483void 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*******************************************************************************/
614void 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*******************************************************************************/
725void 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*****************************************************************************/
757void 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/*****************************************************************************/
825void 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
955void 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/*****************************************************************************/
1078void 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
1199void 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            memmove(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*******************************************************************************/
1288void 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