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*******************************************************************************/ 78void impeg2_copy_mb(yuv_buf_t *ps_src_buf, 79 yuv_buf_t *ps_dst_buf, 80 UWORD32 u4_src_wd, 81 UWORD32 u4_dst_wd) 82{ 83 UWORD8 *pu1_src; 84 UWORD8 *pu1_dst; 85 UWORD32 i; 86 UWORD32 u4_rows = MB_SIZE; 87 UWORD32 u4_cols = MB_SIZE; 88 89 /*******************************************************/ 90 /* copy Y */ 91 /*******************************************************/ 92 pu1_src = ps_src_buf->pu1_y; 93 pu1_dst = ps_dst_buf->pu1_y; 94 for(i = 0; i < u4_rows; i++) 95 { 96 memcpy(pu1_dst, pu1_src, u4_cols); 97 pu1_src += u4_src_wd; 98 pu1_dst += u4_dst_wd; 99 } 100 101 u4_src_wd >>= 1; 102 u4_dst_wd >>= 1; 103 u4_rows >>= 1; 104 u4_cols >>= 1; 105 106 /*******************************************************/ 107 /* copy U */ 108 /*******************************************************/ 109 pu1_src = ps_src_buf->pu1_u; 110 pu1_dst = ps_dst_buf->pu1_u; 111 for(i = 0; i < u4_rows; i++) 112 { 113 memcpy(pu1_dst, pu1_src, u4_cols); 114 115 pu1_src += u4_src_wd; 116 pu1_dst += u4_dst_wd; 117 } 118 /*******************************************************/ 119 /* copy V */ 120 /*******************************************************/ 121 pu1_src = ps_src_buf->pu1_v; 122 pu1_dst = ps_dst_buf->pu1_v; 123 for(i = 0; i < u4_rows; i++) 124 { 125 memcpy(pu1_dst, pu1_src, u4_cols); 126 127 pu1_src += u4_src_wd; 128 pu1_dst += u4_dst_wd; 129 } 130 131} 132 133/*****************************************************************************/ 134/* */ 135/* Function Name : impeg2_interpolate */ 136/* */ 137/* Description : averages the contents of buf_src1 and buf_src2 and stores*/ 138/* result in buf_dst */ 139/* */ 140/* Inputs : buf_src1 - First Source */ 141/* buf_src2 - Second Source */ 142/* */ 143/* Globals : None */ 144/* */ 145/* Processing : Avg the values from two sources and store the result in */ 146/* destination buffer */ 147/* */ 148/* Outputs : buf_dst - Avg of contents of buf_src1 and buf_src2 */ 149/* */ 150/* Returns : None */ 151/* */ 152/* Issues : Assumes that all 3 buffers are of same size */ 153/* */ 154/* Revision History: */ 155/* */ 156/* DD MM YYYY Author(s) Changes */ 157/* 14 09 2005 Harish M First Version */ 158/* 15 09 2010 Venkat Added stride */ 159/* */ 160/*****************************************************************************/ 161void impeg2_interpolate(yuv_buf_t *ps_buf_src1, 162 yuv_buf_t *ps_buf_src2, 163 yuv_buf_t *ps_buf_dst, 164 UWORD32 u4_stride) 165{ 166 167 UWORD32 i,j; 168 UWORD8 *pu1_src1,*pu1_src2,*pu1_dst; 169 pu1_src1 = ps_buf_src1->pu1_y; 170 pu1_src2 = ps_buf_src2->pu1_y; 171 pu1_dst = ps_buf_dst->pu1_y; 172 for(i = MB_SIZE; i > 0; i--) 173 { 174 for(j = MB_SIZE; j > 0; j--) 175 { 176 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1; 177 } 178 179 pu1_dst += u4_stride - MB_SIZE; 180 181 } 182 183 u4_stride >>= 1; 184 185 pu1_src1 = ps_buf_src1->pu1_u; 186 pu1_src2 = ps_buf_src2->pu1_u; 187 pu1_dst = ps_buf_dst->pu1_u; 188 for(i = MB_CHROMA_SIZE; i > 0 ; i--) 189 { 190 for(j = MB_CHROMA_SIZE; j > 0; j--) 191 { 192 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1; 193 } 194 195 pu1_dst += u4_stride - MB_CHROMA_SIZE; 196 } 197 198 pu1_src1 = ps_buf_src1->pu1_v; 199 pu1_src2 = ps_buf_src2->pu1_v; 200 pu1_dst = ps_buf_dst->pu1_v; 201 for(i = MB_CHROMA_SIZE; i > 0 ; i--) 202 { 203 for(j = MB_CHROMA_SIZE; j > 0; j--) 204 { 205 *pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1; 206 } 207 208 pu1_dst += u4_stride - MB_CHROMA_SIZE; 209 } 210 211} 212 213/*****************************************************************************/ 214/* */ 215/* Function Name : impeg2_mc_halfx_halfy_8x8() */ 216/* */ 217/* Description : Gets the buffer from (0.5,0.5) to (8.5,8.5) */ 218/* and the above block of size 8 x 8 will be placed as a */ 219/* block from the current position of out_buf */ 220/* */ 221/* Inputs : ref - Reference frame from which the block will be */ 222/* block will be extracted. */ 223/* ref_wid - WIdth of reference frame */ 224/* out_wid - WIdth of the output frame */ 225/* blk_width - width of the block */ 226/* blk_width - height of the block */ 227/* */ 228/* Globals : None */ 229/* */ 230/* Processing : Point to the (0,0),(1,0),(0,1),(1,1) position in */ 231/* the ref frame.Interpolate these four values to get the */ 232/* value at(0.5,0.5).Repeat this to get an 8 x 8 block */ 233/* using 9 x 9 block from reference frame */ 234/* */ 235/* Outputs : out - Output containing the extracted block */ 236/* */ 237/* Returns : None */ 238/* */ 239/* Issues : None */ 240/* */ 241/* Revision History: */ 242/* */ 243/* DD MM YYYY Author(s) Changes */ 244/* 05 09 2005 Harish M First Version */ 245/* */ 246/*****************************************************************************/ 247void impeg2_mc_halfx_halfy_8x8(UWORD8 *pu1_out, 248 UWORD8 *pu1_ref, 249 UWORD32 u4_ref_wid, 250 UWORD32 u4_out_wid) 251{ 252 UWORD8 *pu1_ref_p0,*pu1_ref_p1,*pu1_ref_p2,*pu1_ref_p3; 253 UWORD32 i,j; 254 /* P0-P3 are the pixels in the reference frame and Q is the value being */ 255 /* estimated */ 256 /* 257 P0 P1 258 Q 259 P2 P3 260 */ 261 262 pu1_ref_p0 = pu1_ref; 263 pu1_ref_p1 = pu1_ref + 1; 264 pu1_ref_p2 = pu1_ref + u4_ref_wid; 265 pu1_ref_p3 = pu1_ref + u4_ref_wid + 1; 266 267 for(i = 0; i < BLK_SIZE; i++) 268 { 269 for(j = 0; j < BLK_SIZE; j++) 270 { 271 *pu1_out++ = (( (*pu1_ref_p0++ ) 272 + (*pu1_ref_p1++ ) 273 + (*pu1_ref_p2++ ) 274 + (*pu1_ref_p3++ ) + 2 ) >> 2); 275 } 276 pu1_ref_p0 += u4_ref_wid - BLK_SIZE; 277 pu1_ref_p1 += u4_ref_wid - BLK_SIZE; 278 pu1_ref_p2 += u4_ref_wid - BLK_SIZE; 279 pu1_ref_p3 += u4_ref_wid - BLK_SIZE; 280 281 pu1_out += u4_out_wid - BLK_SIZE; 282 } 283 return; 284} 285 286/*****************************************************************************/ 287/* */ 288/* Function Name : impeg2_mc_halfx_fully_8x8() */ 289/* */ 290/* Description : Gets the buffer from (0.5,0) to (8.5,8) */ 291/* and the above block of size 8 x 8 will be placed as a */ 292/* block from the current position of out_buf */ 293/* */ 294/* Inputs : ref - Reference frame from which the block will be */ 295/* block will be extracted. */ 296/* ref_wid - WIdth of reference frame */ 297/* out_wid - WIdth of the output frame */ 298/* blk_width - width of the block */ 299/* blk_width - height of the block */ 300/* */ 301/* Globals : None */ 302/* */ 303/* Processing : Point to the (0,0) and (1,0) position in the ref frame */ 304/* Interpolate these two values to get the value at(0.5,0) */ 305/* Repeat this to get an 8 x 8 block using 9 x 8 block from */ 306/* reference frame */ 307/* */ 308/* Outputs : out - Output containing the extracted block */ 309/* */ 310/* Returns : None */ 311/* */ 312/* Issues : None */ 313/* */ 314/* Revision History: */ 315/* */ 316/* DD MM YYYY Author(s) Changes */ 317/* 05 09 2005 Harish M First Version */ 318/* */ 319/*****************************************************************************/ 320void impeg2_mc_halfx_fully_8x8(UWORD8 *pu1_out, 321 UWORD8 *pu1_ref, 322 UWORD32 u4_ref_wid, 323 UWORD32 u4_out_wid) 324{ 325 UWORD8 *pu1_ref_p0, *pu1_ref_p1; 326 UWORD32 i,j; 327 328 /* P0-P3 are the pixels in the reference frame and Q is the value being */ 329 /* estimated */ 330 /* 331 P0 Q P1 332 */ 333 334 pu1_ref_p0 = pu1_ref; 335 pu1_ref_p1 = pu1_ref + 1; 336 337 for(i = 0; i < BLK_SIZE; i++) 338 { 339 for(j = 0; j < BLK_SIZE; j++) 340 { 341 *pu1_out++ = ((( *pu1_ref_p0++ ) 342 + (*pu1_ref_p1++) + 1 ) >> 1); 343 } 344 pu1_ref_p0 += u4_ref_wid - BLK_SIZE; 345 pu1_ref_p1 += u4_ref_wid - BLK_SIZE; 346 347 pu1_out += u4_out_wid - BLK_SIZE; 348 } 349 return; 350} 351 352/*****************************************************************************/ 353/* */ 354/* Function Name : impeg2_mc_fullx_halfy_8x8() */ 355/* */ 356/* Description : Gets the buffer from (0,0.5) to (8,8.5) */ 357/* and the above block of size 8 x 8 will be placed as a */ 358/* block from the current position of out_buf */ 359/* */ 360/* Inputs : ref - Reference frame from which the block will be */ 361/* block will be extracted. */ 362/* ref_wid - WIdth of reference frame */ 363/* out_wid - WIdth of the output frame */ 364/* blk_width - width of the block */ 365/* blk_width - height of the block */ 366/* */ 367/* Globals : None */ 368/* */ 369/* Processing : Point to the (0,0) and (0,1) position in the ref frame */ 370/* Interpolate these two values to get the value at(0,0.5) */ 371/* Repeat this to get an 8 x 8 block using 8 x 9 block from */ 372/* reference frame */ 373/* */ 374/* Outputs : out - Output containing the extracted block */ 375/* */ 376/* Returns : None */ 377/* */ 378/* Issues : None */ 379/* */ 380/* Revision History: */ 381/* */ 382/* DD MM YYYY Author(s) Changes */ 383/* 05 09 2005 Harish M First Version */ 384/* */ 385/*****************************************************************************/ 386void impeg2_mc_fullx_halfy_8x8(UWORD8 *pu1_out, 387 UWORD8 *pu1_ref, 388 UWORD32 u4_ref_wid, 389 UWORD32 u4_out_wid) 390{ 391 392 UWORD8 *pu1_ref_p0, *pu1_ref_p1; 393 UWORD32 i,j; 394 /* P0-P3 are the pixels in the reference frame and Q is the value being */ 395 /* estimated */ 396 /* 397 P0 398 x 399 P1 400 */ 401 pu1_ref_p0 = pu1_ref; 402 pu1_ref_p1 = pu1_ref + u4_ref_wid; 403 404 for(i = 0; i < BLK_SIZE; i++) 405 { 406 for(j = 0; j < BLK_SIZE; j++) 407 { 408 *pu1_out++ = ((( *pu1_ref_p0++) 409 + (*pu1_ref_p1++) + 1 ) >> 1); 410 } 411 pu1_ref_p0 += u4_ref_wid - BLK_SIZE; 412 pu1_ref_p1 += u4_ref_wid - BLK_SIZE; 413 414 pu1_out += u4_out_wid - BLK_SIZE; 415 } 416 417 return; 418} 419 420/*****************************************************************************/ 421/* */ 422/* Function Name : impeg2_mc_fullx_fully_8x8() */ 423/* */ 424/* Description : Gets the buffer from (x,y) to (x+8,y+8) */ 425/* and the above block of size 8 x 8 will be placed as a */ 426/* block from the current position of out_buf */ 427/* */ 428/* Inputs : ref - Reference frame from which the block will be */ 429/* block will be extracted. */ 430/* ref_wid - WIdth of reference frame */ 431/* out_wid - WIdth of the output frame */ 432/* blk_width - width of the block */ 433/* blk_width - height of the block */ 434/* */ 435/* Globals : None */ 436/* */ 437/* Processing : Point to the (0,0) position in the ref frame */ 438/* Get an 8 x 8 block from reference frame */ 439/* */ 440/* Outputs : out - Output containing the extracted block */ 441/* */ 442/* Returns : None */ 443/* */ 444/* Issues : None */ 445/* */ 446/* Revision History: */ 447/* */ 448/* DD MM YYYY Author(s) Changes */ 449/* 05 09 2005 Harish M First Version */ 450/* */ 451/*****************************************************************************/ 452void impeg2_mc_fullx_fully_8x8(UWORD8 *pu1_out, 453 UWORD8 *pu1_ref, 454 UWORD32 u4_ref_wid, 455 UWORD32 u4_out_wid) 456{ 457 458 UWORD32 i; 459 460 for(i = 0; i < BLK_SIZE; i++) 461 { 462 memcpy(pu1_out, pu1_ref, BLK_SIZE); 463 pu1_ref += u4_ref_wid; 464 pu1_out += u4_out_wid; 465 } 466 return; 467} 468