559 lines
14 KiB
C
559 lines
14 KiB
C
/******************************************************************************
|
|
*
|
|
* 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_chroma_had_satd.c
|
|
*
|
|
* \brief
|
|
* This file contains function definitions of chroma HAD SATD functions
|
|
*
|
|
* \date
|
|
* 15/07/2013
|
|
*
|
|
* \author
|
|
* Ittiam
|
|
*
|
|
* List of Functions
|
|
* ihevce_chroma_HAD_4x4_8b()
|
|
* ihevce_chroma_compute_AC_HAD_4x4_8bit()
|
|
* ihevce_hbd_chroma_HAD_4x4()
|
|
* ihevce_hbd_chroma_compute_AC_HAD_4x4()
|
|
* ihevce_chroma_HAD_8x8_8bit()
|
|
* ihevce_hbd_chroma_HAD_8x8()
|
|
* ihevce_chroma_HAD_16x16_8bit()
|
|
* ihevce_hbd_chroma_HAD_16x16()
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* 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 "ihevc_debug.h"
|
|
#include "itt_video_api.h"
|
|
|
|
#include "ihevce_api.h"
|
|
#include "ihevce_defs.h"
|
|
#include "ihevce_had_satd.h"
|
|
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Chroma Hadamard Transform of 4x4 block (8-bit input)
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the source block (u or v, interleaved)
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block (u or v, interleaved)
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd (u or v, interleaved)
|
|
* WORD32 Destination stride
|
|
*
|
|
* @returns
|
|
* Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_chroma_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 diff[16], m[16], d[16];
|
|
UWORD32 u4_sad = 0;
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
for(k = 0; k < 16; k += 4)
|
|
{
|
|
/* u or v, interleaved */
|
|
diff[k + 0] = pu1_origin[2 * 0] - pu1_pred_buf[2 * 0];
|
|
diff[k + 1] = pu1_origin[2 * 1] - pu1_pred_buf[2 * 1];
|
|
diff[k + 2] = pu1_origin[2 * 2] - pu1_pred_buf[2 * 2];
|
|
diff[k + 3] = pu1_origin[2 * 3] - pu1_pred_buf[2 * 3];
|
|
|
|
pu1_pred_buf += pred_strd;
|
|
pu1_origin += src_strd;
|
|
}
|
|
|
|
/*===== hadamard transform =====*/
|
|
m[0] = diff[0] + diff[12];
|
|
m[1] = diff[1] + diff[13];
|
|
m[2] = diff[2] + diff[14];
|
|
m[3] = diff[3] + diff[15];
|
|
m[4] = diff[4] + diff[8];
|
|
m[5] = diff[5] + diff[9];
|
|
m[6] = diff[6] + diff[10];
|
|
m[7] = diff[7] + diff[11];
|
|
m[8] = diff[4] - diff[8];
|
|
m[9] = diff[5] - diff[9];
|
|
m[10] = diff[6] - diff[10];
|
|
m[11] = diff[7] - diff[11];
|
|
m[12] = diff[0] - diff[12];
|
|
m[13] = diff[1] - diff[13];
|
|
m[14] = diff[2] - diff[14];
|
|
m[15] = diff[3] - diff[15];
|
|
|
|
d[0] = m[0] + m[4];
|
|
d[1] = m[1] + m[5];
|
|
d[2] = m[2] + m[6];
|
|
d[3] = m[3] + m[7];
|
|
d[4] = m[8] + m[12];
|
|
d[5] = m[9] + m[13];
|
|
d[6] = m[10] + m[14];
|
|
d[7] = m[11] + m[15];
|
|
d[8] = m[0] - m[4];
|
|
d[9] = m[1] - m[5];
|
|
d[10] = m[2] - m[6];
|
|
d[11] = m[3] - m[7];
|
|
d[12] = m[12] - m[8];
|
|
d[13] = m[13] - m[9];
|
|
d[14] = m[14] - m[10];
|
|
d[15] = m[15] - m[11];
|
|
|
|
m[0] = d[0] + d[3];
|
|
m[1] = d[1] + d[2];
|
|
m[2] = d[1] - d[2];
|
|
m[3] = d[0] - d[3];
|
|
m[4] = d[4] + d[7];
|
|
m[5] = d[5] + d[6];
|
|
m[6] = d[5] - d[6];
|
|
m[7] = d[4] - d[7];
|
|
m[8] = d[8] + d[11];
|
|
m[9] = d[9] + d[10];
|
|
m[10] = d[9] - d[10];
|
|
m[11] = d[8] - d[11];
|
|
m[12] = d[12] + d[15];
|
|
m[13] = d[13] + d[14];
|
|
m[14] = d[13] - d[14];
|
|
m[15] = d[12] - d[15];
|
|
|
|
d[0] = m[0] + m[1];
|
|
d[1] = m[0] - m[1];
|
|
d[2] = m[2] + m[3];
|
|
d[3] = m[3] - m[2];
|
|
d[4] = m[4] + m[5];
|
|
d[5] = m[4] - m[5];
|
|
d[6] = m[6] + m[7];
|
|
d[7] = m[7] - m[6];
|
|
d[8] = m[8] + m[9];
|
|
d[9] = m[8] - m[9];
|
|
d[10] = m[10] + m[11];
|
|
d[11] = m[11] - m[10];
|
|
d[12] = m[12] + m[13];
|
|
d[13] = m[12] - m[13];
|
|
d[14] = m[14] + m[15];
|
|
d[15] = m[15] - m[14];
|
|
|
|
/*===== sad =====*/
|
|
for(k = 0; k < 16; ++k)
|
|
{
|
|
u4_sad += (d[k] > 0 ? d[k] : -d[k]);
|
|
}
|
|
u4_sad = ((u4_sad + 2) >> 2);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Chroma Hadamard Transform of 4x4 block (8-bit input) with DC suppressed
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the source block (u or v, interleaved)
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block (u or v, interleaved)
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd (u or v, interleaved)
|
|
* WORD32 Destination stride
|
|
*
|
|
* @returns
|
|
* Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_chroma_compute_AC_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 diff[16], m[16], d[16];
|
|
UWORD32 u4_sad = 0;
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
for(k = 0; k < 16; k += 4)
|
|
{
|
|
/* u or v, interleaved */
|
|
diff[k + 0] = pu1_origin[2 * 0] - pu1_pred_buf[2 * 0];
|
|
diff[k + 1] = pu1_origin[2 * 1] - pu1_pred_buf[2 * 1];
|
|
diff[k + 2] = pu1_origin[2 * 2] - pu1_pred_buf[2 * 2];
|
|
diff[k + 3] = pu1_origin[2 * 3] - pu1_pred_buf[2 * 3];
|
|
|
|
pu1_pred_buf += pred_strd;
|
|
pu1_origin += src_strd;
|
|
}
|
|
|
|
/*===== hadamard transform =====*/
|
|
m[0] = diff[0] + diff[12];
|
|
m[1] = diff[1] + diff[13];
|
|
m[2] = diff[2] + diff[14];
|
|
m[3] = diff[3] + diff[15];
|
|
m[4] = diff[4] + diff[8];
|
|
m[5] = diff[5] + diff[9];
|
|
m[6] = diff[6] + diff[10];
|
|
m[7] = diff[7] + diff[11];
|
|
m[8] = diff[4] - diff[8];
|
|
m[9] = diff[5] - diff[9];
|
|
m[10] = diff[6] - diff[10];
|
|
m[11] = diff[7] - diff[11];
|
|
m[12] = diff[0] - diff[12];
|
|
m[13] = diff[1] - diff[13];
|
|
m[14] = diff[2] - diff[14];
|
|
m[15] = diff[3] - diff[15];
|
|
|
|
d[0] = m[0] + m[4];
|
|
d[1] = m[1] + m[5];
|
|
d[2] = m[2] + m[6];
|
|
d[3] = m[3] + m[7];
|
|
d[4] = m[8] + m[12];
|
|
d[5] = m[9] + m[13];
|
|
d[6] = m[10] + m[14];
|
|
d[7] = m[11] + m[15];
|
|
d[8] = m[0] - m[4];
|
|
d[9] = m[1] - m[5];
|
|
d[10] = m[2] - m[6];
|
|
d[11] = m[3] - m[7];
|
|
d[12] = m[12] - m[8];
|
|
d[13] = m[13] - m[9];
|
|
d[14] = m[14] - m[10];
|
|
d[15] = m[15] - m[11];
|
|
|
|
m[0] = d[0] + d[3];
|
|
m[1] = d[1] + d[2];
|
|
m[2] = d[1] - d[2];
|
|
m[3] = d[0] - d[3];
|
|
m[4] = d[4] + d[7];
|
|
m[5] = d[5] + d[6];
|
|
m[6] = d[5] - d[6];
|
|
m[7] = d[4] - d[7];
|
|
m[8] = d[8] + d[11];
|
|
m[9] = d[9] + d[10];
|
|
m[10] = d[9] - d[10];
|
|
m[11] = d[8] - d[11];
|
|
m[12] = d[12] + d[15];
|
|
m[13] = d[13] + d[14];
|
|
m[14] = d[13] - d[14];
|
|
m[15] = d[12] - d[15];
|
|
|
|
d[0] = m[0] + m[1];
|
|
d[1] = m[0] - m[1];
|
|
d[2] = m[2] + m[3];
|
|
d[3] = m[3] - m[2];
|
|
d[4] = m[4] + m[5];
|
|
d[5] = m[4] - m[5];
|
|
d[6] = m[6] + m[7];
|
|
d[7] = m[7] - m[6];
|
|
d[8] = m[8] + m[9];
|
|
d[9] = m[8] - m[9];
|
|
d[10] = m[10] + m[11];
|
|
d[11] = m[11] - m[10];
|
|
d[12] = m[12] + m[13];
|
|
d[13] = m[12] - m[13];
|
|
d[14] = m[14] + m[15];
|
|
d[15] = m[15] - m[14];
|
|
|
|
/* DC masking */
|
|
d[0] = 0;
|
|
|
|
/*===== sad =====*/
|
|
for(k = 0; k < 16; ++k)
|
|
{
|
|
u4_sad += (d[k] > 0 ? d[k] : -d[k]);
|
|
}
|
|
u4_sad = ((u4_sad + 2) >> 2);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Chroma Hadamard Transform of 8x8 block (8-bit input)
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the source block (u or v, interleaved)
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block (u or v, interleaved)
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd (u or v, interleaved)
|
|
* WORD32 Destination stride
|
|
*
|
|
* @returns
|
|
* Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_chroma_HAD_8x8_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
WORD32 k, i, j, jj;
|
|
UWORD32 u4_sad = 0;
|
|
WORD16 diff[64], m1[8][8], m2[8][8], m3[8][8];
|
|
|
|
(void)pi2_dst;
|
|
(void)dst_strd;
|
|
for(k = 0; k < 64; k += 8)
|
|
{
|
|
/* u or v, interleaved */
|
|
diff[k + 0] = pu1_origin[2 * 0] - pu1_pred_buf[2 * 0];
|
|
diff[k + 1] = pu1_origin[2 * 1] - pu1_pred_buf[2 * 1];
|
|
diff[k + 2] = pu1_origin[2 * 2] - pu1_pred_buf[2 * 2];
|
|
diff[k + 3] = pu1_origin[2 * 3] - pu1_pred_buf[2 * 3];
|
|
diff[k + 4] = pu1_origin[2 * 4] - pu1_pred_buf[2 * 4];
|
|
diff[k + 5] = pu1_origin[2 * 5] - pu1_pred_buf[2 * 5];
|
|
diff[k + 6] = pu1_origin[2 * 6] - pu1_pred_buf[2 * 6];
|
|
diff[k + 7] = pu1_origin[2 * 7] - pu1_pred_buf[2 * 7];
|
|
|
|
pu1_pred_buf += pred_strd;
|
|
pu1_origin += src_strd;
|
|
}
|
|
|
|
/*===== hadamard transform =====*/
|
|
// horizontal
|
|
for(j = 0; j < 8; j++)
|
|
{
|
|
jj = j << 3;
|
|
m2[j][0] = diff[jj] + diff[jj + 4];
|
|
m2[j][1] = diff[jj + 1] + diff[jj + 5];
|
|
m2[j][2] = diff[jj + 2] + diff[jj + 6];
|
|
m2[j][3] = diff[jj + 3] + diff[jj + 7];
|
|
m2[j][4] = diff[jj] - diff[jj + 4];
|
|
m2[j][5] = diff[jj + 1] - diff[jj + 5];
|
|
m2[j][6] = diff[jj + 2] - diff[jj + 6];
|
|
m2[j][7] = diff[jj + 3] - diff[jj + 7];
|
|
|
|
m1[j][0] = m2[j][0] + m2[j][2];
|
|
m1[j][1] = m2[j][1] + m2[j][3];
|
|
m1[j][2] = m2[j][0] - m2[j][2];
|
|
m1[j][3] = m2[j][1] - m2[j][3];
|
|
m1[j][4] = m2[j][4] + m2[j][6];
|
|
m1[j][5] = m2[j][5] + m2[j][7];
|
|
m1[j][6] = m2[j][4] - m2[j][6];
|
|
m1[j][7] = m2[j][5] - m2[j][7];
|
|
|
|
m2[j][0] = m1[j][0] + m1[j][1];
|
|
m2[j][1] = m1[j][0] - m1[j][1];
|
|
m2[j][2] = m1[j][2] + m1[j][3];
|
|
m2[j][3] = m1[j][2] - m1[j][3];
|
|
m2[j][4] = m1[j][4] + m1[j][5];
|
|
m2[j][5] = m1[j][4] - m1[j][5];
|
|
m2[j][6] = m1[j][6] + m1[j][7];
|
|
m2[j][7] = m1[j][6] - m1[j][7];
|
|
}
|
|
|
|
// vertical
|
|
for(i = 0; i < 8; i++)
|
|
{
|
|
m3[0][i] = m2[0][i] + m2[4][i];
|
|
m3[1][i] = m2[1][i] + m2[5][i];
|
|
m3[2][i] = m2[2][i] + m2[6][i];
|
|
m3[3][i] = m2[3][i] + m2[7][i];
|
|
m3[4][i] = m2[0][i] - m2[4][i];
|
|
m3[5][i] = m2[1][i] - m2[5][i];
|
|
m3[6][i] = m2[2][i] - m2[6][i];
|
|
m3[7][i] = m2[3][i] - m2[7][i];
|
|
|
|
m1[0][i] = m3[0][i] + m3[2][i];
|
|
m1[1][i] = m3[1][i] + m3[3][i];
|
|
m1[2][i] = m3[0][i] - m3[2][i];
|
|
m1[3][i] = m3[1][i] - m3[3][i];
|
|
m1[4][i] = m3[4][i] + m3[6][i];
|
|
m1[5][i] = m3[5][i] + m3[7][i];
|
|
m1[6][i] = m3[4][i] - m3[6][i];
|
|
m1[7][i] = m3[5][i] - m3[7][i];
|
|
|
|
m2[0][i] = m1[0][i] + m1[1][i];
|
|
m2[1][i] = m1[0][i] - m1[1][i];
|
|
m2[2][i] = m1[2][i] + m1[3][i];
|
|
m2[3][i] = m1[2][i] - m1[3][i];
|
|
m2[4][i] = m1[4][i] + m1[5][i];
|
|
m2[5][i] = m1[4][i] - m1[5][i];
|
|
m2[6][i] = m1[6][i] + m1[7][i];
|
|
m2[7][i] = m1[6][i] - m1[7][i];
|
|
}
|
|
|
|
/*===== sad =====*/
|
|
for(i = 0; i < 8; i++)
|
|
{
|
|
for(j = 0; j < 8; j++)
|
|
{
|
|
u4_sad += (m2[i][j] > 0 ? m2[i][j] : -m2[i][j]);
|
|
}
|
|
}
|
|
u4_sad = ((u4_sad + 4) >> 3);
|
|
|
|
return u4_sad;
|
|
}
|
|
|
|
/**
|
|
*******************************************************************************
|
|
*
|
|
* @brief
|
|
* Chroma Hadamard Transform of 16x16 block (8-bit input)
|
|
*
|
|
* @par Description:
|
|
*
|
|
* @param[in] pu1_origin
|
|
* UWORD8 pointer to the source block (u or v, interleaved)
|
|
*
|
|
* @param[in] src_strd
|
|
* WORD32 Source stride
|
|
*
|
|
* @param[in] pu1_pred_buf
|
|
* UWORD8 pointer to the prediction block (u or v, interleaved)
|
|
*
|
|
* @param[in] pred_strd
|
|
* WORD32 Pred stride
|
|
*
|
|
* @param[in] pi2_dst
|
|
* WORD16 pointer to the transform block
|
|
*
|
|
* @param[in] dst_strd (u or v, interleaved)
|
|
* WORD32 Destination stride
|
|
*
|
|
* @returns
|
|
* Hadamard SAD
|
|
*
|
|
* @remarks
|
|
* Not updating the transform destination now. Only returning the SATD
|
|
*
|
|
*******************************************************************************
|
|
*/
|
|
UWORD32 ihevce_chroma_HAD_16x16_8bit(
|
|
UWORD8 *pu1_origin,
|
|
WORD32 src_strd,
|
|
UWORD8 *pu1_pred_buf,
|
|
WORD32 pred_strd,
|
|
WORD16 *pi2_dst,
|
|
WORD32 dst_strd)
|
|
{
|
|
UWORD32 au4_sad[4], u4_result = 0;
|
|
WORD32 i;
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
au4_sad[i] = ihevce_chroma_HAD_8x8_8bit(
|
|
pu1_origin, src_strd, pu1_pred_buf, pred_strd, pi2_dst, dst_strd);
|
|
|
|
if(i == 0 || i == 2)
|
|
{
|
|
pu1_origin += 16;
|
|
pu1_pred_buf += 16;
|
|
}
|
|
|
|
if(i == 1)
|
|
{
|
|
pu1_origin += (8 * src_strd) - 16;
|
|
pu1_pred_buf += (8 * pred_strd) - 16;
|
|
}
|
|
|
|
u4_result += au4_sad[i];
|
|
}
|
|
|
|
return u4_result;
|
|
}
|