blob: 480a8c7c603318c5040cdeabc3e441a118545ea6 [file] [log] [blame]
/******************************************************************************
*
* 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 Name : ih264_inter_pred_filters_intr_ssse3.c */
/* */
/* Description : Contains function definitions for weighted */
/* prediction functions in x86 sse4 intrinsics */
/* */
/* List of Functions : ih264_inter_pred_luma_copy_ssse3() */
/* ih264_inter_pred_luma_horz_ssse3() */
/* ih264_inter_pred_luma_vert_ssse3() */
/* ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3() */
/* ih264_inter_pred_luma_horz_qpel_ssse3() */
/* ih264_inter_pred_luma_vert_qpel_ssse3() */
/* ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3() */
/* ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3() */
/* ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3() */
/* ih264_inter_pred_chroma_ssse3() */
/* */
/* Issues / Problems : None */
/* */
/* Revision History : */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial version */
/* Senthoor */
/* */
/*****************************************************************************/
/*****************************************************************************/
/* File Includes */
/*****************************************************************************/
#include <immintrin.h>
#include "ih264_typedefs.h"
#include "ih264_macros.h"
#include "ih264_platform_macros.h"
#include "ih264_inter_pred_filters.h"
/*****************************************************************************/
/* Constant Data variables */
/*****************************************************************************/
/* coefficients for 6 tap filtering*/
//const WORD32 ih264_g_six_tap[3] ={1,-5,20};
/*****************************************************************************/
/* Function definitions . */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_copy_ssse3 */
/* */
/* Description : This function copies the contents of ht x wd block from */
/* source to destination. (ht,wd) can be (4,4), (8,4), */
/* (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_copy_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
__m128i y_0_16x8b, y_1_16x8b, y_2_16x8b, y_3_16x8b;
WORD32 src_strd2, src_strd3, src_strd4, dst_strd2, dst_strd3, dst_strd4;
UNUSED(pu1_tmp);
UNUSED(dydx);
src_strd2 = src_strd << 1;
dst_strd2 = dst_strd << 1;
src_strd4 = src_strd << 2;
dst_strd4 = dst_strd << 2;
src_strd3 = src_strd2 + src_strd;
dst_strd3 = dst_strd2 + dst_strd;
if(wd == 4)
{
do
{
*((WORD32 *)(pu1_dst)) = *((WORD32 *)(pu1_src));
*((WORD32 *)(pu1_dst + dst_strd)) = *((WORD32 *)(pu1_src + src_strd));
*((WORD32 *)(pu1_dst + dst_strd2)) = *((WORD32 *)(pu1_src + src_strd2));
*((WORD32 *)(pu1_dst + dst_strd3)) = *((WORD32 *)(pu1_src + src_strd3));
ht -= 4;
pu1_src += src_strd4;
pu1_dst += dst_strd4;
}
while(ht > 0);
}
else if(wd == 8)
{
do
{
y_0_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
y_1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
y_2_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd2));
y_3_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd3));
_mm_storel_epi64((__m128i *)pu1_dst, y_0_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), y_1_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd2), y_2_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd3), y_3_16x8b);
ht -= 4;
pu1_src += src_strd4;
pu1_dst += dst_strd4;
}
while(ht > 0);
}
else // wd == 16
{
WORD32 src_strd5, src_strd6, src_strd7, src_strd8;
WORD32 dst_strd5, dst_strd6, dst_strd7, dst_strd8;
__m128i y_4_16x8b, y_5_16x8b, y_6_16x8b, y_7_16x8b;
src_strd5 = src_strd2 + src_strd3;
dst_strd5 = dst_strd2 + dst_strd3;
src_strd6 = src_strd3 << 1;
dst_strd6 = dst_strd3 << 1;
src_strd7 = src_strd3 + src_strd4;
dst_strd7 = dst_strd3 + dst_strd4;
src_strd8 = src_strd << 3;
dst_strd8 = dst_strd << 3;
do
{
y_0_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
y_1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd));
y_2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd2));
y_3_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd3));
y_4_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd4));
y_5_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd5));
y_6_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd6));
y_7_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd7));
_mm_storeu_si128((__m128i *)pu1_dst, y_0_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd), y_1_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd2), y_2_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd3), y_3_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd4), y_4_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd5), y_5_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd6), y_6_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd7), y_7_16x8b);
ht -= 8;
pu1_src += src_strd8;
pu1_dst += dst_strd8;
}
while(ht > 0);
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_ssse3 */
/* */
/* Description : This function applies a horizontal 6-tap filter on */
/* ht x wd block as mentioned in sec. 8.4.2.2.1 titled */
/* "Luma sample interpolation process". (ht,wd) can be */
/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
__m128i const_val16_8x16b;
UNUSED(pu1_tmp);
UNUSED(dydx);
pu1_src -= 2; // the filter input starts from x[-2] (till x[3])
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
const_val16_8x16b = _mm_set1_epi16(16);
if(wd == 4)
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0r1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i res_r0r1_t1_8x16b, res_r0r1_t2_8x16b, res_r0r1_t3_8x16b;
__m128i res_r0r1_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 b0 b1 b1 b2 b2 b3 b3 b4
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 b2 b3 b3 b4 b4 b5 b5 b6
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//b2*c2+b3*c3 b3*c2+b4*c3 b4*c2+b5*c3 b5*c2+b6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0 0 0 0 0
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 b4 b5 b5 b6 b6 b7 b7 b8
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//b4*c4+b5*c5 b5*c4+b6*c5 b4*c6+b7*c5 b7*c4+b8*c5
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0r1_t3_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t3_8x16b); //a0*c0+a1*c1+a2*c2+a3*c3+a4*a4+a5*c5 + 16;
//a1*c0+a2*c1+a2*c2+a3*c3+a5*a4+a6*c5 + 16;
//a2*c0+a3*c1+a4*c2+a5*c3+a6*a4+a7*c5 + 16;
//a3*c0+a4*c1+a5*c2+a6*c3+a6*a4+a8*c5 + 16;
//b0*c0+b1*c1+b2*c2+b3*c3+b4*b4+b5*c5 + 16;
//b1*c0+b2*c1+b2*c2+b3*c3+b5*b4+b6*c5 + 16;
//b2*c0+b3*c1+b4*c2+b5*c3+b6*b4+b7*c5 + 16;
//b3*c0+b4*c1+b5*c2+b6*c3+b6*b4+b8*c5 + 16;
res_r0r1_t1_8x16b = _mm_srai_epi16(res_r0r1_t1_8x16b, 5); //shifting right by 5 bits.
res_r0r1_16x8b = _mm_packus_epi16(res_r0r1_t1_8x16b, res_r0r1_t1_8x16b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
res_r0r1_16x8b = _mm_srli_si128(res_r0r1_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else if(wd == 8)
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(res_r0_t3_8x16b, const_val16_8x16b);
res_r1_t3_8x16b = _mm_add_epi16(res_r1_t3_8x16b, const_val16_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5); //shifting right by 5 bits.
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5);
src_r0_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r0_t1_8x16b);
src_r1_16x8b = _mm_packus_epi16(res_r1_t1_8x16b, res_r1_t1_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst, src_r0_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), src_r1_16x8b);
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else // wd == 16
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row0 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
//b0 is same a8. Similarly other bn pixels are same as a(n+8) pixels.
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(res_r0_t3_8x16b, const_val16_8x16b);
res_r1_t3_8x16b = _mm_add_epi16(res_r1_t3_8x16b, const_val16_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5); //shifting right by 5 bits.
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5);
src_r0_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r1_t1_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, src_r0_16x8b);
ht--;
pu1_src += src_strd;
pu1_dst += dst_strd;
}
while(ht > 0);
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_vert_ssse3 */
/* */
/* Description : This function applies a vertical 6-tap filter on */
/* ht x wd block as mentioned in sec. 8.4.2.2.1 titled */
/* "Luma sample interpolation process". (ht,wd) can be */
/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_vert_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b, src_r4_16x8b;
__m128i src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_16x8b, res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
__m128i const_val16_8x16b;
UNUSED(pu1_tmp);
UNUSED(dydx);
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
const_val16_8x16b = _mm_set1_epi16(16);
pu1_src -= src_strd << 1; // the filter input starts from x[-2] (till x[3])
if(wd == 4)
{
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r0_16x8b = _mm_unpacklo_epi32(src_r0_16x8b, src_r1_16x8b);
src_r1_16x8b = _mm_unpacklo_epi32(src_r1_16x8b, src_r2_16x8b);
src_r2_16x8b = _mm_unpacklo_epi32(src_r2_16x8b, src_r3_16x8b);
src_r3_16x8b = _mm_unpacklo_epi32(src_r3_16x8b, src_r4_16x8b);
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
src_r4_16x8b = _mm_unpacklo_epi32(src_r4_16x8b, src_r5_16x8b);
src_r5_16x8b = _mm_unpacklo_epi32(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_16x8b);
res_16x8b = _mm_srli_si128(res_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else if(wd == 8)
{
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r0_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b);
src_r1_16x8b = _mm_unpacklo_epi64(src_r1_16x8b, src_r2_16x8b);
src_r2_16x8b = _mm_unpacklo_epi64(src_r2_16x8b, src_r3_16x8b);
src_r3_16x8b = _mm_unpacklo_epi64(src_r3_16x8b, src_r4_16x8b);
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
src_r4_16x8b = _mm_unpacklo_epi64(src_r4_16x8b, src_r5_16x8b);
src_r5_16x8b = _mm_unpacklo_epi64(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst, res_16x8b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else // wd == 16
{
__m128i res_t0_8x16b;
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
do
{
src_r5_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(res_t3_8x16b, const_val16_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3 */
/* */
/* Description : This function implements a two stage cascaded six tap */
/* filter, horizontally and then vertically on ht x wd */
/* block as mentioned in sec. 8.4.2.2.1 titled "Luma sample */
/* interpolation process". (ht,wd) can be (4,4), (8,4), */
/* (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
UNUSED(dydx);
if(wd == 4)
{
WORD16 *pi2_temp;
pu1_tmp += 4;
pu1_src -= src_strd << 1;
pi2_temp = (WORD16 *)pu1_tmp;
pu1_src -= 2; // the filter input starts from x[-2] (till x[3])
// Horizontal 6-tap filtering
{
WORD32 ht_tmp = ht + 4;
__m128i src_r0_16x8b, src_r1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0r1_t1_16x8b;
__m128i res_r0r1_t1_8x16b, res_r0r1_t2_8x16b, res_r0r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 b0 b1 b1 b2 b2 b3 b3 b4
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 b2 b3 b3 b4 b4 b5 b5 b6
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//b2*c2+b3*c3 b3*c2+b4*c3 b4*c2+b5*c3 b5*c2+b6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 b4 b5 b5 b6 b6 b7 b7 b8
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//b4*c4+b5*c5 b5*c4+b6*c5 b4*c6+b7*c5 b7*c4+b8*c5
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t3_8x16b, res_r0r1_t1_8x16b);
_mm_storeu_si128((__m128i *)pi2_temp, res_r0r1_t1_8x16b);
ht_tmp -= 2;
pu1_src += src_strd << 1;
pi2_temp += 8;
}
while(ht_tmp > 0);
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b,4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b,4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t3_8x16b, res_r0r1_t1_8x16b);
_mm_storel_epi64((__m128i *)pi2_temp, res_r0r1_t1_8x16b);
}
pi2_temp = (WORD16 *)pu1_tmp;
// Vertical 6-tap filtering
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b,
src_r4_8x16b;
__m128i src_r5_8x16b, src_r6_8x16b;
__m128i src_t1_8x16b, src_t2_8x16b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
src_r0_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp));
src_r1_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp + 4));
src_r2_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp + 8));
src_r3_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp + 12));
src_r4_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp + 16));
pi2_temp += 20;
do
{
src_r5_8x16b = _mm_loadl_epi64((__m128i *)pi2_temp);
src_r6_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp + 4));
src_r0_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_t1_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_t2_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_t1_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_t2_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_t1_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_t2_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_t1_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_t2_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_16x8b);
res_16x8b = _mm_srli_si128(res_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp += 8;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
}
else if(wd == 8)
{
WORD16 *pi2_temp;
pu1_tmp += 4;
pu1_src -= src_strd << 1;
pi2_temp = (WORD16 *)pu1_tmp;
pu1_src -= 2; // the filter input starts from x[-2] (till x[3])
// Horizontal 6-tap filtering
{
WORD32 ht_tmp = ht + 4;
__m128i src_r0_16x8b, src_r1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
_mm_storeu_si128((__m128i *)pi2_temp, res_r0_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp + 8), res_r1_t1_8x16b);
ht_tmp -= 2;
pu1_src += src_strd << 1;
pi2_temp += 16;
}
while(ht_tmp > 0);
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b,src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b,coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
_mm_storeu_si128((__m128i *)pi2_temp, res_r0_t1_8x16b);
}
pi2_temp = (WORD16 *)pu1_tmp;
// Vertical 6-tap filtering
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b,
src_r4_8x16b;
__m128i src_r5_8x16b, src_r6_8x16b;
__m128i src_r0r1_8x16b, src_r2r3_8x16b, src_r4r5_8x16b;
__m128i res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_c0_4x32b, res_c1_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
src_r0_8x16b = _mm_loadu_si128((__m128i *)pi2_temp);
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 8));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 16));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 24));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 32));
pi2_temp += 40;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)pi2_temp);
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 8));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst, res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp += 16;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
}
else // wd == 16
{
WORD16 *pi2_temp;
WORD32 ht_tmp;
pu1_tmp += 4;
pu1_src -= src_strd << 1;
pi2_temp = (WORD16 *)pu1_tmp;
pu1_src -= 2; // the filter input starts from x[-2] (till x[3])
// Horizontal 6-tap filtering
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
ht_tmp = ht + 5;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row0 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
//b0 is same a8. Similarly other bn pixels are same as a(n+8) pixels.
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
_mm_storeu_si128((__m128i *)pi2_temp, res_r0_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp + 8), res_r1_t1_8x16b);
ht_tmp--;
pu1_src += src_strd;
pi2_temp += 16;
}
while(ht_tmp > 0);
}
pi2_temp = (WORD16 *)pu1_tmp;
// Vertical 6-tap filtering
{
WORD16 *pi2_temp2;
UWORD8 *pu1_dst2;
WORD32 ht_tmp;
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b, src_r4_8x16b;
__m128i src_r5_8x16b, src_r6_8x16b;
__m128i src_r0r1_8x16b, src_r2r3_8x16b, src_r4r5_8x16b;
__m128i res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_c0_4x32b, res_c1_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
pi2_temp2 = pi2_temp + 8;
pu1_dst2 = pu1_dst + 8;
ht_tmp = ht;
/**********************************************************/
/* Do first height x 8 block */
/**********************************************************/
src_r0_8x16b = _mm_loadu_si128((__m128i *)pi2_temp);
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 16));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 32));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 48));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 64));
pi2_temp += 80;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)pi2_temp);
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp + 16));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst, res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht_tmp -= 2;
pi2_temp += 32;
pu1_dst += dst_strd << 1;
}
while(ht_tmp > 0);
/**********************************************************/
/* Do second ht x 8 block */
/**********************************************************/
src_r0_8x16b = _mm_loadu_si128((__m128i *)pi2_temp2);
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 16));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 32));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 48));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 64));
pi2_temp2 += 80;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)pi2_temp2);
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 16));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst2, res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_c1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_c0_4x32b, res_c1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
_mm_storel_epi64((__m128i *)(pu1_dst2 + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp2 += 32;
pu1_dst2 += dst_strd << 1;
}
while(ht > 0);
}
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_qpel_ssse3 */
/* */
/* Description : This function implements a six-tap filter horizontally */
/* on ht x wd block and averages the values with the source */
/* pixels to calculate horizontal quarter-pel as mentioned */
/* in sec. 8.4.2.2.1 titled "Luma sample interpolation */
/* process". (ht,wd) can be (4,4), (8,4), (4,8), (8,8), */
/* (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* dydx - x and y reference offset for q-pel */
/* calculations */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_qpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
WORD32 x_offset;
UWORD8 *pu1_pred1;
__m128i src_r0_16x8b, src_r1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
__m128i const_val16_8x16b;
UNUSED(pu1_tmp);
x_offset = dydx & 3;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
pu1_pred1 = pu1_src + (x_offset >> 1);
const_val16_8x16b = _mm_set1_epi16(16);
pu1_src -= 2; // the filter input starts from x[-2] (till x[3])
if(wd == 4)
{
__m128i src_r0r1_16x8b;
__m128i res_r0r1_t1_8x16b, res_r0r1_t2_8x16b, res_r0r1_t3_8x16b;
__m128i res_r0r1_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 b0 b1 b1 b2 b2 b3 b3 b4
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 b2 b3 b3 b4 b4 b5 b5 b6
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//b2*c2+b3*c3 b3*c2+b4*c3 b4*c2+b5*c3 b5*c2+b6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0 0 0 0 0
src_r0r1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 b4 b5 b5 b6 b6 b7 b7 b8
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//b4*c4+b5*c5 b5*c4+b6*c5 b4*c6+b7*c5 b7*c4+b8*c5
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_pred1);
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred1 + src_strd));
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0r1_t3_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t3_8x16b); //a0*c0+a1*c1+a2*c2+a3*c3+a4*a4+a5*c5 + 16;
//a1*c0+a2*c1+a2*c2+a3*c3+a5*a4+a6*c5 + 16;
//a2*c0+a3*c1+a4*c2+a5*c3+a6*a4+a7*c5 + 16;
//a3*c0+a4*c1+a5*c2+a6*c3+a6*a4+a8*c5 + 16;
//b0*c0+b1*c1+b2*c2+b3*c3+b4*b4+b5*c5 + 16;
//b1*c0+b2*c1+b2*c2+b3*c3+b5*b4+b6*c5 + 16;
//b2*c0+b3*c1+b4*c2+b5*c3+b6*b4+b7*c5 + 16;
//b3*c0+b4*c1+b5*c2+b6*c3+b6*b4+b8*c5 + 16;
src_r0r1_16x8b = _mm_unpacklo_epi32(src_r0_16x8b,src_r1_16x8b);
res_r0r1_t1_8x16b = _mm_srai_epi16(res_r0r1_t1_8x16b, 5); //shifting right by 5 bits.
res_r0r1_16x8b = _mm_packus_epi16(res_r0r1_t1_8x16b, res_r0r1_t1_8x16b);
res_r0r1_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_r0r1_16x8b); //computing q-pel
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
res_r0r1_16x8b = _mm_srli_si128(res_r0r1_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
ht -= 2;
pu1_src += src_strd << 1;
pu1_pred1 += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else if(wd == 8)
{
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i res_r0_16x8b, res_r1_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_pred1);
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred1 + src_strd));
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0_t3_8x16b);
res_r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5);
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5); //shifting right by 5 bits.
res_r0_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r0_t1_8x16b);
res_r1_16x8b = _mm_packus_epi16(res_r1_t1_8x16b, res_r1_t1_8x16b);
res_r0_16x8b = _mm_avg_epu8(src_r0_16x8b, res_r0_16x8b);
res_r1_16x8b = _mm_avg_epu8(src_r1_16x8b, res_r1_16x8b); //computing q-pel
_mm_storel_epi64((__m128i *)pu1_dst, res_r0_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_r1_16x8b);
ht -= 2;
pu1_src += src_strd << 1;
pu1_pred1 += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else // wd == 16
{
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i res_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row0 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
//b0 is same a8. Similarly other bn pixels are same as a(n+8) pixels.
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_pred1);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0_t3_8x16b);
res_r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5);
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5); //shifting right by 5 bits
res_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r1_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0_16x8b, res_16x8b); //computing q-pel
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
ht--;
pu1_src += src_strd;
pu1_pred1 += src_strd;
pu1_dst += dst_strd;
}
while(ht > 0);
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_vert_qpel_ssse3 */
/* */
/* Description : This function implements a six-tap filter vertically on */
/* ht x wd block and averages the values with the source */
/* pixels to calculate vertical quarter-pel as mentioned in */
/* sec. 8.4.2.2.1 titled "Luma sample interpolation */
/* process". (ht,wd) can be (4,4), (8,4), (4,8), (8,8), */
/* (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* dydx - x and y reference offset for q-pel */
/* calculations */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_vert_qpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
WORD32 y_offset;
UWORD8 *pu1_pred1;
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b, src_r4_16x8b;
__m128i src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_16x8b, res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
__m128i const_val16_8x16b;
UNUSED(pu1_tmp);
y_offset = dydx & 0xf;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5 c4 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
pu1_pred1 = pu1_src + (y_offset >> 3) * src_strd;
const_val16_8x16b = _mm_set1_epi16(16);
pu1_src -= src_strd << 1; // the filter input starts from x[-2] (till x[3])
if(wd == 4)
{
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r0_16x8b = _mm_unpacklo_epi32(src_r0_16x8b, src_r1_16x8b);
src_r1_16x8b = _mm_unpacklo_epi32(src_r1_16x8b, src_r2_16x8b);
src_r2_16x8b = _mm_unpacklo_epi32(src_r2_16x8b, src_r3_16x8b);
src_r3_16x8b = _mm_unpacklo_epi32(src_r3_16x8b, src_r4_16x8b);
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
src_r4_16x8b = _mm_unpacklo_epi32(src_r4_16x8b, src_r5_16x8b);
src_r5_16x8b = _mm_unpacklo_epi32(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_pred1);
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred1 + src_strd));
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
src_r0r1_16x8b = _mm_unpacklo_epi32(src_r0_16x8b,src_r1_16x8b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_16x8b); //computing q-pel
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_16x8b);
res_16x8b = _mm_srli_si128(res_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_pred1 += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else if(wd == 8)
{
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
pu1_src += src_strd;
src_r0_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b);
src_r1_16x8b = _mm_unpacklo_epi64(src_r1_16x8b, src_r2_16x8b);
src_r2_16x8b = _mm_unpacklo_epi64(src_r2_16x8b, src_r3_16x8b);
src_r3_16x8b = _mm_unpacklo_epi64(src_r3_16x8b, src_r4_16x8b);
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src + src_strd));
src_r4_16x8b = _mm_unpacklo_epi64(src_r4_16x8b, src_r5_16x8b);
src_r5_16x8b = _mm_unpacklo_epi64(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
src_r0r1_16x8b = _mm_loadl_epi64((__m128i *)pu1_pred1);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_16x8b); //computing q-pel
_mm_storel_epi64((__m128i *)pu1_dst, res_16x8b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
src_r0r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred1 + src_strd));
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_16x8b); //computing q-pel
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_pred1 += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else // wd == 16
{
__m128i res_t0_8x16b;
//Epilogue: Load all the pred rows except sixth and seventh row
// for the first and second row processing.
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r1_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r2_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r3_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
src_r4_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
pu1_src += src_strd;
do
{
src_r5_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r6_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
src_r0r1_16x8b = _mm_loadu_si128((__m128i *)pu1_pred1);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_16x8b); //computing q-pel
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
src_r0r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred1 + src_strd));
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
res_16x8b = _mm_avg_epu8(src_r0r1_16x8b, res_16x8b); //computing q-pel
_mm_storeu_si128((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_pred1 += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3 */
/* */
/* Description : This function implements a six-tap filter vertically and */
/* horizontally on ht x wd block separately and averages */
/* the two sets of values to calculate values at (1/4,1/4), */
/* (1/4, 3/4), (3/4, 1/4) or (3/4, 3/4) as mentioned in */
/* sec. 8.4.2.2.1 titled "Luma sample interpolation */
/* process". (ht,wd) can be (4,4), (8,4), (4,8), (8,8), */
/* (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* dydx - x and y reference offset for q-pel */
/* calculations */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
WORD32 ht_temp;
UWORD8 *pu1_pred_vert,*pu1_pred_horiz;
UWORD8 *pu1_tmp1, *pu1_tmp2;
WORD32 x_offset, y_offset;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
__m128i const_val16_8x16b;
pu1_tmp1 = pu1_tmp;
dydx &= 0xf;
ht_temp = ht;
x_offset = dydx & 0x3;
y_offset = dydx >> 2;
pu1_tmp2 = pu1_tmp1;
pu1_pred_vert = pu1_src + (x_offset >> 1) - 2*src_strd;
pu1_pred_horiz = pu1_src + (y_offset >> 1) * src_strd - 2;
//the filter input starts from x[-2] (till x[3])
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
const_val16_8x16b = _mm_set1_epi16(16);
if(wd == 4)
{
//vertical q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b, src_r4_16x8b;
__m128i src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_r0r1_16x8b, res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
//epilogue: Load all the pred rows except sixth and seventh row for the
//first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r0_16x8b = _mm_unpacklo_epi32(src_r0_16x8b, src_r1_16x8b);
src_r2_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r1_16x8b = _mm_unpacklo_epi32(src_r1_16x8b, src_r2_16x8b);
src_r3_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r2_16x8b = _mm_unpacklo_epi32(src_r2_16x8b, src_r3_16x8b);
src_r4_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r3_16x8b = _mm_unpacklo_epi32(src_r3_16x8b, src_r4_16x8b);
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
src_r4_16x8b = _mm_unpacklo_epi32(src_r4_16x8b, src_r5_16x8b);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert + src_strd));
src_r5_16x8b = _mm_unpacklo_epi32(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_r0r1_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
_mm_storel_epi64((__m128i *)pu1_tmp1, res_r0r1_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht_temp -= 2;
pu1_pred_vert += src_strd << 1;
pu1_tmp1 += 8;
}
while(ht_temp > 0);
}
//horizontal q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0r1_vpel_16x8b, src_r0r1_t1_16x8b;
__m128i res_r0r1_t1_8x16b, res_r0r1_t2_8x16b, res_r0r1_t3_8x16b;
__m128i res_r0r1_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_pred_horiz); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_horiz + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0r1_vpel_16x8b = _mm_loadl_epi64((__m128i *)pu1_tmp2);
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 b0 b1 b1 b2 b2 b3 b3 b4
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 b2 b3 b3 b4 b4 b5 b5 b6
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//b2*c2+b3*c3 b3*c2+b4*c3 b4*c2+b5*c3 b5*c2+b6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 b4 b5 b5 b6 b6 b7 b7 b8
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//b4*c4+b5*c5 b5*c4+b6*c5 b4*c6+b7*c5 b7*c4+b8*c5
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0r1_t3_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t3_8x16b); //a0*c0+a1*c1+a2*c2+a3*c3+a4*a4+a5*c5 + 15;
//a1*c0+a2*c1+a2*c2+a3*c3+a5*a4+a6*c5 + 15;
//a2*c0+a3*c1+a4*c2+a5*c3+a6*a4+a7*c5 + 15;
//a3*c0+a4*c1+a5*c2+a6*c3+a6*a4+a8*c5 + 15;
//b0*c0+b1*c1+b2*c2+b3*c3+b4*b4+b5*c5 + 15;
//b1*c0+b2*c1+b2*c2+b3*c3+b5*b4+b6*c5 + 15;
//b2*c0+b3*c1+b4*c2+b5*c3+b6*b4+b7*c5 + 15;
//b3*c0+b4*c1+b5*c2+b6*c3+b6*b4+b8*c5 + 15;
res_r0r1_t1_8x16b = _mm_srai_epi16(res_r0r1_t1_8x16b, 5); //shifting right by 5 bits.
res_r0r1_16x8b = _mm_packus_epi16(res_r0r1_t1_8x16b,res_r0r1_t1_8x16b);
res_r0r1_16x8b = _mm_avg_epu8(res_r0r1_16x8b,src_r0r1_vpel_16x8b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
res_r0r1_16x8b = _mm_srli_si128(res_r0r1_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_r0r1_16x8b);
ht -= 2;
pu1_pred_horiz += src_strd << 1;
pu1_tmp2 += 8;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
}
else if(wd == 8)
{
//vertical q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b;
__m128i src_r4_16x8b, src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_16x8b, res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
//epilogue: Load all the pred rows except sixth and seventh row for the
//first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r0_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b);
src_r2_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r1_16x8b = _mm_unpacklo_epi64(src_r1_16x8b, src_r2_16x8b);
src_r3_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r2_16x8b = _mm_unpacklo_epi64(src_r2_16x8b, src_r3_16x8b);
src_r4_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r3_16x8b = _mm_unpacklo_epi64(src_r3_16x8b, src_r4_16x8b);
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert));
src_r4_16x8b = _mm_unpacklo_epi64(src_r4_16x8b, src_r5_16x8b);
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_pred_vert + src_strd));
src_r5_16x8b = _mm_unpacklo_epi64(src_r5_16x8b, src_r6_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
_mm_storel_epi64((__m128i *)(pu1_tmp1), res_16x8b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t1_8x16b, res_t1_8x16b);
_mm_storel_epi64((__m128i *)(pu1_tmp1 + 8), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht_temp -= 2;
pu1_pred_vert += src_strd << 1;
pu1_tmp1 += 16;
}
while(ht_temp > 0);
}
//horizontal q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i src_r0_vpel_16x8b, src_r1_vpel_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b, res_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_horiz)); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_horiz + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_vpel_16x8b = _mm_loadl_epi64((__m128i *)(pu1_tmp2)); //a2 a3 a4 a5 a6 a7 a8....a15 0 or
//a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_vpel_16x8b = _mm_loadl_epi64((__m128i *)(pu1_tmp2 + 8));
//b2 b3 b4 b5 b6 b7 b8....b15 0 or
//b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0_t3_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r0_t1_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_r0_vpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst), res_16x8b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r1_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_r1_t1_8x16b, res_r1_t1_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b,src_r1_vpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
ht -= 2;
pu1_pred_horiz += src_strd << 1;
pu1_dst += dst_strd << 1;
pu1_tmp2 += 16;
}
while(ht > 0);
}
}
else // wd == 16
{
//vertical q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b;
__m128i src_r4_16x8b, src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_t0_8x16b, res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i res_16x8b;
//epilogue: Load all the pred rows except sixth and seventh row for the
//first and second row processing.
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r2_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r3_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
src_r4_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
pu1_pred_vert = pu1_pred_vert + src_strd;
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert));
src_r6_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_vert + src_strd));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pu1_tmp1), res_16x8b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t0_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t3_8x16b);
res_t1_8x16b = _mm_srai_epi16(res_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_t0_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pu1_tmp1 + 16), res_16x8b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht_temp -= 2;
pu1_pred_vert += src_strd << 1;
pu1_tmp1 += 32;
}
while(ht_temp > 0);
}
//horizontal q-pel filter
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i src_vpel_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i res_16x8b;
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row0 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
//b0 is same a8. Similarly other bn pixels are same as a(n+8) pixels.
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_horiz)); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_pred_horiz + 8)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_vpel_16x8b = _mm_loadu_si128((__m128i *)(pu1_tmp2));
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t3_8x16b = _mm_add_epi16(const_val16_8x16b, res_r0_t3_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r0_t1_8x16b = _mm_srai_epi16(res_r0_t1_8x16b, 5); //shifting right by 5 bits.
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, const_val16_8x16b);
res_r1_t1_8x16b = _mm_srai_epi16(res_r1_t1_8x16b, 5); //shifting right by 5 bits.
res_16x8b = _mm_packus_epi16(res_r0_t1_8x16b, res_r1_t1_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_vpel_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst), res_16x8b);
ht --;
pu1_pred_horiz += src_strd;
pu1_dst += dst_strd;
pu1_tmp2 += 16;
}
while(ht > 0);
}
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3 */
/* */
/* Description : This function implements a six-tap filter vertically and */
/* horizontally on ht x wd block separately and averages */
/* the two sets of values to calculate values at (1/4,1/2), */
/* or (3/4, 1/2) as mentioned in sec. 8.4.2.2.1 titled */
/* "Luma sample interpolation process". (ht,wd) can be */
/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* dydx - x and y reference offset for q-pel */
/* calculations */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
WORD32 ht_temp;
WORD32 x_offset;
WORD32 off0,off1, off2, off3, off4, off5;
WORD16 *pi2_temp1,*pi2_temp2,*pi2_temp3;
ht_temp = ht;
x_offset = dydx & 0x3;
pi2_temp1 = (WORD16 *)pu1_tmp;
pi2_temp2 = pi2_temp1;
pi2_temp3 = pi2_temp1 + (x_offset >> 1);
pu1_src -= 2 * src_strd;
pu1_src -= 2;
pi2_temp3 += 2;
//the filter input starts from x[-2] (till x[3])
if(wd == 4)
{
//vertical half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b, src_r4_16x8b;
__m128i src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//c0 = c5 = 1, c1 = c4 = -5, c2 = c3 = 20
off0 = -((src_strd << 2) + src_strd) + 8;
off1 = -(src_strd << 2) + 8;
off2 = -((src_strd << 1) + src_strd) + 8;
off3 = -(src_strd << 1) + 8;
off4 = -src_strd + 8;
off5 = 8;
//epilogue: Load all the pred rows except sixth and seventh row for the
//first and second row processing.
src_r0_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r1_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r2_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r3_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r4_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t2_8x16b, res_t1_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_t1_8x16b);
pi2_temp1[8] = pu1_src[off0] + pu1_src[off5]
- (pu1_src[off1] + pu1_src[off4])
+ ((pu1_src[off2] + pu1_src[off3] - pu1_src[off1] - pu1_src[off4]) << 2)
+ ((pu1_src[off2] + pu1_src[off3]) << 4);
pu1_src = pu1_src + src_strd;
pi2_temp1 = pi2_temp1 + 9;
src_r6_16x8b = _mm_loadl_epi64((__m128i *)(pu1_src));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t2_8x16b, res_t1_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_t1_8x16b);
pi2_temp1[8] = pu1_src[off0] + pu1_src[off5]
- (pu1_src[off1] + pu1_src[off4])
+ ((pu1_src[off2] + pu1_src[off3] - pu1_src[off1] - pu1_src[off4]) << 2)
+ ((pu1_src[off2] + pu1_src[off3]) << 4);
ht_temp -= 2;
pu1_src = pu1_src + src_strd;
pi2_temp1 = pi2_temp1 + 9;
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
}
while(ht_temp > 0);
}
//horizontal q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b;
__m128i src_r3_8x16b, src_r4_8x16b, src_r5_8x16b;
__m128i src_r0r1_c0_8x16b, src_r2r3_c0_8x16b, src_r4r5_c0_8x16b;
__m128i src_hpel_16x8b, src_hpel_8x16b;
__m128i res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
do
{
src_r0_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 1));
src_r2_8x16b = _mm_srli_si128(src_r1_8x16b, 2);
src_r3_8x16b = _mm_srli_si128(src_r1_8x16b, 4);
src_r4_8x16b = _mm_srli_si128(src_r1_8x16b, 6);
src_r5_8x16b = _mm_srli_si128(src_r1_8x16b, 8);
src_r0r1_c0_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_c0_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_c0_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_c0_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_c0_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_c0_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(const_val512_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t1_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp3));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_16x8b);
ht--;
pi2_temp2 = pi2_temp2 + 4 + 5;
pi2_temp3 = pi2_temp3 + 4 + 5;
pu1_dst = pu1_dst + dst_strd;
}
while(ht > 0);
}
}
else if(wd == 8)
{
// vertical half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b, src_r4_16x8b;
__m128i src_r5_16x8b, src_r6_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//epilogue: Load all the pred rows except sixth and seventh row for the
//first and second row processing.
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r3_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
src_r4_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
pu1_src = pu1_src + src_strd;
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r6_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_t1_8x16b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8), res_t1_8x16b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8 + 5), res_t1_8x16b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r1_16x8b, src_r2_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r3_16x8b, src_r4_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r5_16x8b, src_r6_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8 + 5 + 8), res_t1_8x16b);
src_r0_16x8b = src_r2_16x8b;
src_r1_16x8b = src_r3_16x8b;
src_r2_16x8b = src_r4_16x8b;
src_r3_16x8b = src_r5_16x8b;
src_r4_16x8b = src_r6_16x8b;
ht_temp -= 2;
pu1_src = pu1_src + (src_strd << 1);
pi2_temp1 = pi2_temp1 + (13 << 1);
}
while(ht_temp > 0);
}
// horizontal q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b;
__m128i src_r4_8x16b, src_r5_8x16b;
__m128i src_r0r1_c0_8x16b, src_r2r3_c0_8x16b, src_r4r5_c0_8x16b;
__m128i src_r0r1_c1_8x16b, src_r2r3_c1_8x16b, src_r4r5_c1_8x16b;
__m128i src_hpel_8x16b, src_hpel_16x8b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
do
{
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 1));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 2));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 3));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 4));
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 5));
src_r0r1_c0_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_c0_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_c0_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
src_r0r1_c1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_c1_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_c1_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_c0_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_c0_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_c0_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_c1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_c1_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_c1_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst), res_16x8b);
ht--;
pi2_temp2 = pi2_temp2 + 8 + 5;
pi2_temp3 = pi2_temp3 + 8 + 5;
pu1_dst = pu1_dst + dst_strd;
}
while(ht > 0);
}
}
else // wd == 16
{
// vertical half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r2_16x8b, src_r3_16x8b;
__m128i src_r4_16x8b, src_r5_16x8b;
__m128i src_r0_c2_16x8b, src_r1_c2_16x8b, src_r2_c2_16x8b, src_r3_c2_16x8b;
__m128i src_r4_c2_16x8b, src_r5_c2_16x8b;
__m128i src_r0r1_16x8b, src_r2r3_16x8b, src_r4r5_16x8b;
__m128i res_t1_8x16b, res_t2_8x16b, res_t3_8x16b;
__m128i coeff0_1_16x8b,coeff2_3_16x8b,coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r0_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
pu1_src = pu1_src + src_strd;
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r1_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
pu1_src = pu1_src + src_strd;
src_r2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r2_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
pu1_src = pu1_src + src_strd;
src_r3_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r3_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
pu1_src = pu1_src + src_strd;
src_r4_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r4_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
pu1_src = pu1_src + src_strd;
//Core Loop: Process all the rows.
do
{
src_r5_16x8b = _mm_loadu_si128((__m128i *)(pu1_src));
src_r5_c2_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 16));
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_t1_8x16b);
src_r0r1_16x8b = _mm_unpackhi_epi8(src_r0_16x8b, src_r1_16x8b);
src_r2r3_16x8b = _mm_unpackhi_epi8(src_r2_16x8b, src_r3_16x8b);
src_r4r5_16x8b = _mm_unpackhi_epi8(src_r4_16x8b, src_r5_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8), res_t1_8x16b);
src_r0r1_16x8b = _mm_unpacklo_epi8(src_r0_c2_16x8b, src_r1_c2_16x8b);
src_r2r3_16x8b = _mm_unpacklo_epi8(src_r2_c2_16x8b, src_r3_c2_16x8b);
src_r4r5_16x8b = _mm_unpacklo_epi8(src_r4_c2_16x8b, src_r5_c2_16x8b);
res_t1_8x16b = _mm_maddubs_epi16(src_r0r1_16x8b, coeff0_1_16x8b);
res_t2_8x16b = _mm_maddubs_epi16(src_r2r3_16x8b, coeff2_3_16x8b);
res_t3_8x16b = _mm_maddubs_epi16(src_r4r5_16x8b, coeff4_5_16x8b);
res_t1_8x16b = _mm_add_epi16(res_t1_8x16b, res_t2_8x16b);
res_t1_8x16b = _mm_add_epi16(res_t3_8x16b, res_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 16), res_t1_8x16b);
src_r0_16x8b = src_r1_16x8b;
src_r1_16x8b = src_r2_16x8b;
src_r2_16x8b = src_r3_16x8b;
src_r3_16x8b = src_r4_16x8b;
src_r4_16x8b = src_r5_16x8b;
src_r0_c2_16x8b = src_r1_c2_16x8b;
src_r1_c2_16x8b = src_r2_c2_16x8b;
src_r2_c2_16x8b = src_r3_c2_16x8b;
src_r3_c2_16x8b = src_r4_c2_16x8b;
src_r4_c2_16x8b = src_r5_c2_16x8b;
ht_temp--;
pu1_src = pu1_src + src_strd;
pi2_temp1 = pi2_temp1 + 16 + 5;
}
while(ht_temp > 0);
}
// horizontal q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b;
__m128i src_r4_8x16b, src_r5_8x16b;
__m128i src_r0r1_8x16b, src_r2r3_8x16b, src_r4r5_8x16b;
__m128i src_hpel1_8x16b, src_hpel2_8x16b, src_hpel_16x8b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_c0_8x16b, res_c1_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
do
{
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 1));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 2));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 3));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 4));
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 5));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(const_val512_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_c0_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8 + 1));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8 + 2));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8 + 3));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8 + 4));
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8 + 5));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(const_val512_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b ,10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(const_val512_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_c1_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_c0_8x16b, res_c1_8x16b);
src_hpel1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3));
src_hpel1_8x16b = _mm_add_epi16(src_hpel1_8x16b, const_val16_8x16b);
src_hpel1_8x16b = _mm_srai_epi16(src_hpel1_8x16b, 5); //shifting right by 5 bits.
src_hpel2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3 + 8));
src_hpel2_8x16b = _mm_add_epi16(src_hpel2_8x16b, const_val16_8x16b);
src_hpel2_8x16b = _mm_srai_epi16(src_hpel2_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel1_8x16b, src_hpel2_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storeu_si128((__m128i *)(pu1_dst), res_16x8b);
ht--;
pi2_temp2 = pi2_temp2 + 16 + 5;
pi2_temp3 = pi2_temp3 + 16 + 5;
pu1_dst = pu1_dst + dst_strd;
}
while(ht > 0);
}
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3 */
/* */
/* Description : This function implements a six-tap filter vertically and */
/* horizontally on ht x wd block separately and averages */
/* the two sets of values to calculate values at (1/2,1/4), */
/* or (1/2, 3/4) as mentioned in sec. 8.4.2.2.1 titled */
/* "Luma sample interpolation process". (ht,wd) can be */
/* (4,4), (8,4), (4,8), (8,8), (16,8), (8,16) or (16,16). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* ht - height of the block */
/* wd - width of the block */
/* pu1_tmp - pointer to temporary buffer */
/* dydx - x and y reference offset for q-pel */
/* calculations */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 ht,
WORD32 wd,
UWORD8* pu1_tmp,
WORD32 dydx)
{
WORD32 ht_temp;
WORD32 y_offset;
WORD16 *pi2_temp1,*pi2_temp2,*pi2_temp3;
y_offset = (dydx & 0xf) >> 2;
pi2_temp1 = (WORD16 *)pu1_tmp;
pi2_temp2 = pi2_temp1;
pi2_temp3 = pi2_temp1 + (y_offset >> 1) * wd;
ht_temp = ht + 5;
pu1_src -= src_strd << 1;
pu1_src -= 2;
pi2_temp3 += wd << 1;
//the filter input starts from x[-2] (till x[3])
if(wd == 4)
{
// horizontal half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0r1_t1_16x8b;
__m128i src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i res_r0r1_t1_8x16b, res_r0r1_t2_8x16b, res_r0r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)pu1_src); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 b0 b1 b1 b2 b2 b3 b3 b4
res_r0r1_t1_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 b2 b3 b3 b4 b4 b5 b5 b6
res_r0r1_t2_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//b2*c2+b3*c3 b3*c2+b4*c3 b4*c2+b5*c3 b5*c2+b6*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 4); //a4 a5 a5 a6 a6 a7 a7 a8 0 0 0 0 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 4); //b4 b5 b5 b6 b6 b7 b7 b8 0 0 0 0 0 0 0 0
src_r0r1_t1_16x8b = _mm_unpacklo_epi64(src_r0_16x8b, src_r1_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 b4 b5 b5 b6 b6 b7 b7 b8
res_r0r1_t3_8x16b = _mm_maddubs_epi16(src_r0r1_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//b4*c4+b5*c5 b5*c4+b6*c5 b4*c6+b7*c5 b7*c4+b8*c5
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t2_8x16b);
res_r0r1_t1_8x16b = _mm_add_epi16(res_r0r1_t1_8x16b, res_r0r1_t3_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_r0r1_t1_8x16b);
ht_temp -= 2;
pu1_src = pu1_src + (src_strd << 1);
pi2_temp1 = pi2_temp1 + (4 << 1);
}
while(ht_temp > 0);
}
// vertical q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b;
__m128i src_r4_8x16b, src_r5_8x16b, src_r6_8x16b;
__m128i src_r0r1_c0_8x16b, src_r2r3_c0_8x16b, src_r4r5_c0_8x16b;
__m128i src_hpel_16x8b, src_hpel_8x16b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
src_r0_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2 + 4));
src_r2_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2 + 8));
src_r3_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2 + 12));
src_r4_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2 + 16));
pi2_temp2 += 20;
do
{
src_r5_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2));
src_r6_8x16b = _mm_loadl_epi64((__m128i *)(pi2_temp2 + 4));
src_r0r1_c0_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_c0_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_c0_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_c0_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_c0_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_c0_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_c0_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_c0_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_c0_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_c0_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_c0_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_c0_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)pi2_temp3);
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
*((WORD32 *)(pu1_dst)) = _mm_cvtsi128_si32(res_16x8b);
res_16x8b = _mm_srli_si128(res_16x8b, 4);
*((WORD32 *)(pu1_dst + dst_strd)) = _mm_cvtsi128_si32(res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp2 = pi2_temp2 + (4 << 1);
pi2_temp3 = pi2_temp3 + (4 << 1);
pu1_dst = pu1_dst + (dst_strd << 1);
}
while(ht > 0);
}
}
else if(wd == 8)
{
// horizontal half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row1 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_src)); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_r0_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8), res_r1_t1_8x16b);
ht_temp -= 2;
pu1_src = pu1_src + (src_strd << 1);
pi2_temp1 = pi2_temp1 + (8 << 1);
}
while(ht_temp > 0);
}
// vertical q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b;
__m128i src_r4_8x16b, src_r5_8x16b, src_r6_8x16b;
__m128i src_r0r1_8x16b, src_r2r3_8x16b, src_r4r5_8x16b;
__m128i src_hpel_8x16b, src_hpel_16x8b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 16));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 24));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 32));
pi2_temp2 += 40;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 8));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)pi2_temp3);
src_hpel_8x16b = _mm_add_epi16(const_val16_8x16b, src_hpel_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst), res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3 + 8));
src_hpel_8x16b = _mm_add_epi16(const_val16_8x16b, src_hpel_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp2 = pi2_temp2 + (8 << 1);
pi2_temp3 = pi2_temp3 + (8 << 1);
pu1_dst = pu1_dst + (dst_strd << 1);
}
while(ht > 0);
}
}
else // wd == 16
{
UWORD8 *pu1_dst1;
WORD16 *pi2_temp4,*pi2_temp5;
pu1_dst1 = pu1_dst + 8;
pi2_temp4 = pi2_temp2 + 8;
pi2_temp5 = pi2_temp3 + 8;
// horizontal half-pel
{
__m128i src_r0_16x8b, src_r1_16x8b, src_r0_sht_16x8b, src_r1_sht_16x8b;
__m128i src_r0_t1_16x8b, src_r1_t1_16x8b;
__m128i res_r0_t1_8x16b, res_r0_t2_8x16b, res_r0_t3_8x16b;
__m128i res_r1_t1_8x16b, res_r1_t2_8x16b, res_r1_t3_8x16b;
__m128i coeff0_1_16x8b, coeff2_3_16x8b, coeff4_5_16x8b;
coeff0_1_16x8b = _mm_set1_epi32(0xFB01FB01); //c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1 c0 c1
coeff2_3_16x8b = _mm_set1_epi32(0x14141414); //c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3 c2 c3
coeff4_5_16x8b = _mm_set1_epi32(0x01FB01FB); //c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5 c4 c5 c5 c5
//Row0 : a0 a1 a2 a3 a4 a5 a6 a7 a8 a9.....
//Row0 : b0 b1 b2 b3 b4 b5 b6 b7 b8 b9.....
//b0 is same a8. Similarly other bn pixels are same as a(n+8) pixels.
do
{
src_r0_16x8b = _mm_loadu_si128((__m128i *)(pu1_src)); //a0 a1 a2 a3 a4 a5 a6 a7 a8 a9....a15
src_r1_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8)); //b0 b1 b2 b3 b4 b5 b6 b7 b8 b9....b15
src_r0_sht_16x8b = _mm_srli_si128(src_r0_16x8b, 1); //a1 a2 a3 a4 a5 a6 a7 a8 a9....a15 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_16x8b, 1); //b1 b2 b3 b4 b5 b6 b7 b8 b9....b15 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a0 a1 a1 a2 a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b0 b1 b1 b2 b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8
res_r0_t1_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff0_1_16x8b); //a0*c0+a1*c1 a1*c0+a2*c1 a2*c0+a3*c1 a3*c0+a4*c1
//a4*c0+a5*c1 a5*c0+a6*c1 a6*c0+a7*c1 a7*c0+a8*c1
res_r1_t1_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff0_1_16x8b); //b0*c0+b1*c1 b1*c0+b2*c1 b2*c0+b3*c1 b3*c0+b4*c1
//b4*c0+b5*c1 b5*c0+b6*c1 b6*c0+b7*c1 b7*c0+b8*c1
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a2 a3 a4 a5 a6 a7 a8 a9....a15 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b2 b3 b4 b5 b6 b7 b8 b9....b15 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a3 a4 a5 a6 a7 a8 a9....a15 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b3 b4 b5 b6 b7 b8 b9....b15 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a2 a3 a3 a4 a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b2 b3 b3 b4 b4 b5 b5 b6 b6 b7 b7 b8 a8 a9 a9 a10
res_r0_t2_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff2_3_16x8b); //a2*c2+a3*c3 a3*c2+a4*c3 a4*c2+a5*c3 a5*c2+a6*c3
//a6*c2+a7*c3 a7*c2+a8*c3 a8*c2+a9*c3 a9*c2+a10*c3
res_r1_t2_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff2_3_16x8b); //b2*c2+b3*c3 b3*c2+b4*c3 b2*c4+b5*c3 b5*c2+b6*c3
//b6*c2+b7*c3 b7*c2+b8*c3 b8*c2+b9*c3 b9*c2+b10*c3
src_r0_16x8b = _mm_srli_si128(src_r0_16x8b, 2); //a4 a5 a6 a7 a8 a9....a15 0 0 0 0
src_r1_16x8b = _mm_srli_si128(src_r1_16x8b, 2); //b4 b5 b6 b7 b8 b9....b15 0 0 0 0
src_r0_sht_16x8b = _mm_srli_si128(src_r0_sht_16x8b, 2); //a5 a6 a7 a8 a9....a15 0 0 0 0 0
src_r1_sht_16x8b = _mm_srli_si128(src_r1_sht_16x8b, 2); //b5 b6 b7 b8 b9....b15 0 0 0 0 0
src_r0_t1_16x8b = _mm_unpacklo_epi8(src_r0_16x8b, src_r0_sht_16x8b); //a4 a5 a5 a6 a6 a7 a7 a8 a8 a9 a9 a10 a10 a11 a11 a12
src_r1_t1_16x8b = _mm_unpacklo_epi8(src_r1_16x8b, src_r1_sht_16x8b); //b4 b5 b5 b6 b6 b7 b7 b8 b8 b9 b9 b10 b10 b11 b11 b12
res_r0_t3_8x16b = _mm_maddubs_epi16(src_r0_t1_16x8b, coeff4_5_16x8b); //a4*c4+a5*c5 a5*c4+a6*c5 a6*c4+a7*c5 a7*c4+a8*c5
//a8*c4+a9*c5 a9*c4+a10*c5 a10*c4+a11*c5 a11*c4+a12*c5
res_r1_t3_8x16b = _mm_maddubs_epi16(src_r1_t1_16x8b, coeff4_5_16x8b); //b4*c4+b5*c5 b5*c4+b6*c5 b6*c4+b7*c5 b7*c4+b8*c5
//b8*c4+b9*c5 b9*c4+b10*c5 b10*c4+b11*c5 b11*c4+b12*c5
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t2_8x16b);
res_r0_t1_8x16b = _mm_add_epi16(res_r0_t1_8x16b, res_r0_t3_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t2_8x16b);
res_r1_t1_8x16b = _mm_add_epi16(res_r1_t1_8x16b, res_r1_t3_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1), res_r0_t1_8x16b);
_mm_storeu_si128((__m128i *)(pi2_temp1 + 8), res_r1_t1_8x16b);
ht_temp--;
pu1_src = pu1_src + src_strd;
pi2_temp1 = pi2_temp1 + 16;
}
while(ht_temp > 0);
}
// vertical q-pel
{
__m128i src_r0_8x16b, src_r1_8x16b, src_r2_8x16b, src_r3_8x16b, src_r4_8x16b;
__m128i src_r5_8x16b, src_r6_8x16b;
__m128i src_r0r1_8x16b, src_r2r3_8x16b, src_r4r5_8x16b;
__m128i src_hpel_8x16b, src_hpel_16x8b;
__m128i res_t0_4x32b, res_t1_4x32b, res_t2_4x32b, res_t3_4x32b;
__m128i res_8x16b, res_16x8b;
__m128i coeff0_1_8x16b, coeff2_3_8x16b, coeff4_5_8x16b;
__m128i const_val512_4x32b, const_val16_8x16b;
coeff0_1_8x16b = _mm_set1_epi32(0xFFFB0001);
coeff2_3_8x16b = _mm_set1_epi32(0x00140014);
coeff4_5_8x16b = _mm_set1_epi32(0x0001FFFB);
const_val512_4x32b = _mm_set1_epi32(512);
const_val16_8x16b = _mm_set1_epi16(16);
/**********************************************************/
/* Do first height x 8 block */
/**********************************************************/
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 16));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 32));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 48));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 64));
pi2_temp2 += 80;
ht_temp = ht;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2));
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp2 + 16));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst), res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp3 + 16));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht_temp -= 2;
pi2_temp3 = pi2_temp3 + (16 << 1);
pi2_temp2 = pi2_temp2 + (16 << 1);
pu1_dst = pu1_dst + (dst_strd << 1);
}
while(ht_temp > 0);
/**********************************************************/
/* Do second height * 8 block */
/**********************************************************/
src_r0_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4));
src_r1_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4 + 16));
src_r2_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4 + 32));
src_r3_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4 + 48));
src_r4_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4 + 64));
pi2_temp4 += 80;
do
{
src_r5_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4));
src_r6_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp4 + 16));
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r0_8x16b, src_r1_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r2_8x16b, src_r3_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r4_8x16b, src_r5_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp5));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst1), res_16x8b);
src_r0r1_8x16b = _mm_unpacklo_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpacklo_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpacklo_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t0_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
src_r0r1_8x16b = _mm_unpackhi_epi16(src_r1_8x16b, src_r2_8x16b);
src_r2r3_8x16b = _mm_unpackhi_epi16(src_r3_8x16b, src_r4_8x16b);
src_r4r5_8x16b = _mm_unpackhi_epi16(src_r5_8x16b, src_r6_8x16b);
res_t1_4x32b = _mm_madd_epi16(src_r0r1_8x16b, coeff0_1_8x16b);
res_t2_4x32b = _mm_madd_epi16(src_r2r3_8x16b, coeff2_3_8x16b);
res_t3_4x32b = _mm_madd_epi16(src_r4r5_8x16b, coeff4_5_8x16b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t2_4x32b);
res_t3_4x32b = _mm_add_epi32(res_t3_4x32b, const_val512_4x32b);
res_t1_4x32b = _mm_add_epi32(res_t1_4x32b, res_t3_4x32b);
res_t1_4x32b = _mm_srai_epi32(res_t1_4x32b, 10);
res_8x16b = _mm_packs_epi32(res_t0_4x32b, res_t1_4x32b);
res_16x8b = _mm_packus_epi16(res_8x16b, res_8x16b);
src_hpel_8x16b = _mm_loadu_si128((__m128i *)(pi2_temp5 + 16));
src_hpel_8x16b = _mm_add_epi16(src_hpel_8x16b, const_val16_8x16b);
src_hpel_8x16b = _mm_srai_epi16(src_hpel_8x16b, 5); //shifting right by 5 bits.
src_hpel_16x8b = _mm_packus_epi16(src_hpel_8x16b, src_hpel_8x16b);
res_16x8b = _mm_avg_epu8(res_16x8b, src_hpel_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst1 + dst_strd), res_16x8b);
src_r0_8x16b = src_r2_8x16b;
src_r1_8x16b = src_r3_8x16b;
src_r2_8x16b = src_r4_8x16b;
src_r3_8x16b = src_r5_8x16b;
src_r4_8x16b = src_r6_8x16b;
ht -= 2;
pi2_temp5 = pi2_temp5 + (16 << 1);
pi2_temp4 = pi2_temp4 + (16 << 1);
pu1_dst1 = pu1_dst1 + (dst_strd << 1);
}
while(ht > 0);
}
}
}
/*****************************************************************************/
/* */
/* Function Name : ih264_inter_pred_chroma_ssse3 */
/* */
/* Description : This function implements a four-tap 2D filter as */
/* mentioned in sec. 8.4.2.2.2 titled "Chroma sample */
/* "interpolation process". (ht,wd) can be (2,2), (4,2), */
/* (2,4), (4,4), (8,4), (4,8) or (8,8). */
/* */
/* Inputs : puc_src - pointer to source */
/* puc_dst - pointer to destination */
/* src_strd - stride for source */
/* dst_strd - stride for destination */
/* dx - x position of destination value */
/* dy - y position of destination value */
/* ht - height of the block */
/* wd - width of the block */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 13 02 2015 Kaushik Initial Version */
/* Senthoor */
/* */
/*****************************************************************************/
void ih264_inter_pred_chroma_ssse3(UWORD8 *pu1_src,
UWORD8 *pu1_dst,
WORD32 src_strd,
WORD32 dst_strd,
WORD32 dx,
WORD32 dy,
WORD32 ht,
WORD32 wd)
{
WORD32 i, j, A, B, C, D;
i = 8 - dx;
j = 8 - dy;
A = i * j;
B = dx * j;
C = i * dy;
D = dx * dy;
if(wd == 2)
{
WORD32 tmp1, tmp2, tmp3, tmp4;
do
{
//U
tmp1 = A * pu1_src[0] + B * pu1_src[2] + C * pu1_src[src_strd] + D * pu1_src[src_strd + 2];
tmp2 = A * pu1_src[2] + B * pu1_src[4] + C * pu1_src[src_strd + 2] + D * pu1_src[src_strd + 4];
//V
tmp3 = A * pu1_src[1] + B * pu1_src[3] + C * pu1_src[src_strd + 1] + D * pu1_src[src_strd + 3];
tmp4 = A * pu1_src[3] + B * pu1_src[5] + C * pu1_src[src_strd + 3] + D * pu1_src[src_strd + 5];
tmp1 = (tmp1 + 32) >> 6;
tmp2 = (tmp2 + 32) >> 6;
tmp3 = (tmp3 + 32) >> 6;
tmp4 = (tmp4 + 32) >> 6;
pu1_dst[0] = CLIP_U8(tmp1);
pu1_dst[2] = CLIP_U8(tmp2);
pu1_dst[1] = CLIP_U8(tmp3);
pu1_dst[3] = CLIP_U8(tmp4);
pu1_src += src_strd;
pu1_dst += dst_strd;
tmp1 = A * pu1_src[0] + B * pu1_src[2] + C * pu1_src[src_strd] + D * pu1_src[src_strd + 2];
tmp2 = A * pu1_src[2] + B * pu1_src[4] + C * pu1_src[src_strd + 2] + D * pu1_src[src_strd + 4];
tmp3 = A * pu1_src[1] + B * pu1_src[3] + C * pu1_src[src_strd + 1] + D * pu1_src[src_strd + 3];
tmp4 = A * pu1_src[3] + B * pu1_src[5] + C * pu1_src[src_strd + 3] + D * pu1_src[src_strd + 5];
tmp1 = (tmp1 + 32) >> 6;
tmp2 = (tmp2 + 32) >> 6;
tmp3 = (tmp3 + 32) >> 6;
tmp4 = (tmp4 + 32) >> 6;
pu1_dst[0] = CLIP_U8(tmp1);
pu1_dst[2] = CLIP_U8(tmp2);
pu1_dst[1] = CLIP_U8(tmp3);
pu1_dst[3] = CLIP_U8(tmp4);
ht -= 2;
pu1_src += src_strd;
pu1_dst += dst_strd;
}
while(ht > 0);
}
else if(wd == 4)
{
WORD32 AB, CD;
__m128i src_r1_16x8b, src_r2_16x8b, src_r3_16x8b;
__m128i res1_AB_8x16b, res1_CD_8x16b, res1_8x16b, res1_16x8b;
__m128i res2_AB_8x16b, res2_CD_8x16b, res2_8x16b, res2_16x8b;
__m128i coeffAB_16x8b, coeffCD_16x8b, round_add32_8x16b;
__m128i const_shuff_16x8b;
AB = (B << 8) + A;
CD = (D << 8) + C;
coeffAB_16x8b = _mm_set1_epi16(AB);
coeffCD_16x8b = _mm_set1_epi16(CD);
round_add32_8x16b = _mm_set1_epi16(32);
const_shuff_16x8b = _mm_setr_epi32(0x03010200, 0x05030402, 0x07050604, 0x09070806);
src_r1_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r1_16x8b = _mm_shuffle_epi8(src_r1_16x8b, const_shuff_16x8b);
pu1_src += src_strd;
do
{
src_r2_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r3_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + src_strd));
src_r2_16x8b = _mm_shuffle_epi8(src_r2_16x8b, const_shuff_16x8b);
src_r3_16x8b = _mm_shuffle_epi8(src_r3_16x8b, const_shuff_16x8b);
res1_AB_8x16b = _mm_maddubs_epi16(src_r1_16x8b, coeffAB_16x8b);
res1_CD_8x16b = _mm_maddubs_epi16(src_r2_16x8b, coeffCD_16x8b);
res2_AB_8x16b = _mm_maddubs_epi16(src_r2_16x8b, coeffAB_16x8b);
res2_CD_8x16b = _mm_maddubs_epi16(src_r3_16x8b, coeffCD_16x8b);
res1_8x16b = _mm_add_epi16(res1_AB_8x16b, res1_CD_8x16b);
res2_8x16b = _mm_add_epi16(res2_AB_8x16b, res2_CD_8x16b);
res1_8x16b = _mm_add_epi16(res1_8x16b, round_add32_8x16b);
res2_8x16b = _mm_add_epi16(res2_8x16b, round_add32_8x16b);
res1_8x16b = _mm_srai_epi16(res1_8x16b, 6);
res2_8x16b = _mm_srai_epi16(res2_8x16b, 6);
res1_16x8b = _mm_packus_epi16(res1_8x16b, res1_8x16b);
res2_16x8b = _mm_packus_epi16(res2_8x16b, res2_8x16b);
_mm_storel_epi64((__m128i *)pu1_dst, res1_16x8b);
_mm_storel_epi64((__m128i *)(pu1_dst + dst_strd), res2_16x8b);
src_r1_16x8b = src_r3_16x8b;
ht -= 2;
pu1_src += src_strd << 1;
pu1_dst += dst_strd << 1;
}
while(ht > 0);
}
else // wd == 8
{
WORD32 AB, CD;
__m128i src_r1l_16x8b, src_r2l_16x8b;
__m128i src_r1h_16x8b, src_r2h_16x8b;
__m128i res_l_AB_8x16b, res_l_CD_8x16b;
__m128i res_h_AB_8x16b, res_h_CD_8x16b;
__m128i res_l_8x16b, res_h_8x16b, res_16x8b;
__m128i coeffAB_16x8b, coeffCD_16x8b, round_add32_8x16b;
__m128i const_shuff_16x8b;
AB = (B << 8) + A;
CD = (D << 8) + C;
coeffAB_16x8b = _mm_set1_epi16(AB);
coeffCD_16x8b = _mm_set1_epi16(CD);
round_add32_8x16b = _mm_set1_epi16(32);
const_shuff_16x8b = _mm_setr_epi32(0x03010200, 0x05030402, 0x07050604, 0x09070806);
src_r1l_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r1h_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8));
src_r1l_16x8b = _mm_shuffle_epi8(src_r1l_16x8b, const_shuff_16x8b);
src_r1h_16x8b = _mm_shuffle_epi8(src_r1h_16x8b, const_shuff_16x8b);
pu1_src += src_strd;
do
{
//row 1
src_r2l_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r2h_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8));
src_r2l_16x8b = _mm_shuffle_epi8(src_r2l_16x8b, const_shuff_16x8b);
src_r2h_16x8b = _mm_shuffle_epi8(src_r2h_16x8b, const_shuff_16x8b);
res_l_AB_8x16b = _mm_maddubs_epi16(src_r1l_16x8b, coeffAB_16x8b);
res_h_AB_8x16b = _mm_maddubs_epi16(src_r1h_16x8b, coeffAB_16x8b);
res_l_CD_8x16b = _mm_maddubs_epi16(src_r2l_16x8b, coeffCD_16x8b);
res_h_CD_8x16b = _mm_maddubs_epi16(src_r2h_16x8b, coeffCD_16x8b);
res_l_8x16b = _mm_add_epi16(res_l_AB_8x16b, round_add32_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_AB_8x16b, round_add32_8x16b);
res_l_8x16b = _mm_add_epi16(res_l_8x16b, res_l_CD_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_8x16b, res_h_CD_8x16b);
res_l_8x16b = _mm_srai_epi16(res_l_8x16b, 6);
res_h_8x16b = _mm_srai_epi16(res_h_8x16b, 6);
res_16x8b = _mm_packus_epi16(res_l_8x16b, res_h_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
pu1_src += src_strd;
pu1_dst += dst_strd;
//row 2
src_r1l_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r1h_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8));
src_r1l_16x8b = _mm_shuffle_epi8(src_r1l_16x8b, const_shuff_16x8b);
src_r1h_16x8b = _mm_shuffle_epi8(src_r1h_16x8b, const_shuff_16x8b);
res_l_AB_8x16b = _mm_maddubs_epi16(src_r2l_16x8b, coeffAB_16x8b);
res_h_AB_8x16b = _mm_maddubs_epi16(src_r2h_16x8b, coeffAB_16x8b);
res_l_CD_8x16b = _mm_maddubs_epi16(src_r1l_16x8b, coeffCD_16x8b);
res_h_CD_8x16b = _mm_maddubs_epi16(src_r1h_16x8b, coeffCD_16x8b);
res_l_8x16b = _mm_add_epi16(res_l_AB_8x16b, round_add32_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_AB_8x16b, round_add32_8x16b);
res_l_8x16b = _mm_add_epi16(res_l_8x16b, res_l_CD_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_8x16b, res_h_CD_8x16b);
res_l_8x16b = _mm_srai_epi16(res_l_8x16b, 6);
res_h_8x16b = _mm_srai_epi16(res_h_8x16b, 6);
res_16x8b = _mm_packus_epi16(res_l_8x16b, res_h_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
pu1_src += src_strd;
pu1_dst += dst_strd;
//row 3
src_r2l_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r2h_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8));
src_r2l_16x8b = _mm_shuffle_epi8(src_r2l_16x8b, const_shuff_16x8b);
src_r2h_16x8b = _mm_shuffle_epi8(src_r2h_16x8b, const_shuff_16x8b);
res_l_AB_8x16b = _mm_maddubs_epi16(src_r1l_16x8b, coeffAB_16x8b);
res_h_AB_8x16b = _mm_maddubs_epi16(src_r1h_16x8b, coeffAB_16x8b);
res_l_CD_8x16b = _mm_maddubs_epi16(src_r2l_16x8b, coeffCD_16x8b);
res_h_CD_8x16b = _mm_maddubs_epi16(src_r2h_16x8b, coeffCD_16x8b);
res_l_8x16b = _mm_add_epi16(res_l_AB_8x16b, round_add32_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_AB_8x16b, round_add32_8x16b);
res_l_8x16b = _mm_add_epi16(res_l_8x16b, res_l_CD_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_8x16b, res_h_CD_8x16b);
res_l_8x16b = _mm_srai_epi16(res_l_8x16b, 6);
res_h_8x16b = _mm_srai_epi16(res_h_8x16b, 6);
res_16x8b = _mm_packus_epi16(res_l_8x16b, res_h_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
pu1_src += src_strd;
pu1_dst += dst_strd;
//row 1
src_r1l_16x8b = _mm_loadu_si128((__m128i *)pu1_src);
src_r1h_16x8b = _mm_loadu_si128((__m128i *)(pu1_src + 8));
src_r1l_16x8b = _mm_shuffle_epi8(src_r1l_16x8b, const_shuff_16x8b);
src_r1h_16x8b = _mm_shuffle_epi8(src_r1h_16x8b, const_shuff_16x8b);
res_l_AB_8x16b = _mm_maddubs_epi16(src_r2l_16x8b, coeffAB_16x8b);
res_h_AB_8x16b = _mm_maddubs_epi16(src_r2h_16x8b, coeffAB_16x8b);
res_l_CD_8x16b = _mm_maddubs_epi16(src_r1l_16x8b, coeffCD_16x8b);
res_h_CD_8x16b = _mm_maddubs_epi16(src_r1h_16x8b, coeffCD_16x8b);
res_l_8x16b = _mm_add_epi16(res_l_AB_8x16b, round_add32_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_AB_8x16b, round_add32_8x16b);
res_l_8x16b = _mm_add_epi16(res_l_8x16b, res_l_CD_8x16b);
res_h_8x16b = _mm_add_epi16(res_h_8x16b, res_h_CD_8x16b);
res_l_8x16b = _mm_srai_epi16(res_l_8x16b, 6);
res_h_8x16b = _mm_srai_epi16(res_h_8x16b, 6);
res_16x8b = _mm_packus_epi16(res_l_8x16b, res_h_8x16b);
_mm_storeu_si128((__m128i *)pu1_dst, res_16x8b);
ht -= 4;
pu1_src += src_strd;
pu1_dst += dst_strd;
}
while(ht > 0);
}
}