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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 *****************************************************************************/ 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 *****************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 *******************************************************************************/ 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