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