This commit does not introduce any new functionality w.r.t previous commit. But it fixes few things. They are listed below: 1. Guard Bands in header files are fixed 2. Header files contains function definition comments. These are same as in source file. Maintaining same comment at two locations is unnecessary. These are removed. 3. Improved consistency and code indentation 4. Removed comments that dont align with implementation 5. Grouped headers of a workspace together
1033 lines
28 KiB
C
1033 lines
28 KiB
C
/******************************************************************************
|
|
*
|
|
* 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
|
|
* ih264e_fmt_conv.c
|
|
*
|
|
* @brief
|
|
* Contains functions for format conversion or frame copy of output buffer
|
|
*
|
|
* @author
|
|
* ittiam
|
|
*
|
|
* @par List of Functions:
|
|
* - ih264e_fmt_conv_420sp_to_rgb565
|
|
* - ih264e_fmt_conv_420sp_to_rgba8888
|
|
* - ih264e_fmt_conv_420sp_to_420sp
|
|
* - ih264e_fmt_conv_420sp_to_420sp_swap_uv
|
|
* - ih264e_fmt_conv_420sp_to_420p
|
|
* - ih264e_fmt_conv_420p_to_420sp
|
|
* - ih264e_fmt_conv_422i_to_420sp
|
|
* - ih264e_fmt_conv
|
|
*
|
|
* @remarks
|
|
* none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
|
|
/* System Include Files */
|
|
#include <stdio.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
/* User Include Files */
|
|
#include "ih264_typedefs.h"
|
|
#include "iv2.h"
|
|
#include "ive2.h"
|
|
#include "ithread.h"
|
|
|
|
#include "ih264_debug.h"
|
|
#include "ih264_macros.h"
|
|
#include "ih264_error.h"
|
|
#include "ih264_defs.h"
|
|
#include "ih264_mem_fns.h"
|
|
#include "ih264_padding.h"
|
|
#include "ih264_structs.h"
|
|
#include "ih264_trans_quant_itrans_iquant.h"
|
|
#include "ih264_inter_pred_filters.h"
|
|
#include "ih264_intra_pred_filters.h"
|
|
#include "ih264_deblk_edge_filters.h"
|
|
#include "ih264_cabac_tables.h"
|
|
#include "ih264_platform_macros.h"
|
|
|
|
#include "ime_defs.h"
|
|
#include "ime_distortion_metrics.h"
|
|
#include "ime_structs.h"
|
|
|
|
#include "irc_cntrl_param.h"
|
|
#include "irc_frame_info_collector.h"
|
|
|
|
#include "ih264e.h"
|
|
#include "ih264e_error.h"
|
|
#include "ih264e_defs.h"
|
|
#include "ih264e_rate_control.h"
|
|
#include "ih264e_bitstream.h"
|
|
#include "ih264e_cabac_structs.h"
|
|
#include "ih264e_structs.h"
|
|
#include "ih264e_fmt_conv.h"
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used to perform color space conversion from 420SP to RGB565
|
|
*
|
|
* @par Description
|
|
* Function used to perform color space conversion from 420SP to RGB565
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_uv_src
|
|
* Input UV pointer
|
|
*
|
|
* @param[in] pu2_rgb_dst
|
|
* Output RGB pointer
|
|
*
|
|
* @param[in] wd
|
|
* Width
|
|
*
|
|
* @param[in] ht
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_uv_strd
|
|
* Input UV stride
|
|
*
|
|
* @param[in] dst_strd
|
|
* Output stride
|
|
*
|
|
* @param[in] is_u_first
|
|
* Flag to indicate chroma ordering
|
|
*
|
|
* @returns none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_uv_src,
|
|
UWORD16 *pu2_rgb_dst,
|
|
WORD32 wd,
|
|
WORD32 ht,
|
|
WORD32 src_y_strd,
|
|
WORD32 src_uv_strd,
|
|
WORD32 dst_strd,
|
|
WORD32 is_u_first)
|
|
{
|
|
WORD16 i2_r, i2_g, i2_b;
|
|
UWORD32 u4_r, u4_g, u4_b;
|
|
WORD16 i2_i, i2_j;
|
|
UWORD8 *pu1_y_src_nxt;
|
|
UWORD16 *pu2_rgb_dst_NextRow;
|
|
|
|
UWORD8 *pu1_u_src, *pu1_v_src;
|
|
|
|
if (is_u_first)
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
|
|
}
|
|
else
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src;
|
|
}
|
|
|
|
pu1_y_src_nxt = pu1_y_src + src_y_strd;
|
|
pu2_rgb_dst_NextRow = pu2_rgb_dst + dst_strd;
|
|
|
|
for (i2_i = 0; i2_i < (ht >> 1); i2_i++)
|
|
{
|
|
for (i2_j = (wd >> 1); i2_j > 0; i2_j--)
|
|
{
|
|
i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
|
|
i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
|
|
>> 13;
|
|
i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
|
|
|
|
pu1_u_src += 2;
|
|
pu1_v_src += 2;
|
|
/* pixel 0 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src + i2_b);
|
|
u4_b >>= 3;
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src + i2_g);
|
|
u4_g >>= 2;
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src + i2_r);
|
|
u4_r >>= 3;
|
|
|
|
pu1_y_src++;
|
|
*pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
|
|
|
|
/* pixel 1 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src + i2_b);
|
|
u4_b >>= 3;
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src + i2_g);
|
|
u4_g >>= 2;
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src + i2_r);
|
|
u4_r >>= 3;
|
|
|
|
pu1_y_src++;
|
|
*pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
|
|
|
|
/* pixel 2 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
|
|
u4_b >>= 3;
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
|
|
u4_g >>= 2;
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
|
|
u4_r >>= 3;
|
|
|
|
pu1_y_src_nxt++;
|
|
*pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
|
|
|
|
/* pixel 3 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
|
|
u4_b >>= 3;
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
|
|
u4_g >>= 2;
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
|
|
u4_r >>= 3;
|
|
|
|
pu1_y_src_nxt++;
|
|
*pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b);
|
|
|
|
}
|
|
|
|
pu1_u_src = pu1_u_src + src_uv_strd - wd;
|
|
pu1_v_src = pu1_v_src + src_uv_strd - wd;
|
|
|
|
pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
|
|
pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
|
|
|
|
pu2_rgb_dst = pu2_rgb_dst_NextRow - wd + dst_strd;
|
|
pu2_rgb_dst_NextRow = pu2_rgb_dst_NextRow + (dst_strd << 1) - wd;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used to perform color space conversion from 420SP to RGBA888
|
|
*
|
|
* @par Description
|
|
* Function used to perform color space conversion from 420SP to RGBA888
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_uv_src
|
|
* Input UV pointer
|
|
*
|
|
* @param[in] pu4_rgba_dst
|
|
* Output RGB pointer
|
|
*
|
|
* @param[in] wd
|
|
* Width
|
|
*
|
|
* @param[in] ht
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_uv_strd
|
|
* Input UV stride
|
|
*
|
|
* @param[in] dst_strd
|
|
* Output stride
|
|
*
|
|
* @param[in] is_u_first
|
|
* Flag to indicate chroma ordering
|
|
*
|
|
* @returns none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_uv_src,
|
|
UWORD32 *pu4_rgba_dst,
|
|
WORD32 wd,
|
|
WORD32 ht,
|
|
WORD32 src_y_strd,
|
|
WORD32 src_uv_strd,
|
|
WORD32 dst_strd,
|
|
WORD32 is_u_first)
|
|
{
|
|
WORD16 i2_r, i2_g, i2_b;
|
|
UWORD32 u4_r, u4_g, u4_b;
|
|
WORD16 i2_i, i2_j;
|
|
UWORD8 *pu1_y_src_nxt;
|
|
UWORD32 *pu4_rgba_dst_NextRow;
|
|
UWORD8 *pu1_u_src, *pu1_v_src;
|
|
|
|
if (is_u_first)
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
|
|
}
|
|
else
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src;
|
|
}
|
|
|
|
pu1_y_src_nxt = pu1_y_src + src_y_strd;
|
|
|
|
pu4_rgba_dst_NextRow = pu4_rgba_dst + dst_strd;
|
|
|
|
for (i2_i = 0; i2_i < (ht >> 1); i2_i++)
|
|
{
|
|
for (i2_j = (wd >> 1); i2_j > 0; i2_j--)
|
|
{
|
|
i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13);
|
|
i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3)
|
|
>> 13;
|
|
i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13;
|
|
|
|
pu1_u_src += 2;
|
|
pu1_v_src += 2;
|
|
/* pixel 0 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src + i2_b);
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src + i2_g);
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src + i2_r);
|
|
|
|
pu1_y_src++;
|
|
*pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
|
|
|
|
/* pixel 1 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src + i2_b);
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src + i2_g);
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src + i2_r);
|
|
|
|
pu1_y_src++;
|
|
*pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
|
|
|
|
/* pixel 2 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
|
|
|
|
pu1_y_src_nxt++;
|
|
*pu4_rgba_dst_NextRow++ =
|
|
((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
|
|
|
|
/* pixel 3 */
|
|
/* B */
|
|
u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b);
|
|
/* G */
|
|
u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g);
|
|
/* R */
|
|
u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r);
|
|
|
|
pu1_y_src_nxt++;
|
|
*pu4_rgba_dst_NextRow++ =
|
|
((u4_r << 16) | (u4_g << 8) | (u4_b << 0));
|
|
|
|
}
|
|
|
|
pu1_u_src = pu1_u_src + src_uv_strd - wd;
|
|
pu1_v_src = pu1_v_src + src_uv_strd - wd;
|
|
|
|
pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd;
|
|
pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd;
|
|
|
|
pu4_rgba_dst = pu4_rgba_dst_NextRow - wd + dst_strd;
|
|
pu4_rgba_dst_NextRow = pu4_rgba_dst_NextRow + (dst_strd << 1) - wd;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used for copying a 420SP buffer
|
|
*
|
|
* @par Description
|
|
* Function used for copying a 420SP buffer
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_uv_src
|
|
* Input UV pointer (UV is interleaved either in UV or VU format)
|
|
*
|
|
* @param[in] pu1_y_dst
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_uv_dst
|
|
* Output UV pointer (UV is interleaved in the same format as that of input)
|
|
*
|
|
* @param[in] wd
|
|
* Width
|
|
*
|
|
* @param[in] ht
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_uv_strd
|
|
* Input UV stride
|
|
*
|
|
* @param[in] dst_y_strd
|
|
* Output Y stride
|
|
*
|
|
* @param[in] dst_uv_strd
|
|
* Output UV stride
|
|
*
|
|
* @returns None
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_uv_src,
|
|
UWORD8 *pu1_y_dst,
|
|
UWORD8 *pu1_uv_dst,
|
|
WORD32 wd,
|
|
WORD32 ht,
|
|
WORD32 src_y_strd,
|
|
WORD32 src_uv_strd,
|
|
WORD32 dst_y_strd,
|
|
WORD32 dst_uv_strd)
|
|
{
|
|
UWORD8 *pu1_src, *pu1_dst;
|
|
WORD32 num_rows, num_cols, src_strd, dst_strd;
|
|
WORD32 i;
|
|
|
|
/* copy luma */
|
|
pu1_src = (UWORD8 *) pu1_y_src;
|
|
pu1_dst = (UWORD8 *) pu1_y_dst;
|
|
|
|
num_rows = ht;
|
|
num_cols = wd;
|
|
|
|
src_strd = src_y_strd;
|
|
dst_strd = dst_y_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
memcpy(pu1_dst, pu1_src, num_cols);
|
|
pu1_dst += dst_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
|
|
/* copy U and V */
|
|
pu1_src = (UWORD8 *) pu1_uv_src;
|
|
pu1_dst = (UWORD8 *) pu1_uv_dst;
|
|
|
|
num_rows = ht >> 1;
|
|
num_cols = wd;
|
|
|
|
src_strd = src_uv_strd;
|
|
dst_strd = dst_uv_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
memcpy(pu1_dst, pu1_src, num_cols);
|
|
pu1_dst += dst_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used for copying a 420SP buffer and interchange chroma planes
|
|
*
|
|
* @par Description
|
|
* Function used for copying a 420SP buffer and interchange chroma planes
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_uv_src
|
|
* Input UV pointer (UV is interleaved either in UV or VU format)
|
|
*
|
|
* @param[in] pu1_y_dst
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_uv_dst
|
|
* Output UV pointer (UV is interleaved in the opp. format as that of input)
|
|
*
|
|
* @param[in] wd
|
|
* Width
|
|
*
|
|
* @param[in] ht
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_uv_strd
|
|
* Input UV stride
|
|
*
|
|
* @param[in] dst_y_strd
|
|
* Output Y stride
|
|
*
|
|
* @param[in] dst_uv_strd
|
|
* Output UV stride
|
|
*
|
|
* @returns None
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_uv_src,
|
|
UWORD8 *pu1_y_dst,
|
|
UWORD8 *pu1_uv_dst,
|
|
WORD32 wd,
|
|
WORD32 ht,
|
|
WORD32 src_y_strd,
|
|
WORD32 src_uv_strd,
|
|
WORD32 dst_y_strd,
|
|
WORD32 dst_uv_strd)
|
|
{
|
|
UWORD8 *pu1_src, *pu1_dst;
|
|
WORD32 num_rows, num_cols, src_strd, dst_strd;
|
|
WORD32 i;
|
|
|
|
/* copy luma */
|
|
pu1_src = (UWORD8 *) pu1_y_src;
|
|
pu1_dst = (UWORD8 *) pu1_y_dst;
|
|
|
|
num_rows = ht;
|
|
num_cols = wd;
|
|
|
|
src_strd = src_y_strd;
|
|
dst_strd = dst_y_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
memcpy(pu1_dst, pu1_src, num_cols);
|
|
pu1_dst += dst_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
|
|
/* copy U and V */
|
|
pu1_src = (UWORD8 *) pu1_uv_src;
|
|
pu1_dst = (UWORD8 *) pu1_uv_dst;
|
|
|
|
num_rows = ht >> 1;
|
|
num_cols = wd;
|
|
|
|
src_strd = src_uv_strd;
|
|
dst_strd = dst_uv_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
WORD32 j;
|
|
for (j = 0; j < num_cols; j += 2)
|
|
{
|
|
pu1_dst[j + 0] = pu1_src[j + 1];
|
|
pu1_dst[j + 1] = pu1_src[j + 0];
|
|
}
|
|
pu1_dst += dst_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used to perform color space conversion from 420SP to 420P
|
|
*
|
|
* @par Description
|
|
* Function used to perform color space conversion from 420SP to 420P
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_uv_src
|
|
* Input UV pointer (UV is interleaved either in UV or VU format)
|
|
*
|
|
* @param[in] pu1_y_dst
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_u_dst
|
|
* Output U pointer
|
|
*
|
|
* @param[in] pu1_v_dst
|
|
* Output V pointer
|
|
*
|
|
* @param[in] wd
|
|
* Width
|
|
*
|
|
* @param[in] ht
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_uv_strd
|
|
* Input UV stride
|
|
*
|
|
* @param[in] dst_y_strd
|
|
* Output Y stride
|
|
*
|
|
* @param[in] dst_uv_strd
|
|
* Output UV stride
|
|
*
|
|
* @param[in] is_u_first
|
|
* Flag to indicate chroma ordering
|
|
*
|
|
* @param[in] disable_luma_copy
|
|
* Flag to indicate if only UV copy needs to be done
|
|
*
|
|
* @returns none
|
|
*
|
|
* @remarks none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_uv_src,
|
|
UWORD8 *pu1_y_dst,
|
|
UWORD8 *pu1_u_dst,
|
|
UWORD8 *pu1_v_dst,
|
|
WORD32 wd,
|
|
WORD32 ht,
|
|
WORD32 src_y_strd,
|
|
WORD32 src_uv_strd,
|
|
WORD32 dst_y_strd,
|
|
WORD32 dst_uv_strd,
|
|
WORD32 is_u_first,
|
|
WORD32 disable_luma_copy)
|
|
{
|
|
UWORD8 *pu1_src, *pu1_dst;
|
|
UWORD8 *pu1_u_src, *pu1_v_src;
|
|
WORD32 num_rows, num_cols, src_strd, dst_strd;
|
|
WORD32 i, j;
|
|
|
|
if (0 == disable_luma_copy)
|
|
{
|
|
/* copy luma */
|
|
pu1_src = (UWORD8 *) pu1_y_src;
|
|
pu1_dst = (UWORD8 *) pu1_y_dst;
|
|
|
|
num_rows = ht;
|
|
num_cols = wd;
|
|
|
|
src_strd = src_y_strd;
|
|
dst_strd = dst_y_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
memcpy(pu1_dst, pu1_src, num_cols);
|
|
pu1_dst += dst_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
}
|
|
/* de-interleave U and V and copy to destination */
|
|
if (is_u_first)
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src + 1;
|
|
}
|
|
else
|
|
{
|
|
pu1_u_src = (UWORD8 *) pu1_uv_src + 1;
|
|
pu1_v_src = (UWORD8 *) pu1_uv_src;
|
|
}
|
|
|
|
num_rows = ht >> 1;
|
|
num_cols = wd >> 1;
|
|
|
|
src_strd = src_uv_strd;
|
|
dst_strd = dst_uv_strd;
|
|
|
|
for (i = 0; i < num_rows; i++)
|
|
{
|
|
for (j = 0; j < num_cols; j++)
|
|
{
|
|
pu1_u_dst[j] = pu1_u_src[j * 2];
|
|
pu1_v_dst[j] = pu1_v_src[j * 2];
|
|
}
|
|
|
|
pu1_u_dst += dst_strd;
|
|
pu1_v_dst += dst_strd;
|
|
pu1_u_src += src_strd;
|
|
pu1_v_src += src_strd;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used to perform color space conversion from 420P to 420SP
|
|
*
|
|
* @par Description
|
|
* Function used to perform color space conversion from 420P to 420SP
|
|
*
|
|
* @param[in] pu1_y_src
|
|
* Input Y pointer
|
|
*
|
|
* @param[in] pu1_u_src
|
|
* Input U pointer
|
|
*
|
|
* @param[in] pu1_v_dst
|
|
* Input V pointer
|
|
*
|
|
* @param[in] pu1_y_dst
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_uv_dst
|
|
* Output UV pointer
|
|
*
|
|
* @param[in] u4_width
|
|
* Width
|
|
*
|
|
* @param[in] u4_height
|
|
* Height
|
|
*
|
|
* @param[in] src_y_strd
|
|
* Input Y Stride
|
|
*
|
|
* @param[in] src_u_strd
|
|
* Input U stride
|
|
*
|
|
* @param[in] src_v_strd
|
|
* Input V stride
|
|
*
|
|
* @param[in] dst_y_strd
|
|
* Output Y stride
|
|
*
|
|
* @param[in] dst_uv_strd
|
|
* Output UV stride
|
|
*
|
|
* @param[in] convert_uv_only
|
|
* Flag to indicate if only UV copy needs to be done
|
|
*
|
|
* @returns none
|
|
*
|
|
* @remarks none
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src,
|
|
UWORD8 *pu1_u_src,
|
|
UWORD8 *pu1_v_src,
|
|
UWORD8 *pu1_y_dst,
|
|
UWORD8 *pu1_uv_dst,
|
|
UWORD16 u2_height,
|
|
UWORD16 u2_width,
|
|
UWORD16 src_y_strd,
|
|
UWORD16 src_u_strd,
|
|
UWORD16 src_v_strd,
|
|
UWORD16 dst_y_strd,
|
|
UWORD16 dst_uv_strd,
|
|
UWORD32 convert_uv_only)
|
|
{
|
|
UWORD8 *pu1_src, *pu1_dst;
|
|
UWORD8 *pu1_src_u, *pu1_src_v;
|
|
UWORD16 i;
|
|
UWORD32 u2_width_uv;
|
|
UWORD32 dest_inc_Y = 0, dest_inc_UV = 0;
|
|
|
|
dest_inc_UV = dst_uv_strd;
|
|
|
|
if (0 == convert_uv_only)
|
|
{
|
|
/* Copy Y buffer */
|
|
pu1_dst = (UWORD8 *) pu1_y_dst;
|
|
pu1_src = (UWORD8 *) pu1_y_src;
|
|
|
|
dest_inc_Y = dst_y_strd;
|
|
|
|
for (i = 0; i < u2_height; i++)
|
|
{
|
|
memcpy((void *) pu1_dst, (void *) pu1_src, u2_width);
|
|
pu1_dst += dest_inc_Y;
|
|
pu1_src += src_y_strd;
|
|
}
|
|
}
|
|
|
|
/* Interleave Cb and Cr buffers */
|
|
pu1_src_u = pu1_u_src;
|
|
pu1_src_v = pu1_v_src;
|
|
pu1_dst = pu1_uv_dst;
|
|
|
|
u2_height = (u2_height + 1) >> 1;
|
|
u2_width_uv = (u2_width + 1) >> 1;
|
|
for (i = 0; i < u2_height; i++)
|
|
{
|
|
UWORD32 j;
|
|
for (j = 0; j < u2_width_uv; j++)
|
|
{
|
|
*pu1_dst++ = *pu1_src_u++;
|
|
*pu1_dst++ = *pu1_src_v++;
|
|
}
|
|
|
|
pu1_dst += dest_inc_UV - u2_width;
|
|
pu1_src_u += src_u_strd - u2_width_uv;
|
|
pu1_src_v += src_v_strd - u2_width_uv;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used to convert 422 interleaved to 420sp
|
|
*
|
|
* @par Description
|
|
* Function used to convert 422 interleaved to 420sp
|
|
*
|
|
* @param[in] pu1_y_buf
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_u_buf
|
|
* Output u pointer
|
|
*
|
|
* @param[in[ pu1_v_buf
|
|
* Output V pointer
|
|
*
|
|
* @param[in] pu1_422i_buf
|
|
* Input 422i pointer
|
|
*
|
|
* @param[in] u4_y_width
|
|
* Width of Y component
|
|
*
|
|
* @param[in] u4_y_height
|
|
* Height of Y component
|
|
*
|
|
* @param[in] u4_y_stride
|
|
* Stride of pu1_y_buf
|
|
*
|
|
* @param[in] u4_u_stride
|
|
* Stride of pu1_u_buf
|
|
*
|
|
* @param[in] u4_v_stride
|
|
* Stride of pu1_v_buf
|
|
*
|
|
* @param[in] u4_422i_stride
|
|
* Stride of pu1_422i_buf
|
|
*
|
|
* @returns None
|
|
*
|
|
* @remarks For conversion
|
|
* pu1_v_buf = pu1_u_buf+1
|
|
* u4_u_stride = u4_v_stride
|
|
*
|
|
* The extra parameters are for maintaining API with assembly function
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf,
|
|
UWORD8 *pu1_u_buf,
|
|
UWORD8 *pu1_v_buf,
|
|
UWORD8 *pu1_422i_buf,
|
|
WORD32 u4_y_width,
|
|
WORD32 u4_y_height,
|
|
WORD32 u4_y_stride,
|
|
WORD32 u4_u_stride,
|
|
WORD32 u4_v_stride,
|
|
WORD32 u4_422i_stride)
|
|
{
|
|
WORD32 row, col;
|
|
UWORD8 *row_even_422 = pu1_422i_buf;
|
|
UWORD8 *row_odd_422 = row_even_422 + (u4_422i_stride << 1);
|
|
UWORD8 *row_even_luma = pu1_y_buf;
|
|
/* Since at the end of loop, we have row_even_luma += (luma_width << 1),
|
|
* it should be same here right? */
|
|
UWORD8 *row_odd_luma = row_even_luma + u4_y_stride;
|
|
UWORD8 *row_cb = pu1_u_buf;
|
|
UWORD8 *row_cr = pu1_v_buf;
|
|
|
|
for (row = 0; row < u4_y_height; row = row + 2)
|
|
{
|
|
for (col = 0; col < (u4_y_width << 1); col = col + 4)
|
|
{
|
|
UWORD8 cb_even = row_even_422[col];
|
|
UWORD8 cr_even = row_even_422[col + 2];
|
|
|
|
row_cb[col >> 1] = cb_even;
|
|
row_cr[col >> 1] = cr_even;
|
|
|
|
row_even_luma[col >> 1] = row_even_422[col + 1];
|
|
row_even_luma[(col >> 1) + 1] = row_even_422[col + 3];
|
|
|
|
row_odd_luma[col >> 1] = row_odd_422[col + 1];
|
|
row_odd_luma[(col >> 1) + 1] = row_odd_422[col + 3];
|
|
}
|
|
|
|
row_even_422 += (u4_422i_stride << 2);
|
|
row_odd_422 += (u4_422i_stride << 2);
|
|
|
|
row_even_luma += (u4_y_stride << 1);
|
|
row_odd_luma += (u4_y_stride << 1);
|
|
|
|
row_cb += u4_u_stride;
|
|
row_cr += u4_v_stride;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief Function used for format conversion or frame copy
|
|
*
|
|
* @par Description
|
|
* Function used from copying or converting a reference frame to display buffer
|
|
* in non shared mode
|
|
*
|
|
* @param[in] ps_codec
|
|
* Codec ctxt
|
|
*
|
|
* @param[in] ps_pic
|
|
* Reference pic ctxt
|
|
*
|
|
* @param[in] pu1_y_dst
|
|
* Output Y pointer
|
|
*
|
|
* @param[in] pu1_u_dst
|
|
* Output U/UV pointer ( UV is interleaved in the same format as that of input)
|
|
*
|
|
* @param[in] pu1_v_dst
|
|
* Output V pointer ( used in 420P output case)
|
|
*
|
|
* @param[in] u4_dst_y_strd
|
|
* Stride of destination Y buffer
|
|
*
|
|
* @param[in] u4_dst_u_strd
|
|
* Stride of destination U/V buffer
|
|
*
|
|
* @param[in] cur_row
|
|
* Start row of fmt conversion
|
|
*
|
|
* @param[in] num_rows
|
|
* number of rows to process
|
|
*
|
|
* @returns error status
|
|
*
|
|
* @remarks Assumes that the stride of U and V buffers are same.
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec,
|
|
pic_buf_t *ps_pic,
|
|
UWORD8 *pu1_y_dst,
|
|
UWORD8 *pu1_u_dst,
|
|
UWORD8 *pu1_v_dst,
|
|
UWORD32 u4_dst_y_strd,
|
|
UWORD32 u4_dst_uv_strd,
|
|
WORD32 cur_row,
|
|
WORD32 num_rows)
|
|
{
|
|
IH264E_ERROR_T ret = IH264E_SUCCESS;
|
|
UWORD8 *pu1_y_src, *pu1_uv_src;
|
|
UWORD8 *pu1_y_dst_tmp, *pu1_uv_dst_tmp;
|
|
UWORD8 *pu1_u_dst_tmp, *pu1_v_dst_tmp;
|
|
UWORD16 *pu2_rgb_dst_tmp;
|
|
UWORD32 *pu4_rgb_dst_tmp;
|
|
WORD32 is_u_first;
|
|
UWORD8 *pu1_luma;
|
|
UWORD8 *pu1_chroma;
|
|
WORD32 dst_stride, wd;
|
|
|
|
if (0 == num_rows)
|
|
return ret;
|
|
|
|
pu1_luma = ps_pic->pu1_luma;
|
|
pu1_chroma = ps_pic->pu1_chroma;
|
|
|
|
dst_stride = ps_codec->s_cfg.u4_wd;
|
|
wd = ps_codec->s_cfg.u4_disp_wd;
|
|
is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0;
|
|
|
|
/* In case of 420P output luma copy is disabled for shared mode */
|
|
{
|
|
pu1_y_src = pu1_luma + cur_row * ps_codec->i4_rec_strd;
|
|
pu1_uv_src = pu1_chroma + (cur_row / 2) * ps_codec->i4_rec_strd;
|
|
|
|
pu2_rgb_dst_tmp = (UWORD16 *) pu1_y_dst;
|
|
pu2_rgb_dst_tmp += cur_row * dst_stride;
|
|
pu4_rgb_dst_tmp = (UWORD32 *) pu1_y_dst;
|
|
pu4_rgb_dst_tmp += cur_row * dst_stride;
|
|
|
|
pu1_y_dst_tmp = pu1_y_dst + cur_row * u4_dst_y_strd;
|
|
pu1_uv_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
|
|
pu1_u_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd;
|
|
pu1_v_dst_tmp = pu1_v_dst + (cur_row / 2) * u4_dst_uv_strd;
|
|
|
|
/* If the call is non-blocking and there are no rows to be copied then return */
|
|
/* In non-shared mode, reference buffers are in 420SP UV format,
|
|
* if output also is in 420SP_UV, then just copy
|
|
* if output is in 420SP_VU then swap UV values
|
|
*/
|
|
if ((IV_YUV_420SP_UV == ps_codec->s_cfg.e_recon_color_fmt) ||
|
|
(IV_YUV_420SP_VU == ps_codec->s_cfg.e_recon_color_fmt))
|
|
{
|
|
ih264e_fmt_conv_420sp_to_420sp(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp,
|
|
pu1_uv_dst_tmp, wd, num_rows,
|
|
ps_codec->i4_rec_strd,
|
|
ps_codec->i4_rec_strd, u4_dst_y_strd,
|
|
u4_dst_uv_strd);
|
|
}
|
|
else if (IV_YUV_420P == ps_codec->s_cfg.e_recon_color_fmt)
|
|
{
|
|
ih264e_fmt_conv_420sp_to_420p(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp,
|
|
pu1_u_dst_tmp, pu1_v_dst_tmp, wd,
|
|
num_rows, ps_codec->i4_rec_strd,
|
|
ps_codec->i4_rec_strd, u4_dst_y_strd,
|
|
u4_dst_uv_strd, is_u_first, 0);
|
|
}
|
|
}
|
|
return(ret);
|
|
}
|
|
|