/****************************************************************************** * * 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 * impeg2_inter_pred_sse42_intr.c * * @brief * Contains Motion compensation function definitions for MPEG2 decoder * * @author * Mohit [100664] * * - impeg2_copy_mb_sse42() * - impeg2_interpolate_sse42() * - impeg2_mc_halfx_halfy_8x8_sse42() * - impeg2_mc_halfx_fully_8x8_sse42() * - impeg2_mc_fullx_halfy_8x8_sse42() * - impeg2_mc_fullx_fully_8x8_sse42() * * @remarks * None * ******************************************************************************* */ #include <stdio.h> #include <string.h> #include "iv_datatypedef.h" #include "impeg2_macros.h" #include "impeg2_defs.h" #include "impeg2_inter_pred.h" #include <immintrin.h> #include <emmintrin.h> #include <smmintrin.h> #include <tmmintrin.h> /******************************************************************************* * Function Name : impeg2_copy_mb * * Description : copies 3 components to the frame from mc_buf * * Arguments : * src_buf : Source Buffer * dst_buf : Destination Buffer * src_wd : Source Width * dst_wd : destination Width * * Values Returned : None *******************************************************************************/ void impeg2_copy_mb_sse42(yuv_buf_t *src_buf, yuv_buf_t *dst_buf, UWORD32 src_wd, UWORD32 dst_wd) { UWORD8 *src; UWORD8 *dst; __m128i src_r0, src_r1, src_r2, src_r3; /*******************************************************/ /* copy Y */ /*******************************************************/ src = src_buf->pu1_y; dst = dst_buf->pu1_y; // Row 0-3 src_r0 = _mm_loadu_si128((__m128i *) (src)); src_r1 = _mm_loadu_si128((__m128i *) (src + src_wd)); src_r2 = _mm_loadu_si128((__m128i *) (src + 2 * src_wd)); src_r3 = _mm_loadu_si128((__m128i *) (src + 3 * src_wd)); _mm_storeu_si128((__m128i *) dst, src_r0); _mm_storeu_si128((__m128i *) (dst + dst_wd), src_r1); _mm_storeu_si128((__m128i *) (dst + 2 * dst_wd), src_r2); _mm_storeu_si128((__m128i *) (dst + 3 * dst_wd), src_r3); // Row 4-7 src += 4 * src_wd; dst += 4 * dst_wd; src_r0 = _mm_loadu_si128((__m128i *) (src)); src_r1 = _mm_loadu_si128((__m128i *) (src + src_wd)); src_r2 = _mm_loadu_si128((__m128i *) (src + 2 * src_wd)); src_r3 = _mm_loadu_si128((__m128i *) (src + 3 * src_wd)); _mm_storeu_si128((__m128i *) dst, src_r0); _mm_storeu_si128((__m128i *) (dst + dst_wd), src_r1); _mm_storeu_si128((__m128i *) (dst + 2 * dst_wd), src_r2); _mm_storeu_si128((__m128i *) (dst + 3 * dst_wd), src_r3); // Row 8-11 src += 4 * src_wd; dst += 4 * dst_wd; src_r0 = _mm_loadu_si128((__m128i *) (src)); src_r1 = _mm_loadu_si128((__m128i *) (src + src_wd)); src_r2 = _mm_loadu_si128((__m128i *) (src + 2 * src_wd)); src_r3 = _mm_loadu_si128((__m128i *) (src + 3 * src_wd)); _mm_storeu_si128((__m128i *) dst, src_r0); _mm_storeu_si128((__m128i *) (dst + dst_wd), src_r1); _mm_storeu_si128((__m128i *) (dst + 2 * dst_wd), src_r2); _mm_storeu_si128((__m128i *) (dst + 3 * dst_wd), src_r3); // Row 12-15 src += 4 * src_wd; dst += 4 * dst_wd; src_r0 = _mm_loadu_si128((__m128i *) (src)); src_r1 = _mm_loadu_si128((__m128i *) (src + src_wd)); src_r2 = _mm_loadu_si128((__m128i *) (src + 2 * src_wd)); src_r3 = _mm_loadu_si128((__m128i *) (src + 3 * src_wd)); _mm_storeu_si128((__m128i *) dst, src_r0); _mm_storeu_si128((__m128i *) (dst + dst_wd), src_r1); _mm_storeu_si128((__m128i *) (dst + 2 * dst_wd), src_r2); _mm_storeu_si128((__m128i *) (dst + 3 * dst_wd), src_r3); src_wd >>= 1; dst_wd >>= 1; /*******************************************************/ /* copy U */ /*******************************************************/ src = src_buf->pu1_u; dst = dst_buf->pu1_u; // Row 0-3 src_r0 = _mm_loadl_epi64((__m128i *)src); src_r1 = _mm_loadl_epi64((__m128i *)(src + src_wd)); src_r2 = _mm_loadl_epi64((__m128i *)(src + 2 * src_wd)); src_r3 = _mm_loadl_epi64((__m128i *)(src + 3 * src_wd)); _mm_storel_epi64((__m128i *)dst, src_r0); _mm_storel_epi64((__m128i *)(dst + dst_wd), src_r1); _mm_storel_epi64((__m128i *)(dst + 2 * dst_wd), src_r2); _mm_storel_epi64((__m128i *)(dst + 3 * dst_wd), src_r3); // Row 4-7 src += 4 * src_wd; dst += 4 * dst_wd; src_r0 = _mm_loadl_epi64((__m128i *)src); src_r1 = _mm_loadl_epi64((__m128i *)(src + src_wd)); src_r2 = _mm_loadl_epi64((__m128i *)(src + 2 * src_wd)); src_r3 = _mm_loadl_epi64((__m128i *)(src + 3 * src_wd)); _mm_storel_epi64((__m128i *)dst, src_r0); _mm_storel_epi64((__m128i *)(dst + dst_wd), src_r1); _mm_storel_epi64((__m128i *)(dst + 2 * dst_wd), src_r2); _mm_storel_epi64((__m128i *)(dst + 3 * dst_wd), src_r3); /*******************************************************/ /* copy V */ /*******************************************************/ src = src_buf->pu1_v; dst = dst_buf->pu1_v; // Row 0-3 src_r0 = _mm_loadl_epi64((__m128i *)src); src_r1 = _mm_loadl_epi64((__m128i *)(src + src_wd)); src_r2 = _mm_loadl_epi64((__m128i *)(src + 2 * src_wd)); src_r3 = _mm_loadl_epi64((__m128i *)(src + 3 * src_wd)); _mm_storel_epi64((__m128i *)dst, src_r0); _mm_storel_epi64((__m128i *)(dst + dst_wd), src_r1); _mm_storel_epi64((__m128i *)(dst + 2 * dst_wd), src_r2); _mm_storel_epi64((__m128i *)(dst + 3 * dst_wd), src_r3); // Row 4-7 src += 4 * src_wd; dst += 4 * dst_wd; src_r0 = _mm_loadl_epi64((__m128i *)src); src_r1 = _mm_loadl_epi64((__m128i *)(src + src_wd)); src_r2 = _mm_loadl_epi64((__m128i *)(src + 2 * src_wd)); src_r3 = _mm_loadl_epi64((__m128i *)(src + 3 * src_wd)); _mm_storel_epi64((__m128i *)dst, src_r0); _mm_storel_epi64((__m128i *)(dst + dst_wd), src_r1); _mm_storel_epi64((__m128i *)(dst + 2 * dst_wd), src_r2); _mm_storel_epi64((__m128i *)(dst + 3 * dst_wd), src_r3); } /*****************************************************************************/ /* */ /* Function Name : impeg2_interpolate */ /* */ /* Description : averages the contents of buf_src1 and buf_src2 and stores*/ /* result in buf_dst */ /* */ /* Inputs : buf_src1 - First Source */ /* buf_src2 - Second Source */ /* */ /* Globals : None */ /* */ /* Processing : Avg the values from two sources and store the result in */ /* destination buffer */ /* */ /* Outputs : buf_dst - Avg of contents of buf_src1 and buf_src2 */ /* */ /* Returns : None */ /* */ /* Issues : Assumes that all 3 buffers are of same size */ /* */ /*****************************************************************************/ void impeg2_interpolate_sse42(yuv_buf_t *buf_src1, yuv_buf_t *buf_src2, yuv_buf_t *buf_dst, UWORD32 stride) { UWORD8 *src1, *src2; UWORD8 *dst; __m128i src1_r0, src1_r1, src1_r2, src1_r3; __m128i src2_r0, src2_r1, src2_r2, src2_r3; /*******************************************************/ /* interpolate Y */ /*******************************************************/ src1 = buf_src1->pu1_y; src2 = buf_src2->pu1_y; dst = buf_dst->pu1_y; // Row 0-3 src1_r0 = _mm_loadu_si128((__m128i *) (src1)); src1_r1 = _mm_loadu_si128((__m128i *) (src1 + 16)); src1_r2 = _mm_loadu_si128((__m128i *) (src1 + 2 * 16)); src1_r3 = _mm_loadu_si128((__m128i *) (src1 + 3 * 16)); src2_r0 = _mm_loadu_si128((__m128i *) (src2)); src2_r1 = _mm_loadu_si128((__m128i *) (src2 + 16)); src2_r2 = _mm_loadu_si128((__m128i *) (src2 + 2 * 16)); src2_r3 = _mm_loadu_si128((__m128i *) (src2 + 3 * 16)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storeu_si128((__m128i *) dst, src1_r0); _mm_storeu_si128((__m128i *) (dst + stride), src1_r1); _mm_storeu_si128((__m128i *) (dst + 2 * stride), src1_r2); _mm_storeu_si128((__m128i *) (dst + 3 * stride), src1_r3); // Row 4-7 src1 += 4 * 16; src2 += 4 * 16; dst += 4 * stride; src1_r0 = _mm_loadu_si128((__m128i *) (src1)); src1_r1 = _mm_loadu_si128((__m128i *) (src1 + 16)); src1_r2 = _mm_loadu_si128((__m128i *) (src1 + 2 * 16)); src1_r3 = _mm_loadu_si128((__m128i *) (src1 + 3 * 16)); src2_r0 = _mm_loadu_si128((__m128i *) (src2)); src2_r1 = _mm_loadu_si128((__m128i *) (src2 + 16)); src2_r2 = _mm_loadu_si128((__m128i *) (src2 + 2 * 16)); src2_r3 = _mm_loadu_si128((__m128i *) (src2 + 3 * 16)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storeu_si128((__m128i *) dst, src1_r0); _mm_storeu_si128((__m128i *) (dst + stride), src1_r1); _mm_storeu_si128((__m128i *) (dst + 2 * stride), src1_r2); _mm_storeu_si128((__m128i *) (dst + 3 * stride), src1_r3); // Row 8-11 src1 += 4 * 16; src2 += 4 * 16; dst += 4 * stride; src1_r0 = _mm_loadu_si128((__m128i *) (src1)); src1_r1 = _mm_loadu_si128((__m128i *) (src1 + 16)); src1_r2 = _mm_loadu_si128((__m128i *) (src1 + 2 * 16)); src1_r3 = _mm_loadu_si128((__m128i *) (src1 + 3 * 16)); src2_r0 = _mm_loadu_si128((__m128i *) (src2)); src2_r1 = _mm_loadu_si128((__m128i *) (src2 + 16)); src2_r2 = _mm_loadu_si128((__m128i *) (src2 + 2 * 16)); src2_r3 = _mm_loadu_si128((__m128i *) (src2 + 3 * 16)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storeu_si128((__m128i *) dst, src1_r0); _mm_storeu_si128((__m128i *) (dst + stride), src1_r1); _mm_storeu_si128((__m128i *) (dst + 2 * stride), src1_r2); _mm_storeu_si128((__m128i *) (dst + 3 * stride), src1_r3); // Row 12-15 src1 += 4 * 16; src2 += 4 * 16; dst += 4 * stride; src1_r0 = _mm_loadu_si128((__m128i *) (src1)); src1_r1 = _mm_loadu_si128((__m128i *) (src1 + 16)); src1_r2 = _mm_loadu_si128((__m128i *) (src1 + 2 * 16)); src1_r3 = _mm_loadu_si128((__m128i *) (src1 + 3 * 16)); src2_r0 = _mm_loadu_si128((__m128i *) (src2)); src2_r1 = _mm_loadu_si128((__m128i *) (src2 + 16)); src2_r2 = _mm_loadu_si128((__m128i *) (src2 + 2 * 16)); src2_r3 = _mm_loadu_si128((__m128i *) (src2 + 3 * 16)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storeu_si128((__m128i *) dst, src1_r0); _mm_storeu_si128((__m128i *) (dst + stride), src1_r1); _mm_storeu_si128((__m128i *) (dst + 2 * stride), src1_r2); _mm_storeu_si128((__m128i *) (dst + 3 * stride), src1_r3); stride >>= 1; /*******************************************************/ /* interpolate U */ /*******************************************************/ src1 = buf_src1->pu1_u; src2 = buf_src2->pu1_u; dst = buf_dst->pu1_u; // Row 0-3 src1_r0 = _mm_loadl_epi64((__m128i *) (src1)); src1_r1 = _mm_loadl_epi64((__m128i *) (src1 + 8)); src1_r2 = _mm_loadl_epi64((__m128i *) (src1 + 2 * 8)); src1_r3 = _mm_loadl_epi64((__m128i *) (src1 + 3 * 8)); src2_r0 = _mm_loadl_epi64((__m128i *) (src2)); src2_r1 = _mm_loadl_epi64((__m128i *) (src2 + 8)); src2_r2 = _mm_loadl_epi64((__m128i *) (src2 + 2 * 8)); src2_r3 = _mm_loadl_epi64((__m128i *) (src2 + 3 * 8)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storel_epi64((__m128i *) dst, src1_r0); _mm_storel_epi64((__m128i *) (dst + stride), src1_r1); _mm_storel_epi64((__m128i *) (dst + 2 * stride), src1_r2); _mm_storel_epi64((__m128i *) (dst + 3 * stride), src1_r3); // Row 4-7 src1 += 4 * 8; src2 += 4 * 8; dst += 4 * stride; src1_r0 = _mm_loadl_epi64((__m128i *) (src1)); src1_r1 = _mm_loadl_epi64((__m128i *) (src1 + 8)); src1_r2 = _mm_loadl_epi64((__m128i *) (src1 + 2 * 8)); src1_r3 = _mm_loadl_epi64((__m128i *) (src1 + 3 * 8)); src2_r0 = _mm_loadl_epi64((__m128i *) (src2)); src2_r1 = _mm_loadl_epi64((__m128i *) (src2 + 8)); src2_r2 = _mm_loadl_epi64((__m128i *) (src2 + 2 * 8)); src2_r3 = _mm_loadl_epi64((__m128i *) (src2 + 3 * 8)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storel_epi64((__m128i *) dst, src1_r0); _mm_storel_epi64((__m128i *) (dst + stride), src1_r1); _mm_storel_epi64((__m128i *) (dst + 2 * stride), src1_r2); _mm_storel_epi64((__m128i *) (dst + 3 * stride), src1_r3); /*******************************************************/ /* interpolate V */ /*******************************************************/ src1 = buf_src1->pu1_v; src2 = buf_src2->pu1_v; dst = buf_dst->pu1_v; // Row 0-3 src1_r0 = _mm_loadl_epi64((__m128i *) (src1)); src1_r1 = _mm_loadl_epi64((__m128i *) (src1 + 8)); src1_r2 = _mm_loadl_epi64((__m128i *) (src1 + 2 * 8)); src1_r3 = _mm_loadl_epi64((__m128i *) (src1 + 3 * 8)); src2_r0 = _mm_loadl_epi64((__m128i *) (src2)); src2_r1 = _mm_loadl_epi64((__m128i *) (src2 + 8)); src2_r2 = _mm_loadl_epi64((__m128i *) (src2 + 2 * 8)); src2_r3 = _mm_loadl_epi64((__m128i *) (src2 + 3 * 8)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storel_epi64((__m128i *) dst, src1_r0); _mm_storel_epi64((__m128i *) (dst + stride), src1_r1); _mm_storel_epi64((__m128i *) (dst + 2 * stride), src1_r2); _mm_storel_epi64((__m128i *) (dst + 3 * stride), src1_r3); // Row 4-7 src1 += 4 * 8; src2 += 4 * 8; dst += 4 * stride; src1_r0 = _mm_loadl_epi64((__m128i *) (src1)); src1_r1 = _mm_loadl_epi64((__m128i *) (src1 + 8)); src1_r2 = _mm_loadl_epi64((__m128i *) (src1 + 2 * 8)); src1_r3 = _mm_loadl_epi64((__m128i *) (src1 + 3 * 8)); src2_r0 = _mm_loadl_epi64((__m128i *) (src2)); src2_r1 = _mm_loadl_epi64((__m128i *) (src2 + 8)); src2_r2 = _mm_loadl_epi64((__m128i *) (src2 + 2 * 8)); src2_r3 = _mm_loadl_epi64((__m128i *) (src2 + 3 * 8)); src1_r0 = _mm_avg_epu8 (src1_r0, src2_r0); src1_r1 = _mm_avg_epu8 (src1_r1, src2_r1); src1_r2 = _mm_avg_epu8 (src1_r2, src2_r2); src1_r3 = _mm_avg_epu8 (src1_r3, src2_r3); _mm_storel_epi64((__m128i *) dst, src1_r0); _mm_storel_epi64((__m128i *) (dst + stride), src1_r1); _mm_storel_epi64((__m128i *) (dst + 2 * stride), src1_r2); _mm_storel_epi64((__m128i *) (dst + 3 * stride), src1_r3); } /*****************************************************************************/ /* */ /* Function Name : impeg2_mc_halfx_halfy_8x8_sse42() */ /* */ /* Description : Gets the buffer from (0.5,0.5) to (8.5,8.5) */ /* and the above block of size 8 x 8 will be placed as a */ /* block from the current position of out_buf */ /* */ /* Inputs : ref - Reference frame from which the block will be */ /* block will be extracted. */ /* ref_wid - WIdth of reference frame */ /* out_wid - WIdth of the output frame */ /* blk_width - width of the block */ /* blk_width - height of the block */ /* */ /* Globals : None */ /* */ /* Processing : Point to the (0,0),(1,0),(0,1),(1,1) position in */ /* the ref frame.Interpolate these four values to get the */ /* value at(0.5,0.5).Repeat this to get an 8 x 8 block */ /* using 9 x 9 block from reference frame */ /* */ /* Outputs : out - Output containing the extracted block */ /* */ /* Returns : None */ /* */ /* Issues : None */ /* */ /*****************************************************************************/ void impeg2_mc_halfx_halfy_8x8_sse42(UWORD8 *out, UWORD8 *ref, UWORD32 ref_wid, UWORD32 out_wid) { UWORD8 *ref_p0,*ref_p1,*ref_p2,*ref_p3; /* P0-P3 are the pixels in the reference frame and Q is the value being */ /* estimated */ /* P0 P1 Q P2 P3 */ __m128i src_r0, src_r0_1, src_r1, src_r1_1; __m128i tmp0, tmp1; __m128i value_2 = _mm_set1_epi16(2); ref_p0 = ref; ref_p1 = ref + 1; ref_p2 = ref + ref_wid; ref_p3 = ref + ref_wid + 1; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p0)); //Row 0 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p1)); src_r1 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 1 src_r1_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); src_r1 = _mm_cvtepu8_epi16(src_r1); src_r1_1 = _mm_cvtepu8_epi16(src_r1_1); tmp0 = _mm_add_epi16(src_r0, src_r0_1); //Row 0 horizontal interpolation tmp1 = _mm_add_epi16(src_r1, src_r1_1); //Row 1 horizontal interpolation tmp0 = _mm_add_epi16(tmp0, tmp1); //Row 0 vertical interpolation tmp0 = _mm_add_epi16(tmp0, value_2); tmp0 = _mm_srli_epi16(tmp0, 2); tmp0 = _mm_packus_epi16(tmp0, value_2); _mm_storel_epi64((__m128i *)out, tmp0); //Row 1 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 2 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp0 = _mm_add_epi16(src_r0, src_r0_1); //Row 2 horizontal interpolation tmp1 = _mm_add_epi16(tmp0, tmp1); //Row 1 vertical interpolation tmp1 = _mm_add_epi16(tmp1, value_2); tmp1 = _mm_srli_epi16(tmp1, 2); tmp1 = _mm_packus_epi16(tmp1, value_2); _mm_storel_epi64((__m128i *)out, tmp1); //Row 2 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 3 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp1 = _mm_add_epi16(src_r0, src_r0_1); //Row 3 horizontal interpolation tmp0 = _mm_add_epi16(tmp0, tmp1); //Row 2 vertical interpolation tmp0 = _mm_add_epi16(tmp0, value_2); tmp0 = _mm_srli_epi16(tmp0, 2); tmp0 = _mm_packus_epi16(tmp0, value_2); _mm_storel_epi64((__m128i *)out, tmp0); //Row 3 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 4 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp0 = _mm_add_epi16(src_r0, src_r0_1); //Row 4 horizontal interpolation tmp1 = _mm_add_epi16(tmp0, tmp1); //Row 3 vertical interpolation tmp1 = _mm_add_epi16(tmp1, value_2); tmp1 = _mm_srli_epi16(tmp1, 2); tmp1 = _mm_packus_epi16(tmp1, value_2); _mm_storel_epi64((__m128i *)out, tmp1); //Row 4 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 5 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp1 = _mm_add_epi16(src_r0, src_r0_1); //Row 5 horizontal interpolation tmp0 = _mm_add_epi16(tmp0, tmp1); //Row 4 vertical interpolation tmp0 = _mm_add_epi16(tmp0, value_2); tmp0 = _mm_srli_epi16(tmp0, 2); tmp0 = _mm_packus_epi16(tmp0, value_2); _mm_storel_epi64((__m128i *)out, tmp0); //Row 5 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 6 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp0 = _mm_add_epi16(src_r0, src_r0_1); //Row 6 horizontal interpolation tmp1 = _mm_add_epi16(tmp0, tmp1); //Row 5 vertical interpolation tmp1 = _mm_add_epi16(tmp1, value_2); tmp1 = _mm_srli_epi16(tmp1, 2); tmp1 = _mm_packus_epi16(tmp1, value_2); _mm_storel_epi64((__m128i *)out, tmp1); //Row 6 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 7 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp1 = _mm_add_epi16(src_r0, src_r0_1); //Row 7 horizontal interpolation tmp0 = _mm_add_epi16(tmp0, tmp1); //Row 6 vertical interpolation tmp0 = _mm_add_epi16(tmp0, value_2); tmp0 = _mm_srli_epi16(tmp0, 2); tmp0 = _mm_packus_epi16(tmp0, value_2); _mm_storel_epi64((__m128i *)out, tmp0); //Row 7 ref_p2 += ref_wid; ref_p3 += ref_wid; out += out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p2)); //Row 8 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p3)); src_r0 = _mm_cvtepu8_epi16(src_r0); src_r0_1 = _mm_cvtepu8_epi16(src_r0_1); tmp0 = _mm_add_epi16(src_r0, src_r0_1); //Row 8 horizontal interpolation tmp1 = _mm_add_epi16(tmp0, tmp1); //Row 7 vertical interpolation tmp1 = _mm_add_epi16(tmp1, value_2); tmp1 = _mm_srli_epi16(tmp1, 2); tmp1 = _mm_packus_epi16(tmp1, value_2); _mm_storel_epi64((__m128i *)out, tmp1); return; } /*****************************************************************************/ /* */ /* Function Name : impeg2_mc_halfx_fully_8x8_sse42() */ /* */ /* Description : Gets the buffer from (0.5,0) to (8.5,8) */ /* and the above block of size 8 x 8 will be placed as a */ /* block from the current position of out_buf */ /* */ /* Inputs : ref - Reference frame from which the block will be */ /* block will be extracted. */ /* ref_wid - WIdth of reference frame */ /* out_wid - WIdth of the output frame */ /* blk_width - width of the block */ /* blk_width - height of the block */ /* */ /* Globals : None */ /* */ /* Processing : Point to the (0,0) and (1,0) position in the ref frame */ /* Interpolate these two values to get the value at(0.5,0) */ /* Repeat this to get an 8 x 8 block using 9 x 8 block from */ /* reference frame */ /* */ /* Outputs : out - Output containing the extracted block */ /* */ /* Returns : None */ /* */ /* Issues : None */ /* */ /*****************************************************************************/ void impeg2_mc_halfx_fully_8x8_sse42(UWORD8 *out, UWORD8 *ref, UWORD32 ref_wid, UWORD32 out_wid) { UWORD8 *ref_p0,*ref_p1; __m128i src_r0, src_r0_1, src_r1, src_r1_1; /* P0-P3 are the pixels in the reference frame and Q is the value being */ /* estimated */ /* P0 Q P1 */ ref_p0 = ref; ref_p1 = ref + 1; // Row 0 and 1 src_r0 = _mm_loadl_epi64((__m128i *) (ref_p0)); //Row 0 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p1)); src_r1 = _mm_loadl_epi64((__m128i *) (ref_p0 + ref_wid)); //Row 1 src_r1_1 = _mm_loadl_epi64((__m128i *) (ref_p1 + ref_wid)); src_r0 = _mm_avg_epu8(src_r0, src_r0_1); src_r1 = _mm_avg_epu8(src_r1, src_r1_1); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); // Row 2 and 3 ref_p0 += 2*ref_wid; ref_p1 += 2*ref_wid; out += 2*out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p0)); //Row 2 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p1)); src_r1 = _mm_loadl_epi64((__m128i *) (ref_p0 + ref_wid)); //Row 3 src_r1_1 = _mm_loadl_epi64((__m128i *) (ref_p1 + ref_wid)); src_r0 = _mm_avg_epu8(src_r0, src_r0_1); src_r1 = _mm_avg_epu8(src_r1, src_r1_1); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); // Row 4 and 5 ref_p0 += 2*ref_wid; ref_p1 += 2*ref_wid; out += 2*out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p0)); //Row 4 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p1)); src_r1 = _mm_loadl_epi64((__m128i *) (ref_p0 + ref_wid)); //Row 5 src_r1_1 = _mm_loadl_epi64((__m128i *) (ref_p1 + ref_wid)); src_r0 = _mm_avg_epu8(src_r0, src_r0_1); src_r1 = _mm_avg_epu8(src_r1, src_r1_1); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); // Row 6 and 7 ref_p0 += 2*ref_wid; ref_p1 += 2*ref_wid; out += 2*out_wid; src_r0 = _mm_loadl_epi64((__m128i *) (ref_p0)); //Row 6 src_r0_1 = _mm_loadl_epi64((__m128i *) (ref_p1)); src_r1 = _mm_loadl_epi64((__m128i *) (ref_p0 + ref_wid)); //Row 7 src_r1_1 = _mm_loadl_epi64((__m128i *) (ref_p1 + ref_wid)); src_r0 = _mm_avg_epu8(src_r0, src_r0_1); src_r1 = _mm_avg_epu8(src_r1, src_r1_1); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); return; } /*****************************************************************************/ /* */ /* Function Name : impeg2_mc_fullx_halfy_8x8_sse42() */ /* */ /* Description : Gets the buffer from (0,0.5) to (8,8.5) */ /* and the above block of size 8 x 8 will be placed as a */ /* block from the current position of out_buf */ /* */ /* Inputs : ref - Reference frame from which the block will be */ /* block will be extracted. */ /* ref_wid - WIdth of reference frame */ /* out_wid - WIdth of the output frame */ /* blk_width - width of the block */ /* blk_width - height of the block */ /* */ /* Globals : None */ /* */ /* Processing : Point to the (0,0) and (0,1) position in the ref frame */ /* Interpolate these two values to get the value at(0,0.5) */ /* Repeat this to get an 8 x 8 block using 8 x 9 block from */ /* reference frame */ /* */ /* Outputs : out - Output containing the extracted block */ /* */ /* Returns : None */ /* */ /* Issues : None */ /* */ /*****************************************************************************/ void impeg2_mc_fullx_halfy_8x8_sse42(UWORD8 *out, UWORD8 *ref, UWORD32 ref_wid, UWORD32 out_wid) { __m128i src_r0, src_r1, src_r2, temp0, temp1; /* P0-P3 are the pixels in the reference frame and Q is the value being */ /* estimated */ /* P0 x P1 */ src_r0 = _mm_loadl_epi64((__m128i *)ref); //Row 0 src_r1 = _mm_loadl_epi64((__m128i *)(ref + ref_wid)); //Row 1 src_r2 = _mm_loadl_epi64((__m128i *)(ref + 2 * ref_wid)); //Row 2 temp0 = _mm_avg_epu8(src_r0, src_r1); temp1 = _mm_avg_epu8(src_r1, src_r2); _mm_storel_epi64((__m128i *)out, temp0); //Row 0 _mm_storel_epi64((__m128i *)(out + out_wid), temp1); //Row 1 ref+= 3*ref_wid; out+= 2*out_wid; src_r0 = _mm_loadl_epi64((__m128i *)ref); //Row 3 src_r1 = _mm_loadl_epi64((__m128i *)(ref + ref_wid)); //Row 4 temp0 = _mm_avg_epu8(src_r2, src_r0); temp1 = _mm_avg_epu8(src_r0, src_r1); _mm_storel_epi64((__m128i *)out, temp0); //Row 2 _mm_storel_epi64((__m128i *)(out + out_wid), temp1); //Row 3 ref += 2*ref_wid; out+= 2*out_wid; src_r2 = _mm_loadl_epi64((__m128i *)ref); //Row 5 src_r0 = _mm_loadl_epi64((__m128i *)(ref + ref_wid)); //Row 6 temp0 = _mm_avg_epu8(src_r1, src_r2); temp1 = _mm_avg_epu8(src_r2, src_r0); _mm_storel_epi64((__m128i *)out, temp0); //Row 4 _mm_storel_epi64((__m128i *)(out + out_wid), temp1); //Row 5 ref += 2*ref_wid; out+= 2*out_wid; src_r1 = _mm_loadl_epi64((__m128i *)ref); //Row 7 src_r2 = _mm_loadl_epi64((__m128i *) (ref + ref_wid)); //Row 8 temp0 = _mm_avg_epu8(src_r0, src_r1); temp1 = _mm_avg_epu8(src_r1, src_r2); _mm_storel_epi64((__m128i *)out, temp0); //Row 6 _mm_storel_epi64((__m128i *)(out + out_wid), temp1); //Row 7 return; } /*****************************************************************************/ /* */ /* Function Name : impeg2_mc_fullx_fully_8x8_sse42() */ /* */ /* Description : Gets the buffer from (x,y) to (x+8,y+8) */ /* and the above block of size 8 x 8 will be placed as a */ /* block from the current position of out_buf */ /* */ /* Inputs : ref - Reference frame from which the block will be */ /* block will be extracted. */ /* ref_wid - WIdth of reference frame */ /* out_wid - WIdth of the output frame */ /* blk_width - width of the block */ /* blk_width - height of the block */ /* */ /* Globals : None */ /* */ /* Processing : Point to the (0,0) position in the ref frame */ /* Get an 8 x 8 block from reference frame */ /* */ /* Outputs : out - Output containing the extracted block */ /* */ /* Returns : None */ /* */ /* Issues : None */ /* */ /*****************************************************************************/ void impeg2_mc_fullx_fully_8x8_sse42(UWORD8 *out, UWORD8 *ref, UWORD32 ref_wid, UWORD32 out_wid) { __m128i src_r0, src_r1, src_r2, src_r3; // Row 0-3 src_r0 = _mm_loadl_epi64((__m128i *)ref); src_r1 = _mm_loadl_epi64((__m128i *)(ref + ref_wid)); src_r2 = _mm_loadl_epi64((__m128i *)(ref + 2 * ref_wid)); src_r3 = _mm_loadl_epi64((__m128i *)(ref + 3 * ref_wid)); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); _mm_storel_epi64((__m128i *)(out + 2 * out_wid), src_r2); _mm_storel_epi64((__m128i *)(out + 3 * out_wid), src_r3); // Row 4-7 ref += 4 * ref_wid; out += 4 * out_wid; src_r0 = _mm_loadl_epi64((__m128i *)ref); src_r1 = _mm_loadl_epi64((__m128i *)(ref + ref_wid)); src_r2 = _mm_loadl_epi64((__m128i *)(ref + 2 * ref_wid)); src_r3 = _mm_loadl_epi64((__m128i *)(ref + 3 * ref_wid)); _mm_storel_epi64((__m128i *)out, src_r0); _mm_storel_epi64((__m128i *)(out + out_wid), src_r1); _mm_storel_epi64((__m128i *)(out + 2 * out_wid), src_r2); _mm_storel_epi64((__m128i *)(out + 3 * out_wid), src_r3); return; }