/******************************************************************************
*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
/**
*******************************************************************************
* @file
* impeg2d_mcu.c
*
* @brief
* Contains MC function definitions for MPEG2 decoder
*
* @author
* Harish
*
* @par List of Functions:
* - impeg2_copy_mb()
* - impeg2_interpolate()
* - impeg2_mc_halfx_halfy_8x8()
* - impeg2_mc_halfx_fully_8x8()
* - impeg2_mc_fullx_halfy_8x8()
* - impeg2_mc_fullx_fully_8x8()
*
* @remarks
* None
*
*******************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include "iv_datatypedef.h"
#include "iv.h"
#include "impeg2_buf_mgr.h"
#include "impeg2_disp_mgr.h"
#include "impeg2_defs.h"
#include "impeg2_platform_macros.h"
#include "impeg2_inter_pred.h"
#include "impeg2_globals.h"
#include "impeg2_macros.h"
#include "impeg2_idct.h"
/*******************************************************************************
* Function Name : impeg2_copy_mb
*
* Description : copies 3 components to the frame from mc_buf
*
* Arguments :
* src_buf : Source Buffer
* dst_buf : Destination Buffer
* src_offset_x : X offset for source
* src_offset_y : Y offset for source
* dst_offset_x : X offset for destination
* dst_offset_y : Y offset for destination
* src_wd : Source Width
* dst_wd : destination Width
* rows : Number of rows
* cols : Number of columns
*
* Values Returned : None
*******************************************************************************/
void impeg2_copy_mb(yuv_buf_t *ps_src_buf,
yuv_buf_t *ps_dst_buf,
UWORD32 u4_src_wd,
UWORD32 u4_dst_wd)
{
UWORD8 *pu1_src;
UWORD8 *pu1_dst;
UWORD32 i;
UWORD32 u4_rows = MB_SIZE;
UWORD32 u4_cols = MB_SIZE;
/*******************************************************/
/* copy Y */
/*******************************************************/
pu1_src = ps_src_buf->pu1_y;
pu1_dst = ps_dst_buf->pu1_y;
for(i = 0; i < u4_rows; i++)
{
memcpy(pu1_dst, pu1_src, u4_cols);
pu1_src += u4_src_wd;
pu1_dst += u4_dst_wd;
}
u4_src_wd >>= 1;
u4_dst_wd >>= 1;
u4_rows >>= 1;
u4_cols >>= 1;
/*******************************************************/
/* copy U */
/*******************************************************/
pu1_src = ps_src_buf->pu1_u;
pu1_dst = ps_dst_buf->pu1_u;
for(i = 0; i < u4_rows; i++)
{
memcpy(pu1_dst, pu1_src, u4_cols);
pu1_src += u4_src_wd;
pu1_dst += u4_dst_wd;
}
/*******************************************************/
/* copy V */
/*******************************************************/
pu1_src = ps_src_buf->pu1_v;
pu1_dst = ps_dst_buf->pu1_v;
for(i = 0; i < u4_rows; i++)
{
memcpy(pu1_dst, pu1_src, u4_cols);
pu1_src += u4_src_wd;
pu1_dst += u4_dst_wd;
}
}
/*****************************************************************************/
/* */
/* Function Name : impeg2_interpolate */
/* */
/* Description : averages the contents of buf_src1 and buf_src2 and stores*/
/* result in buf_dst */
/* */
/* Inputs : buf_src1 - First Source */
/* buf_src2 - Second Source */
/* */
/* Globals : None */
/* */
/* Processing : Avg the values from two sources and store the result in */
/* destination buffer */
/* */
/* Outputs : buf_dst - Avg of contents of buf_src1 and buf_src2 */
/* */
/* Returns : None */
/* */
/* Issues : Assumes that all 3 buffers are of same size */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 14 09 2005 Harish M First Version */
/* 15 09 2010 Venkat Added stride */
/* */
/*****************************************************************************/
void impeg2_interpolate(yuv_buf_t *ps_buf_src1,
yuv_buf_t *ps_buf_src2,
yuv_buf_t *ps_buf_dst,
UWORD32 u4_stride)
{
UWORD32 i,j;
UWORD8 *pu1_src1,*pu1_src2,*pu1_dst;
pu1_src1 = ps_buf_src1->pu1_y;
pu1_src2 = ps_buf_src2->pu1_y;
pu1_dst = ps_buf_dst->pu1_y;
for(i = MB_SIZE; i > 0; i--)
{
for(j = MB_SIZE; j > 0; j--)
{
*pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
}
pu1_dst += u4_stride - MB_SIZE;
}
u4_stride >>= 1;
pu1_src1 = ps_buf_src1->pu1_u;
pu1_src2 = ps_buf_src2->pu1_u;
pu1_dst = ps_buf_dst->pu1_u;
for(i = MB_CHROMA_SIZE; i > 0 ; i--)
{
for(j = MB_CHROMA_SIZE; j > 0; j--)
{
*pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
}
pu1_dst += u4_stride - MB_CHROMA_SIZE;
}
pu1_src1 = ps_buf_src1->pu1_v;
pu1_src2 = ps_buf_src2->pu1_v;
pu1_dst = ps_buf_dst->pu1_v;
for(i = MB_CHROMA_SIZE; i > 0 ; i--)
{
for(j = MB_CHROMA_SIZE; j > 0; j--)
{
*pu1_dst++ = ((*pu1_src1++) + (*pu1_src2++) + 1) >> 1;
}
pu1_dst += u4_stride - MB_CHROMA_SIZE;
}
}
/*****************************************************************************/
/* */
/* Function Name : impeg2_mc_halfx_halfy_8x8() */
/* */
/* Description : Gets the buffer from (0.5,0.5) to (8.5,8.5) */
/* and the above block of size 8 x 8 will be placed as a */
/* block from the current position of out_buf */
/* */
/* Inputs : ref - Reference frame from which the block will be */
/* block will be extracted. */
/* ref_wid - WIdth of reference frame */
/* out_wid - WIdth of the output frame */
/* blk_width - width of the block */
/* blk_width - height of the block */
/* */
/* Globals : None */
/* */
/* Processing : Point to the (0,0),(1,0),(0,1),(1,1) position in */
/* the ref frame.Interpolate these four values to get the */
/* value at(0.5,0.5).Repeat this to get an 8 x 8 block */
/* using 9 x 9 block from reference frame */
/* */
/* Outputs : out - Output containing the extracted block */
/* */
/* Returns : None */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 05 09 2005 Harish M First Version */
/* */
/*****************************************************************************/
void impeg2_mc_halfx_halfy_8x8(UWORD8 *pu1_out,
UWORD8 *pu1_ref,
UWORD32 u4_ref_wid,
UWORD32 u4_out_wid)
{
UWORD8 *pu1_ref_p0,*pu1_ref_p1,*pu1_ref_p2,*pu1_ref_p3;
UWORD32 i,j;
/* P0-P3 are the pixels in the reference frame and Q is the value being */
/* estimated */
/*
P0 P1
Q
P2 P3
*/
pu1_ref_p0 = pu1_ref;
pu1_ref_p1 = pu1_ref + 1;
pu1_ref_p2 = pu1_ref + u4_ref_wid;
pu1_ref_p3 = pu1_ref + u4_ref_wid + 1;
for(i = 0; i < BLK_SIZE; i++)
{
for(j = 0; j < BLK_SIZE; j++)
{
*pu1_out++ = (( (*pu1_ref_p0++ )
+ (*pu1_ref_p1++ )
+ (*pu1_ref_p2++ )
+ (*pu1_ref_p3++ ) + 2 ) >> 2);
}
pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
pu1_ref_p2 += u4_ref_wid - BLK_SIZE;
pu1_ref_p3 += u4_ref_wid - BLK_SIZE;
pu1_out += u4_out_wid - BLK_SIZE;
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : impeg2_mc_halfx_fully_8x8() */
/* */
/* Description : Gets the buffer from (0.5,0) to (8.5,8) */
/* and the above block of size 8 x 8 will be placed as a */
/* block from the current position of out_buf */
/* */
/* Inputs : ref - Reference frame from which the block will be */
/* block will be extracted. */
/* ref_wid - WIdth of reference frame */
/* out_wid - WIdth of the output frame */
/* blk_width - width of the block */
/* blk_width - height of the block */
/* */
/* Globals : None */
/* */
/* Processing : Point to the (0,0) and (1,0) position in the ref frame */
/* Interpolate these two values to get the value at(0.5,0) */
/* Repeat this to get an 8 x 8 block using 9 x 8 block from */
/* reference frame */
/* */
/* Outputs : out - Output containing the extracted block */
/* */
/* Returns : None */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 05 09 2005 Harish M First Version */
/* */
/*****************************************************************************/
void impeg2_mc_halfx_fully_8x8(UWORD8 *pu1_out,
UWORD8 *pu1_ref,
UWORD32 u4_ref_wid,
UWORD32 u4_out_wid)
{
UWORD8 *pu1_ref_p0, *pu1_ref_p1;
UWORD32 i,j;
/* P0-P3 are the pixels in the reference frame and Q is the value being */
/* estimated */
/*
P0 Q P1
*/
pu1_ref_p0 = pu1_ref;
pu1_ref_p1 = pu1_ref + 1;
for(i = 0; i < BLK_SIZE; i++)
{
for(j = 0; j < BLK_SIZE; j++)
{
*pu1_out++ = ((( *pu1_ref_p0++ )
+ (*pu1_ref_p1++) + 1 ) >> 1);
}
pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
pu1_out += u4_out_wid - BLK_SIZE;
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : impeg2_mc_fullx_halfy_8x8() */
/* */
/* Description : Gets the buffer from (0,0.5) to (8,8.5) */
/* and the above block of size 8 x 8 will be placed as a */
/* block from the current position of out_buf */
/* */
/* Inputs : ref - Reference frame from which the block will be */
/* block will be extracted. */
/* ref_wid - WIdth of reference frame */
/* out_wid - WIdth of the output frame */
/* blk_width - width of the block */
/* blk_width - height of the block */
/* */
/* Globals : None */
/* */
/* Processing : Point to the (0,0) and (0,1) position in the ref frame */
/* Interpolate these two values to get the value at(0,0.5) */
/* Repeat this to get an 8 x 8 block using 8 x 9 block from */
/* reference frame */
/* */
/* Outputs : out - Output containing the extracted block */
/* */
/* Returns : None */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 05 09 2005 Harish M First Version */
/* */
/*****************************************************************************/
void impeg2_mc_fullx_halfy_8x8(UWORD8 *pu1_out,
UWORD8 *pu1_ref,
UWORD32 u4_ref_wid,
UWORD32 u4_out_wid)
{
UWORD8 *pu1_ref_p0, *pu1_ref_p1;
UWORD32 i,j;
/* P0-P3 are the pixels in the reference frame and Q is the value being */
/* estimated */
/*
P0
x
P1
*/
pu1_ref_p0 = pu1_ref;
pu1_ref_p1 = pu1_ref + u4_ref_wid;
for(i = 0; i < BLK_SIZE; i++)
{
for(j = 0; j < BLK_SIZE; j++)
{
*pu1_out++ = ((( *pu1_ref_p0++)
+ (*pu1_ref_p1++) + 1 ) >> 1);
}
pu1_ref_p0 += u4_ref_wid - BLK_SIZE;
pu1_ref_p1 += u4_ref_wid - BLK_SIZE;
pu1_out += u4_out_wid - BLK_SIZE;
}
return;
}
/*****************************************************************************/
/* */
/* Function Name : impeg2_mc_fullx_fully_8x8() */
/* */
/* Description : Gets the buffer from (x,y) to (x+8,y+8) */
/* and the above block of size 8 x 8 will be placed as a */
/* block from the current position of out_buf */
/* */
/* Inputs : ref - Reference frame from which the block will be */
/* block will be extracted. */
/* ref_wid - WIdth of reference frame */
/* out_wid - WIdth of the output frame */
/* blk_width - width of the block */
/* blk_width - height of the block */
/* */
/* Globals : None */
/* */
/* Processing : Point to the (0,0) position in the ref frame */
/* Get an 8 x 8 block from reference frame */
/* */
/* Outputs : out - Output containing the extracted block */
/* */
/* Returns : None */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 05 09 2005 Harish M First Version */
/* */
/*****************************************************************************/
void impeg2_mc_fullx_fully_8x8(UWORD8 *pu1_out,
UWORD8 *pu1_ref,
UWORD32 u4_ref_wid,
UWORD32 u4_out_wid)
{
UWORD32 i;
for(i = 0; i < BLK_SIZE; i++)
{
memcpy(pu1_out, pu1_ref, BLK_SIZE);
pu1_ref += u4_ref_wid;
pu1_out += u4_out_wid;
}
return;
}