You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
467 lines
21 KiB
467 lines
21 KiB
/****************************************************************************** |
|
* |
|
* 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; |
|
}
|
|
|