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.
1770 lines
48 KiB
1770 lines
48 KiB
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2018 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 ihevce_had_satd.c
|
|
*
|
|
* @brief
|
|
* This file contains functions of Hadamard SAD and SATD
|
|
*
|
|
* @author
|
|
* Ittiam
|
|
*
|
|
* List of Functions
|
|
* <TODO: TO BE ADDED>
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
/* System include files */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdarg.h>
|
|
#include <math.h>
|
|
|
|
/* User include files */
|
|
#include "ihevc_typedefs.h"
|
|
#include "itt_video_api.h"
|
|
#include "ihevce_api.h"
|
|
|
|
#include "rc_cntrl_param.h"
|
|
#include "rc_frame_info_collector.h"
|
|
#include "rc_look_ahead_params.h"
|
|
|
|
#include "ihevc_defs.h"
|
|
#include "ihevc_structs.h"
|
|
#include "ihevc_platform_macros.h"
|
|
#include "ihevc_deblk.h"
|
|
#include "ihevc_itrans_recon.h"
|
|
#include "ihevc_chroma_itrans_recon.h"
|
|
#include "ihevc_chroma_intra_pred.h"
|
|
#include "ihevc_intra_pred.h"
|
|
#include "ihevc_inter_pred.h"
|
|
#include "ihevc_mem_fns.h"
|
|
#include "ihevc_padding.h"
|
|
#include "ihevc_weighted_pred.h"
|
|
#include "ihevc_sao.h"
|
|
#include "ihevc_resi_trans.h"
|
|
#include "ihevc_quant_iquant_ssd.h"
|
|
#include "ihevc_cabac_tables.h"
|
|
|
|
#include "ihevce_defs.h"
|
|
#include "ihevce_lap_enc_structs.h"
|
|
#include "ihevce_multi_thrd_structs.h"
|
|
#include "ihevce_multi_thrd_funcs.h"
|
|
#include "ihevce_me_common_defs.h"
|
|
#include "ihevce_had_satd.h"
|
|
#include "ihevce_error_codes.h"
|
|
#include "ihevce_bitstream.h"
|
|
#include "ihevce_cabac.h"
|
|
#include "ihevce_rdoq_macros.h"
|
|
#include "ihevce_function_selector.h"
|
|
#include "ihevce_enc_structs.h"
|
|
#include "ihevce_cmn_utils_instr_set_router.h"
|
|
#include "hme_datatype.h"
|
|
#include "hme_interface.h"
|
|
#include "hme_common_defs.h"
|
|
#include "hme_defs.h"
|
|
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
static void ihevce_hadamard_4x4_8bit(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
WORD16 m[16];
|
|
|
|
/*===== hadamard horz transform =====*/
|
|
for(k = 0; k < 4; k++)
|
|
{
|
|
WORD32 r0, r1, r2, r3;
|
|
WORD32 h0, h1, h2, h3;
|
|
|
|
/* Compute the residue block */
|
|
r0 = pu1_src[0] - pu1_pred[0];
|
|
r1 = pu1_src[1] - pu1_pred[1];
|
|
r2 = pu1_src[2] - pu1_pred[2];
|
|
r3 = pu1_src[3] - pu1_pred[3];
|
|
|
|
h0 = r0 + r1;
|
|
h1 = r0 - r1;
|
|
h2 = r2 + r3;
|
|
h3 = r2 - r3;
|
|
|
|
m[k * 4 + 0] = h0 + h2;
|
|
m[k * 4 + 1] = h1 + h3;
|
|
m[k * 4 + 2] = h0 - h2;
|
|
m[k * 4 + 3] = h1 - h3;
|
|
|
|
pu1_pred += pred_strd;
|
|
pu1_src += src_strd;
|
|
}
|
|
|
|
/*===== hadamard vert transform =====*/
|
|
for(k = 0; k < 4; k++)
|
|
{
|
|
WORD32 v0, v1, v2, v3;
|
|
|
|
v0 = m[0 + k] + m[4 + k];
|
|
v1 = m[0 + k] - m[4 + k];
|
|
v2 = m[8 + k] + m[12 + k];
|
|
v3 = m[8 + k] - m[12 + k];
|
|
|
|
pi2_dst[0 * dst_strd + k] = v0 + v2;
|
|
pi2_dst[1 * dst_strd + k] = v1 + v3;
|
|
pi2_dst[2 * dst_strd + k] = v0 - v2;
|
|
pi2_dst[3 * dst_strd + k] = v1 - v3;
|
|
}
|
|
}
|
|
|
|
static void ihevce_hadamard_8x8_8bit(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 i;
|
|
|
|
// y0
|
|
ihevce_hadamard_4x4_8bit(pu1_src, src_strd, pu1_pred, pred_strd, pi2_dst, dst_strd);
|
|
// y1
|
|
ihevce_hadamard_4x4_8bit(pu1_src + 4, src_strd, pu1_pred + 4, pred_strd, pi2_dst + 4, dst_strd);
|
|
// y2
|
|
ihevce_hadamard_4x4_8bit(
|
|
pu1_src + 4 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 4 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (4 * dst_strd),
|
|
dst_strd);
|
|
// y3
|
|
ihevce_hadamard_4x4_8bit(
|
|
pu1_src + 4 + 4 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 4 + 4 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (4 * dst_strd) + 4,
|
|
dst_strd);
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
WORD32 idx = (i >> 2) * dst_strd + (i % 4);
|
|
WORD16 a0 = pi2_dst[idx];
|
|
WORD16 a1 = pi2_dst[4 + idx];
|
|
WORD16 a2 = pi2_dst[(4 * dst_strd) + idx];
|
|
WORD16 a3 = pi2_dst[(4 * dst_strd) + 4 + idx];
|
|
|
|
WORD16 b0 = (a0 + a1);
|
|
WORD16 b1 = (a0 - a1);
|
|
WORD16 b2 = (a2 + a3);
|
|
WORD16 b3 = (a2 - a3);
|
|
|
|
pi2_dst[idx] = b0 + b2;
|
|
pi2_dst[4 + idx] = b1 + b3;
|
|
pi2_dst[(4 * dst_strd) + idx] = b0 - b2;
|
|
pi2_dst[(4 * dst_strd) + 4 + idx] = b1 - b3;
|
|
}
|
|
}
|
|
|
|
static void ihevce_hadamard_16x16_8bit(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 i;
|
|
|
|
// y0
|
|
ihevce_hadamard_8x8_8bit(pu1_src, src_strd, pu1_pred, pred_strd, pi2_dst, dst_strd);
|
|
// y1
|
|
ihevce_hadamard_8x8_8bit(pu1_src + 8, src_strd, pu1_pred + 8, pred_strd, pi2_dst + 8, dst_strd);
|
|
// y2
|
|
ihevce_hadamard_8x8_8bit(
|
|
pu1_src + 8 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 8 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (8 * dst_strd),
|
|
dst_strd);
|
|
// y3
|
|
ihevce_hadamard_8x8_8bit(
|
|
pu1_src + 8 + 8 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 8 + 8 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (8 * dst_strd) + 8,
|
|
dst_strd);
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 64; i++)
|
|
{
|
|
WORD32 idx = (i >> 3) * dst_strd + (i % 8);
|
|
WORD16 a0 = pi2_dst[idx];
|
|
WORD16 a1 = pi2_dst[8 + idx];
|
|
WORD16 a2 = pi2_dst[(8 * dst_strd) + idx];
|
|
WORD16 a3 = pi2_dst[(8 * dst_strd) + 8 + idx];
|
|
|
|
WORD16 b0 = (a0 + a1) >> 1;
|
|
WORD16 b1 = (a0 - a1) >> 1;
|
|
WORD16 b2 = (a2 + a3) >> 1;
|
|
WORD16 b3 = (a2 - a3) >> 1;
|
|
|
|
pi2_dst[idx] = b0 + b2;
|
|
pi2_dst[8 + idx] = b1 + b3;
|
|
pi2_dst[(8 * dst_strd) + idx] = b0 - b2;
|
|
pi2_dst[(8 * dst_strd) + 8 + idx] = b1 - b3;
|
|
}
|
|
}
|
|
|
|
static void ihevce_hadamard_32x32_8bit(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 i;
|
|
|
|
// y0
|
|
ihevce_hadamard_16x16_8bit(pu1_src, src_strd, pu1_pred, pred_strd, pi2_dst, dst_strd);
|
|
// y1
|
|
ihevce_hadamard_16x16_8bit(
|
|
pu1_src + 16, src_strd, pu1_pred + 16, pred_strd, pi2_dst + 16, dst_strd);
|
|
// y2
|
|
ihevce_hadamard_16x16_8bit(
|
|
pu1_src + 16 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 16 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (16 * dst_strd),
|
|
dst_strd);
|
|
// y3
|
|
ihevce_hadamard_16x16_8bit(
|
|
pu1_src + 16 + 16 * src_strd,
|
|
src_strd,
|
|
pu1_pred + 16 + 16 * pred_strd,
|
|
pred_strd,
|
|
pi2_dst + (16 * dst_strd) + 16,
|
|
dst_strd);
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 256; i++)
|
|
{
|
|
WORD32 idx = (i >> 4) * dst_strd + (i % 16);
|
|
WORD16 a0 = pi2_dst[idx] >> 2;
|
|
WORD16 a1 = pi2_dst[16 + idx] >> 2;
|
|
WORD16 a2 = pi2_dst[(16 * dst_strd) + idx] >> 2;
|
|
WORD16 a3 = pi2_dst[(16 * dst_strd) + 16 + idx] >> 2;
|
|
|
|
WORD16 b0 = (a0 + a1);
|
|
WORD16 b1 = (a0 - a1);
|
|
WORD16 b2 = (a2 + a3);
|
|
WORD16 b3 = (a2 - a3);
|
|
|
|
pi2_dst[idx] = b0 + b2;
|
|
pi2_dst[16 + idx] = b1 + b3;
|
|
pi2_dst[(16 * dst_strd) + idx] = b0 - b2;
|
|
pi2_dst[(16 * dst_strd) + 16 + idx] = b1 - b3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Compute Hadamard sad for 4x4 block with 8-bit input
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[in] size
|
|
* WORD32 transform Block size
|
|
*
|
|
* @returns hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_HAD_4x4_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
WORD16 v[16];
|
|
UWORD32 u4_sad = 0;
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ihevce_hadamard_4x4_8bit(pu1_origin, src_strd, pu1_pred_buf, pred_strd, v, 4);
|
|
|
|
for(k = 0; k < 16; ++k)
|
|
u4_sad += abs(v[k]);
|
|
u4_sad = ((u4_sad + 2) >> 2);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes Hadamard Sad for 8x8 block with 8-bit input
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[in] size
|
|
* WORD32 transform Block size
|
|
*
|
|
* @returns Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_HAD_8x8_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
UWORD32 u4_sad = 0;
|
|
WORD16 v[64];
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ihevce_hadamard_8x8_8bit(pu1_origin, src_strd, pu1_pred_buf, pred_strd, v, 8);
|
|
|
|
for(k = 0; k < 64; ++k)
|
|
u4_sad += abs(v[k]);
|
|
u4_sad = ((u4_sad + 4) >> 3);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Compute dc suppressed hadamard sad for 8x8 block with 8-bit input
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[in] size
|
|
* WORD32 transform Block size
|
|
*
|
|
* @returns Hadamard SAD with DC Suppressed
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_compute_ac_had_8x8_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
UWORD32 u4_sad = 0;
|
|
WORD16 v[64];
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ihevce_hadamard_8x8_8bit(pu1_origin, src_strd, pu1_pred_buf, pred_strd, v, 8);
|
|
|
|
v[0] = 0;
|
|
for(k = 0; k < 64; ++k)
|
|
u4_sad += abs(v[k]);
|
|
u4_sad = ((u4_sad + 4) >> 3);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes Hadamard Sad for 16x16 block with 8-bit input
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[in] size
|
|
* WORD32 transform Block size
|
|
*
|
|
* @returns Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_HAD_16x16_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
UWORD32 u4_sad = 0;
|
|
WORD16 v[256];
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ihevce_hadamard_16x16_8bit(pu1_origin, src_strd, pu1_pred_buf, pred_strd, v, 16);
|
|
|
|
for(k = 0; k < 256; ++k)
|
|
u4_sad += abs(v[k]);
|
|
u4_sad = ((u4_sad + 4) >> 3);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes Hadamard Sad for 32x32 block with 8-bit input
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[in] size
|
|
* WORD32 transform Block size
|
|
*
|
|
* @returns Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_HAD_32x32_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k;
|
|
UWORD32 u4_sad = 0;
|
|
WORD16 v[32 * 32];
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ihevce_hadamard_32x32_8bit(pu1_origin, src_strd, pu1_pred_buf, pred_strd, v, 32);
|
|
|
|
for(k = 0; k < 32 * 32; ++k)
|
|
u4_sad += abs(v[k]);
|
|
u4_sad = ((u4_sad + 2) >> 2);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
//#if COMPUTE_16x16_R == C
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes 8x8 transform using children 4x4 hadamard results
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pi2_4x4_had
|
|
* WORD16 pointer to 4x4 hadamard buffer(y0, y1, y2, y3 hadmard in Zscan order)
|
|
*
|
|
* @param[in] had4_strd
|
|
* stride of 4x4 hadmard buffer pi2_y0, pi2_y1, pi2_y2, pi2_y3
|
|
*
|
|
* @param[out] pi2_dst
|
|
* destination buffer where 8x8 hadamard result is stored
|
|
*
|
|
* @param[in] dst_stride
|
|
* stride of destination block
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
* 8x8 Hadamard SATD
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
static UWORD32 ihevce_compute_8x8HAD_using_4x4(
|
|
WORD16 *pi2_4x4_had,
|
|
WORD32 had4_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 *pi4_cbf)
|
|
{
|
|
/* Qstep value is right shifted by 8 */
|
|
WORD32 threshold = (i4_frm_qstep >> 8);
|
|
|
|
/* Initialize pointers to 4 subblocks of 4x4 HAD buffer */
|
|
WORD16 *pi2_y0 = pi2_4x4_had;
|
|
WORD16 *pi2_y1 = pi2_4x4_had + 4;
|
|
WORD16 *pi2_y2 = pi2_4x4_had + had4_strd * 4;
|
|
WORD16 *pi2_y3 = pi2_4x4_had + had4_strd * 4 + 4;
|
|
|
|
/* Initialize pointers to store 8x8 HAD output */
|
|
WORD16 *pi2_dst0 = pi2_dst;
|
|
WORD16 *pi2_dst1 = pi2_dst + 4;
|
|
WORD16 *pi2_dst2 = pi2_dst + dst_strd * 4;
|
|
WORD16 *pi2_dst3 = pi2_dst + dst_strd * 4 + 4;
|
|
|
|
UWORD32 u4_satd = 0;
|
|
WORD32 i;
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
WORD32 src_idx = (i >> 2) * had4_strd + (i % 4);
|
|
WORD32 dst_idx = (i >> 2) * dst_strd + (i % 4);
|
|
|
|
WORD16 a0 = pi2_y0[src_idx];
|
|
WORD16 a1 = pi2_y1[src_idx];
|
|
WORD16 a2 = pi2_y2[src_idx];
|
|
WORD16 a3 = pi2_y3[src_idx];
|
|
|
|
WORD16 b0 = (a0 + a1);
|
|
WORD16 b1 = (a0 - a1);
|
|
WORD16 b2 = (a2 + a3);
|
|
WORD16 b3 = (a2 - a3);
|
|
|
|
pi2_dst0[dst_idx] = b0 + b2;
|
|
pi2_dst1[dst_idx] = b1 + b3;
|
|
pi2_dst2[dst_idx] = b0 - b2;
|
|
pi2_dst3[dst_idx] = b1 - b3;
|
|
|
|
if(ABS(pi2_dst0[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst1[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst2[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst3[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
|
|
u4_satd += ABS(pi2_dst0[dst_idx]);
|
|
u4_satd += ABS(pi2_dst1[dst_idx]);
|
|
u4_satd += ABS(pi2_dst2[dst_idx]);
|
|
u4_satd += ABS(pi2_dst3[dst_idx]);
|
|
}
|
|
|
|
/* return the 8x8 satd */
|
|
return (u4_satd);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes Residue and Hadamard Transform for four 4x4 blocks (Z scan) of
|
|
* a 8x8 block (Residue is computed for 8-bit src and prediction buffers)
|
|
* Modified to incorporate the dead-zone implementation - Lokesh
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[out] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[out] pi4_hsad
|
|
* array for storing hadmard sad of each 4x4 block
|
|
*
|
|
* @param[in] hsad_stride
|
|
* stride of hadmard sad destination buffer (for Zscan order of storing sads)
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
*
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
static WORD32 ihevce_had4_4x4(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst4x4,
|
|
WORD32 dst_strd,
|
|
WORD32 *pi4_hsad,
|
|
WORD32 hsad_stride,
|
|
WORD32 i4_frm_qstep)
|
|
{
|
|
WORD32 i, k;
|
|
WORD32 i4_child_total_sad = 0;
|
|
|
|
(void)i4_frm_qstep;
|
|
/* -------- Compute four 4x4 HAD Transforms ---------*/
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
UWORD8 *pu1_pi0, *pu1_pi1;
|
|
WORD16 *pi2_dst;
|
|
WORD32 blkx, blky;
|
|
UWORD32 u4_hsad = 0;
|
|
// TODO: choose deadzone as f(qstep)
|
|
WORD32 threshold = 0;
|
|
|
|
/*****************************************************/
|
|
/* Assuming the looping structure of the four */
|
|
/* blocks is in Z scan order of 4x4s in a 8x8 */
|
|
/* block instead of raster scan */
|
|
/*****************************************************/
|
|
blkx = (i & 0x1);
|
|
blky = (i >> 1);
|
|
|
|
pu1_pi0 = pu1_src + (blkx * 4) + (blky * 4 * src_strd);
|
|
pu1_pi1 = pu1_pred + (blkx * 4) + (blky * 4 * pred_strd);
|
|
pi2_dst = pi2_dst4x4 + (blkx * 4) + (blky * 4 * dst_strd);
|
|
|
|
ihevce_hadamard_4x4_8bit(pu1_pi0, src_strd, pu1_pi1, pred_strd, pi2_dst, dst_strd);
|
|
|
|
for(k = 0; k < 4; k++)
|
|
{
|
|
if(ABS(pi2_dst[0 * dst_strd + k]) < threshold)
|
|
pi2_dst[0 * dst_strd + k] = 0;
|
|
|
|
if(ABS(pi2_dst[1 * dst_strd + k]) < threshold)
|
|
pi2_dst[1 * dst_strd + k] = 0;
|
|
|
|
if(ABS(pi2_dst[2 * dst_strd + k]) < threshold)
|
|
pi2_dst[2 * dst_strd + k] = 0;
|
|
|
|
if(ABS(pi2_dst[3 * dst_strd + k]) < threshold)
|
|
pi2_dst[3 * dst_strd + k] = 0;
|
|
|
|
/* Accumulate the SATD */
|
|
u4_hsad += ABS(pi2_dst[0 * dst_strd + k]);
|
|
u4_hsad += ABS(pi2_dst[1 * dst_strd + k]);
|
|
u4_hsad += ABS(pi2_dst[2 * dst_strd + k]);
|
|
u4_hsad += ABS(pi2_dst[3 * dst_strd + k]);
|
|
}
|
|
|
|
/*===== Normalize the HSAD =====*/
|
|
pi4_hsad[blkx + (blky * hsad_stride)] = ((u4_hsad + 2) >> 2);
|
|
i4_child_total_sad += ((u4_hsad + 2) >> 2);
|
|
}
|
|
return i4_child_total_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* HSAD is returned for the 4, 4x4 in 8x8
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[out] pi2_dst
|
|
* WORD16 pointer to the transform output block
|
|
*
|
|
* @param[out] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[out] ppi4_hsad
|
|
* pointer to base pointers for storing hadmard sads of various
|
|
* block sizes (4x4 to 32x32)
|
|
*
|
|
* @param[in] pos_x_y_4x4
|
|
* Denotes packed x,y postion of current 4x4 block w.r.t to start of ctb/CU/MB
|
|
* Lower 16bits denote xpos and upper 16ypos of the 4x4block
|
|
*
|
|
* @param[in] num_4x4_in_row
|
|
* Denotes the number of current 4x4 blocks in a ctb/CU/MB
|
|
*
|
|
* @returns
|
|
*
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ihevce_had_8x8_using_4_4x4(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 **ppi4_hsad,
|
|
WORD32 pos_x_y_4x4,
|
|
WORD32 num_4x4_in_row)
|
|
{
|
|
WORD16 ai2_4x4_had[64];
|
|
WORD32 pos_x = pos_x_y_4x4 & 0xFFFF;
|
|
WORD32 pos_y = (pos_x_y_4x4 >> 16) & 0xFFFF;
|
|
WORD32 *pi4_4x4_hsad;
|
|
WORD32 *pi4_8x8_hsad;
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
ASSERT(pos_x >= 0);
|
|
ASSERT(pos_y >= 0);
|
|
|
|
/* Initialize pointers to store 4x4 and 8x8 HAD SATDs */
|
|
pi4_4x4_hsad = ppi4_hsad[HAD_4x4] + pos_x + pos_y * num_4x4_in_row;
|
|
pi4_8x8_hsad = ppi4_hsad[HAD_8x8] + (pos_x >> 1) + (pos_y >> 1) * (num_4x4_in_row >> 1);
|
|
|
|
/* -------- Compute four 4x4 HAD Transforms of 8x8 in one call--------- */
|
|
pi4_8x8_hsad[0] = ihevce_had4_4x4(
|
|
pu1_src, src_strd, pu1_pred, pred_strd, ai2_4x4_had, 8, pi4_4x4_hsad, num_4x4_in_row, 0);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Reursive Hadamard Transform for 8x8 block. HSAD is returned for the 8x8
|
|
* block and its four subblocks(4x4).
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[out] pi2_dst
|
|
* WORD16 pointer to the transform output block
|
|
*
|
|
* @param[out] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[out] ppi4_hsad
|
|
* pointer to base pointers for storing hadmard sads of various
|
|
* block sizes (4x4 to 32x32)
|
|
*
|
|
* @param[in] pos_x_y_4x4
|
|
* Denotes packed x,y postion of current 4x4 block w.r.t to start of ctb/CU/MB
|
|
* Lower 16bits denote xpos and upper 16ypos of the 4x4block
|
|
*
|
|
* @param[in] num_4x4_in_row
|
|
* Denotes the number of current 4x4 blocks in a ctb/CU/MB
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
*
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
WORD32 ihevce_had_8x8_using_4_4x4_r(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 **ppi4_hsad,
|
|
WORD32 **ppi4_tu_split,
|
|
WORD32 **ppi4_tu_early_cbf,
|
|
WORD32 pos_x_y_4x4,
|
|
WORD32 num_4x4_in_row,
|
|
WORD32 lambda,
|
|
WORD32 lambda_q_shift,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 i4_cur_depth,
|
|
WORD32 i4_max_depth,
|
|
WORD32 i4_max_tr_size,
|
|
WORD32 *pi4_tu_split_cost,
|
|
void *pv_func_sel)
|
|
{
|
|
WORD16 ai2_4x4_had[64];
|
|
WORD32 pos_x = pos_x_y_4x4 & 0xFFFF;
|
|
WORD32 pos_y = (pos_x_y_4x4 >> 16) & 0xFFFF;
|
|
WORD32 *pi4_4x4_hsad;
|
|
WORD32 *pi4_8x8_hsad;
|
|
WORD32 *pi4_8x8_tu_split;
|
|
|
|
WORD32 *pi4_8x8_tu_early_cbf;
|
|
|
|
UWORD32 u4_satd;
|
|
WORD32 cost_child = 0, cost_parent = 0;
|
|
WORD32 early_cbf = 0;
|
|
|
|
const UWORD8 u1_cur_tr_size = 8;
|
|
/* Stores the best cost for the Current 8x8: Lokesh */
|
|
WORD32 best_cost = 0;
|
|
|
|
(void)pv_func_sel;
|
|
ASSERT(pos_x >= 0);
|
|
ASSERT(pos_y >= 0);
|
|
|
|
/* Initialize pointers to store 4x4 and 8x8 HAD SATDs */
|
|
pi4_4x4_hsad = ppi4_hsad[HAD_4x4] + pos_x + pos_y * num_4x4_in_row;
|
|
pi4_8x8_hsad = ppi4_hsad[HAD_8x8] + (pos_x >> 1) + (pos_y >> 1) * (num_4x4_in_row >> 1);
|
|
pi4_8x8_tu_split = ppi4_tu_split[HAD_8x8] + (pos_x >> 1) + (pos_y >> 1) * (num_4x4_in_row >> 1);
|
|
pi4_8x8_tu_early_cbf =
|
|
ppi4_tu_early_cbf[HAD_8x8] + (pos_x >> 1) + (pos_y >> 1) * (num_4x4_in_row >> 1);
|
|
|
|
/* -------- Compute four 4x4 HAD Transforms of 8x8 in one call--------- */
|
|
cost_child = ihevce_had4_4x4(
|
|
pu1_src, src_strd, pu1_pred, pred_strd, ai2_4x4_had, 8, pi4_4x4_hsad, num_4x4_in_row, 0);
|
|
|
|
/* -------- Compute 8x8 HAD Transform using 4x4 results ------------- */
|
|
u4_satd = ihevce_compute_8x8HAD_using_4x4(
|
|
ai2_4x4_had, 8, pi2_dst, dst_strd, i4_frm_qstep, &early_cbf);
|
|
|
|
/* store the normalized 8x8 satd */
|
|
cost_parent = ((u4_satd + 4) >> 3);
|
|
|
|
/* 4 CBF Flags, extra 1 becoz of the 0.5 bits per bin is assumed */
|
|
cost_child += ((4) * lambda) >> (lambda_q_shift + 1);
|
|
|
|
if(i4_cur_depth < i4_max_depth)
|
|
{
|
|
if((cost_child < cost_parent) || (i4_max_tr_size < u1_cur_tr_size))
|
|
{
|
|
//cost_child -= ((4) * lambda) >> (lambda_q_shift + 1);
|
|
*pi4_tu_split_cost += (4 * lambda) >> (lambda_q_shift + 1);
|
|
best_cost = cost_child;
|
|
best_cost <<= 1;
|
|
best_cost++;
|
|
pi4_8x8_tu_split[0] = 1;
|
|
pi4_8x8_hsad[0] = cost_child;
|
|
}
|
|
else
|
|
{
|
|
//cost_parent -= ((1) * lambda) >> (lambda_q_shift + 1);
|
|
best_cost = cost_parent;
|
|
best_cost <<= 1;
|
|
pi4_8x8_tu_split[0] = 0;
|
|
pi4_8x8_hsad[0] = cost_parent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//cost_parent -= ((1) * lambda) >> (lambda_q_shift + 1);
|
|
best_cost = cost_parent;
|
|
best_cost <<= 1;
|
|
pi4_8x8_tu_split[0] = 0;
|
|
pi4_8x8_hsad[0] = cost_parent;
|
|
}
|
|
|
|
pi4_8x8_tu_early_cbf[0] = early_cbf;
|
|
|
|
/* best cost has tu_split_flag at LSB(Least significant bit) */
|
|
return ((best_cost << 1) + early_cbf);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes 16x16 transform using children 8x8 hadamard results
|
|
* Modified to incorporate the dead-zone implementation - Lokesh
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pi2_8x8_had
|
|
* WORD16 pointer to 8x8 hadamard buffer(y0, y1, y2, y3 hadmard in Zscan order)
|
|
*
|
|
* @param[in] had8_strd
|
|
* stride of 8x8 hadmard buffer pi2_y0, pi2_y1, pi2_y2, pi2_y3
|
|
*
|
|
* @param[out] pi2_dst
|
|
* destination buffer where 8x8 hadamard result is stored
|
|
*
|
|
* @param[in] dst_stride
|
|
* stride of destination block
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
* 16x16 Hadamard SATD
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
static UWORD32 ihevce_compute_16x16HAD_using_8x8(
|
|
WORD16 *pi2_8x8_had,
|
|
WORD32 had8_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 *pi4_cbf)
|
|
{
|
|
/* Qstep value is right shifted by 8 */
|
|
WORD32 threshold = (i4_frm_qstep >> 8);
|
|
|
|
/* Initialize pointers to 4 subblocks of 8x8 HAD buffer */
|
|
WORD16 *pi2_y0 = pi2_8x8_had;
|
|
WORD16 *pi2_y1 = pi2_8x8_had + 8;
|
|
WORD16 *pi2_y2 = pi2_8x8_had + had8_strd * 8;
|
|
WORD16 *pi2_y3 = pi2_8x8_had + had8_strd * 8 + 8;
|
|
|
|
/* Initialize pointers to store 8x8 HAD output */
|
|
WORD16 *pi2_dst0 = pi2_dst;
|
|
WORD16 *pi2_dst1 = pi2_dst + 8;
|
|
WORD16 *pi2_dst2 = pi2_dst + dst_strd * 8;
|
|
WORD16 *pi2_dst3 = pi2_dst + dst_strd * 8 + 8;
|
|
|
|
UWORD32 u4_satd = 0;
|
|
WORD32 i;
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 64; i++)
|
|
{
|
|
WORD32 src_idx = (i >> 3) * had8_strd + (i % 8);
|
|
WORD32 dst_idx = (i >> 3) * dst_strd + (i % 8);
|
|
|
|
WORD16 a0 = pi2_y0[src_idx];
|
|
WORD16 a1 = pi2_y1[src_idx];
|
|
WORD16 a2 = pi2_y2[src_idx];
|
|
WORD16 a3 = pi2_y3[src_idx];
|
|
|
|
WORD16 b0 = (a0 + a1) >> 1;
|
|
WORD16 b1 = (a0 - a1) >> 1;
|
|
WORD16 b2 = (a2 + a3) >> 1;
|
|
WORD16 b3 = (a2 - a3) >> 1;
|
|
|
|
pi2_dst0[dst_idx] = b0 + b2;
|
|
pi2_dst1[dst_idx] = b1 + b3;
|
|
pi2_dst2[dst_idx] = b0 - b2;
|
|
pi2_dst3[dst_idx] = b1 - b3;
|
|
|
|
/* Make the value of dst to zerp, if it falls below the dead-zone */
|
|
if(ABS(pi2_dst0[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst1[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst2[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst3[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
|
|
u4_satd += ABS(pi2_dst0[dst_idx]);
|
|
u4_satd += ABS(pi2_dst1[dst_idx]);
|
|
u4_satd += ABS(pi2_dst2[dst_idx]);
|
|
u4_satd += ABS(pi2_dst3[dst_idx]);
|
|
}
|
|
|
|
/* return 16x16 satd */
|
|
return (u4_satd);
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Hadamard Transform for 16x16 block with 8x8 and 4x4 SATD updates.
|
|
* Uses recursive 8x8 had output to compute satd for 16x16 and its children
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[out] pi2_dst
|
|
* WORD16 pointer to the transform output block
|
|
*
|
|
* @param[out] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[out] ppi4_hsad
|
|
* pointer to base pointers for storing hadmard sads of various
|
|
* block sizes (4x4 to 32x32)
|
|
*
|
|
* @param[in] pos_x_y_4x4
|
|
* Denotes packed x,y postion of current 4x4 block w.r.t to start of ctb/CU/MB
|
|
* Lower 16bits denote xpos and upper 16ypos of the 4x4block
|
|
*
|
|
* @param[in] num_4x4_in_row
|
|
* Denotes the number of current 4x4 blocks in a ctb/CU/MB
|
|
*
|
|
* @param[in] lambda
|
|
* lambda values is the cost factor calculated based on QP
|
|
*
|
|
* @param[in] lambda_q_shift
|
|
* lambda_q_shift used to reverse the lambda value back from q8 format
|
|
*
|
|
* @param[in] depth
|
|
* depth gives the current TU depth with respect to the CU
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
*
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
|
|
WORD32 ihevce_had_16x16_r(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 **ppi4_hsad,
|
|
WORD32 **ppi4_tu_split,
|
|
WORD32 **ppi4_tu_early_cbf,
|
|
WORD32 pos_x_y_4x4,
|
|
WORD32 num_4x4_in_row,
|
|
WORD32 lambda,
|
|
WORD32 lambda_q_shift,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 i4_cur_depth,
|
|
WORD32 i4_max_depth,
|
|
WORD32 i4_max_tr_size,
|
|
WORD32 *pi4_tu_split_cost,
|
|
void *pv_func_sel)
|
|
{
|
|
WORD16 ai2_8x8_had[256];
|
|
WORD32 *pi4_16x16_hsad;
|
|
WORD32 *pi4_16x16_tu_split;
|
|
|
|
WORD32 *pi4_16x16_tu_early_cbf;
|
|
|
|
UWORD32 u4_satd = 0;
|
|
WORD32 tu_split_flag = 0;
|
|
WORD32 i4_early_cbf_flag = 0, early_cbf = 0;
|
|
const UWORD8 u1_cur_tr_size = 16;
|
|
|
|
/* cost_parent : Stores the cost of the parent HAD transform (16x16) */
|
|
/* cost_child : Stores the cost of the child HAD transform (16x16) */
|
|
WORD32 cost_parent = 0, cost_child = 0;
|
|
|
|
/*best_cost returns the best cost at the end of the function */
|
|
/*tu_split denoes whether the TU (16x16)is split or not */
|
|
WORD32 best_cost = 0, best_cost_tu_split;
|
|
WORD32 i;
|
|
|
|
WORD16 *pi2_y0;
|
|
UWORD8 *pu1_src0;
|
|
UWORD8 *pu1_pred0;
|
|
WORD32 pos_x_y_4x4_0;
|
|
|
|
WORD32 pos_x = pos_x_y_4x4 & 0xFFFF;
|
|
WORD32 pos_y = (pos_x_y_4x4 >> 16) & 0xFFFF;
|
|
|
|
ASSERT(pos_x >= 0);
|
|
ASSERT(pos_y >= 0);
|
|
|
|
/* Initialize pointers to store 16x16 SATDs */
|
|
pi4_16x16_hsad = ppi4_hsad[HAD_16x16] + (pos_x >> 2) + (pos_y >> 2) * (num_4x4_in_row >> 2);
|
|
|
|
pi4_16x16_tu_split =
|
|
ppi4_tu_split[HAD_16x16] + (pos_x >> 2) + (pos_y >> 2) * (num_4x4_in_row >> 2);
|
|
|
|
pi4_16x16_tu_early_cbf =
|
|
ppi4_tu_early_cbf[HAD_16x16] + (pos_x >> 2) + (pos_y >> 2) * (num_4x4_in_row >> 2);
|
|
|
|
/* -------- Compute four 8x8 HAD Transforms of 16x16 call--------- */
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
pu1_src0 = pu1_src + (i & 0x01) * 8 + (i >> 1) * src_strd * 8;
|
|
pu1_pred0 = pu1_pred + (i & 0x01) * 8 + (i >> 1) * pred_strd * 8;
|
|
pi2_y0 = ai2_8x8_had + (i & 0x01) * 8 + (i >> 1) * 16 * 8;
|
|
pos_x_y_4x4_0 = pos_x_y_4x4 + (i & 0x01) * 2 + (i >> 1) * (2 << 16);
|
|
|
|
best_cost_tu_split = ihevce_had_8x8_using_4_4x4_r(
|
|
pu1_src0,
|
|
src_strd,
|
|
pu1_pred0,
|
|
pred_strd,
|
|
pi2_y0,
|
|
16,
|
|
ppi4_hsad,
|
|
ppi4_tu_split,
|
|
ppi4_tu_early_cbf,
|
|
pos_x_y_4x4_0,
|
|
num_4x4_in_row,
|
|
lambda,
|
|
lambda_q_shift,
|
|
i4_frm_qstep,
|
|
i4_cur_depth + 1,
|
|
i4_max_depth,
|
|
i4_max_tr_size,
|
|
pi4_tu_split_cost,
|
|
pv_func_sel);
|
|
|
|
/* Cost is shifted by two bits for Tu_split_flag and early cbf flag */
|
|
best_cost = (best_cost_tu_split >> 2);
|
|
|
|
/* Last but one bit stores the information regarding the TU_Split */
|
|
tu_split_flag += (best_cost_tu_split & 0x3) >> 1;
|
|
|
|
/* Last bit stores the information regarding the early_cbf */
|
|
i4_early_cbf_flag += (best_cost_tu_split & 0x1);
|
|
|
|
cost_child += best_cost;
|
|
|
|
tu_split_flag <<= 1;
|
|
i4_early_cbf_flag <<= 1;
|
|
}
|
|
|
|
/* -------- Compute 16x16 HAD Transform using 8x8 results ------------- */
|
|
pi2_y0 = ai2_8x8_had;
|
|
|
|
/* Threshold currently passed as "0" */
|
|
u4_satd =
|
|
ihevce_compute_16x16HAD_using_8x8(pi2_y0, 16, pi2_dst, dst_strd, i4_frm_qstep, &early_cbf);
|
|
|
|
/* store the normalized satd */
|
|
cost_parent = ((u4_satd + 4) >> 3);
|
|
|
|
/* 4 TU_Split flags , 4 CBF Flags, extra 1 becoz of the 0.5 bits per bin is assumed */
|
|
cost_child += ((4 + 4) * lambda) >> (lambda_q_shift + 1);
|
|
|
|
i4_early_cbf_flag += early_cbf;
|
|
|
|
/* Right now the depth is hard-coded to 4: The depth can be modified from the config file
|
|
which decides the extent to which TU_REC needs to be done */
|
|
if(i4_cur_depth < i4_max_depth)
|
|
{
|
|
if((cost_child < cost_parent) || (i4_max_tr_size < u1_cur_tr_size))
|
|
{
|
|
//cost_child -= ((4 + 4) * lambda) >> (lambda_q_shift + 1);
|
|
*pi4_tu_split_cost += ((4 + 4) * lambda) >> (lambda_q_shift + 1);
|
|
tu_split_flag += 1;
|
|
best_cost = cost_child;
|
|
}
|
|
else
|
|
{
|
|
//cost_parent -= ((1 + 1) * lambda) >> (lambda_q_shift + 1);
|
|
tu_split_flag += 0;
|
|
best_cost = cost_parent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//cost_parent -= ((1 + 1) * lambda) >> (lambda_q_shift + 1);
|
|
tu_split_flag += 0;
|
|
best_cost = cost_parent;
|
|
}
|
|
|
|
pi4_16x16_hsad[0] = best_cost;
|
|
pi4_16x16_tu_split[0] = tu_split_flag;
|
|
pi4_16x16_tu_early_cbf[0] = i4_early_cbf_flag;
|
|
|
|
/*returning two values(best cost & tu_split_flag) as a single value*/
|
|
return ((best_cost << 10) + (tu_split_flag << 5) + i4_early_cbf_flag);
|
|
}
|
|
|
|
//#endif
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Computes 32x32 transform using children 16x16 hadamard results
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pi2_16x16_had
|
|
* WORD16 pointer to 16x16 hadamard buffer(y0, y1, y2, y3 hadmard in Zscan order)
|
|
*
|
|
* @param[in] had16_strd
|
|
* stride of 16x16 hadmard buffer pi2_y0, pi2_y1, pi2_y2, pi2_y3
|
|
*
|
|
* @param[out] pi2_dst
|
|
* destination buffer where 16x16 hadamard result is stored
|
|
*
|
|
* @param[in] dst_stride
|
|
* stride of destination block
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
* @returns
|
|
* 32x32 Hadamard SATD
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
//#if COMPUTE_32x32_USING_16X16 == C
|
|
UWORD32 ihevce_compute_32x32HAD_using_16x16(
|
|
WORD16 *pi2_16x16_had,
|
|
WORD32 had16_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 *pi4_cbf)
|
|
{
|
|
/* Qstep value is right shifted by 8 */
|
|
WORD32 threshold = (i4_frm_qstep >> 8);
|
|
|
|
/* Initialize pointers to 4 subblocks of 8x8 HAD buffer */
|
|
WORD16 *pi2_y0 = pi2_16x16_had;
|
|
WORD16 *pi2_y1 = pi2_16x16_had + 16;
|
|
WORD16 *pi2_y2 = pi2_16x16_had + had16_strd * 16;
|
|
WORD16 *pi2_y3 = pi2_16x16_had + had16_strd * 16 + 16;
|
|
|
|
/* Initialize pointers to store 8x8 HAD output */
|
|
WORD16 *pi2_dst0 = pi2_dst;
|
|
WORD16 *pi2_dst1 = pi2_dst + 16;
|
|
WORD16 *pi2_dst2 = pi2_dst + dst_strd * 16;
|
|
WORD16 *pi2_dst3 = pi2_dst + dst_strd * 16 + 16;
|
|
|
|
UWORD32 u4_satd = 0;
|
|
WORD32 i;
|
|
|
|
/* Child HAD results combined as follows to get Parent result */
|
|
/* _ _ */
|
|
/* | (y0 + y1) + (y2 + y3) (y0 - y1) + (y2 - y3) | */
|
|
/* | (y0 + y1) - (y2 + y3) (y0 - y1) - (y2 - y3) | */
|
|
/* \- -/ */
|
|
for(i = 0; i < 256; i++)
|
|
{
|
|
WORD32 src_idx = (i >> 4) * had16_strd + (i % 16);
|
|
WORD32 dst_idx = (i >> 4) * dst_strd + (i % 16);
|
|
|
|
WORD16 a0 = pi2_y0[src_idx] >> 2;
|
|
WORD16 a1 = pi2_y1[src_idx] >> 2;
|
|
WORD16 a2 = pi2_y2[src_idx] >> 2;
|
|
WORD16 a3 = pi2_y3[src_idx] >> 2;
|
|
|
|
WORD16 b0 = (a0 + a1);
|
|
WORD16 b1 = (a0 - a1);
|
|
WORD16 b2 = (a2 + a3);
|
|
WORD16 b3 = (a2 - a3);
|
|
|
|
pi2_dst0[dst_idx] = b0 + b2;
|
|
pi2_dst1[dst_idx] = b1 + b3;
|
|
pi2_dst2[dst_idx] = b0 - b2;
|
|
pi2_dst3[dst_idx] = b1 - b3;
|
|
|
|
/* Make the value of dst to zerp, if it falls below the dead-zone */
|
|
if(ABS(pi2_dst0[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst1[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst2[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
if(ABS(pi2_dst3[dst_idx]) > threshold)
|
|
*pi4_cbf = 1;
|
|
|
|
u4_satd += ABS(pi2_dst0[dst_idx]);
|
|
u4_satd += ABS(pi2_dst1[dst_idx]);
|
|
u4_satd += ABS(pi2_dst2[dst_idx]);
|
|
u4_satd += ABS(pi2_dst3[dst_idx]);
|
|
}
|
|
|
|
/* return 32x32 satd */
|
|
return (u4_satd);
|
|
}
|
|
//#endif
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Hadamard Transform for 32x32 block with 16x6, 8x8 and 4x4 SATD updates.
|
|
* Uses recursive 16x16 had output to compute satd for 32x32 and its children
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the current block
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred
|
|
* UWORD8 pointer to the prediction block
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[out] pi2_dst
|
|
* WORD16 pointer to the transform output block
|
|
*
|
|
* @param[out] dst_strd
|
|
* WORD32 Destination stride
|
|
*
|
|
* @param[out] ppi4_hsad
|
|
* pointer to base pointers for storing hadmard sads of various
|
|
* block sizes (4x4 to 32x32)
|
|
*
|
|
* @param[in] pos_x_y_4x4
|
|
* Denotes packed x,y postion of current 4x4 block w.r.t to start of ctb/CU/MB
|
|
* Lower 16bits denote xpos and upper 16ypos of the 4x4block
|
|
*
|
|
* @param[in] num_4x4_in_row
|
|
* Denotes the number of current 4x4 blocks in a ctb/CU/MB
|
|
*
|
|
* @param[in] lambda
|
|
* lambda values is the cost factor calculated based on QP
|
|
*
|
|
* @param[in] lambda_q_shift
|
|
* lambda_q_shift used to reverse the lambda value back from q8 format
|
|
*
|
|
* @param[in] depth
|
|
* depth gives the current TU depth with respect to the CU
|
|
*
|
|
* @param[in] i4_frm_qstep
|
|
* frm_qstep value based on the which the threshold value is calculated
|
|
*
|
|
*
|
|
* @returns
|
|
*
|
|
* @remarks
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
void ihevce_had_32x32_r(
|
|
UWORD8 *pu1_src,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd,
|
|
WORD32 **ppi4_hsad,
|
|
WORD32 **ppi4_tu_split,
|
|
WORD32 **ppi4_tu_early_cbf,
|
|
WORD32 pos_x_y_4x4,
|
|
WORD32 num_4x4_in_row,
|
|
WORD32 lambda,
|
|
WORD32 lambda_q_shift,
|
|
WORD32 i4_frm_qstep,
|
|
WORD32 i4_cur_depth,
|
|
WORD32 i4_max_depth,
|
|
WORD32 i4_max_tr_size,
|
|
WORD32 *pi4_tu_split_cost,
|
|
me_func_selector_t *ps_func_selector)
|
|
|
|
{
|
|
WORD16 ai2_16x16_had[1024];
|
|
WORD32 *pi4_32x32_hsad;
|
|
WORD32 *pi4_32x32_tu_split;
|
|
WORD32 *pi4_32x32_tu_early_cbf;
|
|
|
|
WORD32 pos_x = pos_x_y_4x4 & 0xFFFF;
|
|
WORD32 pos_y = (pos_x_y_4x4 >> 16) & 0xFFFF;
|
|
WORD32 tu_split_flag = 0;
|
|
const UWORD8 u1_cur_tr_size = 32;
|
|
WORD32 i4_early_cbf_flag = 0, early_cbf = 0;
|
|
|
|
/* cost_parent : Stores the cost of the parent HAD transform (16x16) */
|
|
/* cost_child : Stores the cost of the child HAD transform (16x16) */
|
|
WORD32 cost_child = 0, cost_parent = 0;
|
|
|
|
/*retuned as the best cost for the entire TU (32x32) */
|
|
WORD32 best_cost = 0;
|
|
/*captures the best cost and tu_split at child level */
|
|
WORD32 best_cost_tu_split;
|
|
|
|
/* Initialize pointers to 4 8x8 blocks in 16x16 */
|
|
WORD16 *pi2_y0 = ai2_16x16_had;
|
|
WORD16 *pi2_y1 = ai2_16x16_had + 16;
|
|
WORD16 *pi2_y2 = ai2_16x16_had + 32 * 16;
|
|
WORD16 *pi2_y3 = ai2_16x16_had + 32 * 16 + 16;
|
|
|
|
UWORD8 *pu1_src0 = pu1_src;
|
|
UWORD8 *pu1_src1 = pu1_src + 16;
|
|
UWORD8 *pu1_src2 = pu1_src + src_strd * 16;
|
|
UWORD8 *pu1_src3 = pu1_src + src_strd * 16 + 16;
|
|
|
|
UWORD8 *pu1_pred0 = pu1_pred;
|
|
UWORD8 *pu1_pred1 = pu1_pred + 16;
|
|
UWORD8 *pu1_pred2 = pu1_pred + pred_strd * 16;
|
|
UWORD8 *pu1_pred3 = pu1_pred + pred_strd * 16 + 16;
|
|
|
|
ASSERT(pos_x >= 0);
|
|
ASSERT(pos_y >= 0);
|
|
|
|
/* Initialize pointers to store 32x32 SATDs */
|
|
pi4_32x32_hsad = ppi4_hsad[HAD_32x32] + (pos_x >> 3) + (pos_y >> 3) * (num_4x4_in_row >> 3);
|
|
|
|
pi4_32x32_tu_split =
|
|
ppi4_tu_split[HAD_32x32] + (pos_x >> 3) + (pos_y >> 3) * (num_4x4_in_row >> 3);
|
|
|
|
pi4_32x32_tu_early_cbf =
|
|
ppi4_tu_early_cbf[HAD_32x32] + (pos_x >> 3) + (pos_y >> 3) * (num_4x4_in_row >> 3);
|
|
|
|
/* -------- Compute four 8x8 HAD Transforms of 16x16 call--------- */
|
|
best_cost_tu_split = ps_func_selector->pf_had_16x16_r(
|
|
pu1_src0,
|
|
src_strd,
|
|
pu1_pred0,
|
|
pred_strd,
|
|
pi2_y0,
|
|
32,
|
|
ppi4_hsad,
|
|
ppi4_tu_split,
|
|
ppi4_tu_early_cbf,
|
|
pos_x_y_4x4,
|
|
num_4x4_in_row,
|
|
lambda,
|
|
lambda_q_shift,
|
|
i4_frm_qstep,
|
|
i4_cur_depth + 1,
|
|
i4_max_depth,
|
|
i4_max_tr_size,
|
|
pi4_tu_split_cost,
|
|
NULL);
|
|
|
|
/* cost is shifted by 10bits */
|
|
best_cost = best_cost_tu_split >> 10;
|
|
|
|
/* Tu split is present in the 6-10 bits */
|
|
tu_split_flag += (best_cost_tu_split & 0x3E0) >> 5;
|
|
|
|
/*Early CBF info is present in the last 5 bits */
|
|
i4_early_cbf_flag += best_cost_tu_split & 0x1F;
|
|
|
|
tu_split_flag <<= 5;
|
|
i4_early_cbf_flag <<= 5;
|
|
|
|
cost_child += best_cost;
|
|
|
|
best_cost_tu_split = ps_func_selector->pf_had_16x16_r(
|
|
pu1_src1,
|
|
src_strd,
|
|
pu1_pred1,
|
|
pred_strd,
|
|
pi2_y1,
|
|
32,
|
|
ppi4_hsad,
|
|
ppi4_tu_split,
|
|
ppi4_tu_early_cbf,
|
|
pos_x_y_4x4 + 4,
|
|
num_4x4_in_row,
|
|
lambda,
|
|
lambda_q_shift,
|
|
i4_frm_qstep,
|
|
i4_cur_depth + 1,
|
|
i4_max_depth,
|
|
i4_max_tr_size,
|
|
pi4_tu_split_cost,
|
|
NULL);
|
|
|
|
/* cost is shifted by 10bits */
|
|
best_cost = best_cost_tu_split >> 10;
|
|
|
|
/* Tu split is present in the 6-10 bits */
|
|
tu_split_flag += (best_cost_tu_split & 0x3E0) >> 5;
|
|
|
|
/*Early CBF info is present in the last 5 bits */
|
|
i4_early_cbf_flag += best_cost_tu_split & 0x1F;
|
|
|
|
tu_split_flag <<= 5;
|
|
i4_early_cbf_flag <<= 5;
|
|
|
|
cost_child += best_cost;
|
|
|
|
best_cost_tu_split = ps_func_selector->pf_had_16x16_r(
|
|
pu1_src2,
|
|
src_strd,
|
|
pu1_pred2,
|
|
pred_strd,
|
|
pi2_y2,
|
|
32,
|
|
ppi4_hsad,
|
|
ppi4_tu_split,
|
|
ppi4_tu_early_cbf,
|
|
pos_x_y_4x4 + (4 << 16),
|
|
num_4x4_in_row,
|
|
lambda,
|
|
lambda_q_shift,
|
|
i4_frm_qstep,
|
|
i4_cur_depth + 1,
|
|
i4_max_depth,
|
|
i4_max_tr_size,
|
|
pi4_tu_split_cost,
|
|
NULL);
|
|
|
|
/* cost is shifted by 10bits */
|
|
best_cost = best_cost_tu_split >> 10;
|
|
|
|
/* Tu split is present in the 6-10 bits */
|
|
tu_split_flag += (best_cost_tu_split & 0x3E0) >> 5;
|
|
|
|
/*Early CBF info is present in the last 5 bits */
|
|
i4_early_cbf_flag += best_cost_tu_split & 0x1F;
|
|
|
|
tu_split_flag <<= 5;
|
|
i4_early_cbf_flag <<= 5;
|
|
|
|
cost_child += best_cost;
|
|
|
|
best_cost_tu_split = ps_func_selector->pf_had_16x16_r(
|
|
pu1_src3,
|
|
src_strd,
|
|
pu1_pred3,
|
|
pred_strd,
|
|
pi2_y3,
|
|
32,
|
|
ppi4_hsad,
|
|
ppi4_tu_split,
|
|
ppi4_tu_early_cbf,
|
|
pos_x_y_4x4 + (4 << 16) + 4,
|
|
num_4x4_in_row,
|
|
lambda,
|
|
lambda_q_shift,
|
|
i4_frm_qstep,
|
|
i4_cur_depth + 1,
|
|
i4_max_depth,
|
|
i4_max_tr_size,
|
|
pi4_tu_split_cost,
|
|
NULL);
|
|
|
|
/* cost is shifted by 10bits */
|
|
best_cost = best_cost_tu_split >> 10;
|
|
|
|
/* Tu split is present in the 6-10 bits */
|
|
tu_split_flag += (best_cost_tu_split & 0x3E0) >> 5;
|
|
|
|
/*Early CBF info is present in the last 5 bits */
|
|
i4_early_cbf_flag += best_cost_tu_split & 0x1F;
|
|
|
|
tu_split_flag <<= 1;
|
|
i4_early_cbf_flag <<= 1;
|
|
|
|
cost_child += best_cost;
|
|
|
|
{
|
|
UWORD32 u4_satd = 0;
|
|
|
|
u4_satd = ps_func_selector->pf_compute_32x32HAD_using_16x16(
|
|
pi2_y0, 32, pi2_dst, dst_strd, i4_frm_qstep, &early_cbf);
|
|
|
|
cost_parent = ((u4_satd + 2) >> 2);
|
|
}
|
|
|
|
/* 4 TU_Split flags , 4 CBF Flags*/
|
|
cost_child += ((4 + 4) * lambda) >> (lambda_q_shift + 1);
|
|
|
|
i4_early_cbf_flag += early_cbf;
|
|
|
|
/* 1 TU_SPlit flag, 1 CBF flag */
|
|
//cost_parent += ((1 + 1)* lambda) >> (lambda_q_shift + 1);
|
|
|
|
if(i4_cur_depth < i4_max_depth)
|
|
{
|
|
if((cost_child < cost_parent) || (u1_cur_tr_size > i4_max_tr_size))
|
|
{
|
|
*pi4_tu_split_cost += ((4 + 4) * lambda) >> (lambda_q_shift + 1);
|
|
best_cost = cost_child;
|
|
tu_split_flag++;
|
|
}
|
|
else
|
|
{
|
|
tu_split_flag = 0;
|
|
best_cost = cost_parent;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tu_split_flag = 0;
|
|
best_cost = cost_parent;
|
|
}
|
|
|
|
pi4_32x32_tu_split[0] = tu_split_flag;
|
|
|
|
pi4_32x32_hsad[0] = best_cost;
|
|
|
|
pi4_32x32_tu_early_cbf[0] = i4_early_cbf_flag;
|
|
}
|