298 lines · 10.8 KB · C++
RawDownload
/*! * \copy *     Copyright (c)  2013, Cisco Systems *     All rights reserved. * *     Redistribution and use in source and binary forms, with or without *     modification, are permitted provided that the following conditions *     are met: * *        * Redistributions of source code must retain the above copyright *          notice, this list of conditions and the following disclaimer. * *        * Redistributions in binary form must reproduce the above copyright *          notice, this list of conditions and the following disclaimer in *          the documentation and/or other materials provided with the *          distribution. * *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *     POSSIBILITY OF SUCH DAMAGE. * */ #include "decode_mb_aux.h"#include "cpu_core.h" namespace WelsEnc {/**************************************************************************** * Dequant and Ihdm functions ****************************************************************************/void WelsIHadamard4x4Dc (int16_t* pRes) { //pBuffer size : 4x4  int16_t iTemp[4];  int32_t i	= 4;   while (--i >= 0) {    const int32_t kiIdx	= i << 2;    const int32_t kiIdx1	= 1 + kiIdx;    const int32_t kiIdx2	= 1 + kiIdx1;    const int32_t kiIdx3	= 1 + kiIdx2;     iTemp[0] = pRes[kiIdx ] + pRes[kiIdx2];    iTemp[1] = pRes[kiIdx ] - pRes[kiIdx2];    iTemp[2] = pRes[kiIdx1] - pRes[kiIdx3];    iTemp[3] = pRes[kiIdx1] + pRes[kiIdx3];     pRes[kiIdx ] = iTemp[0] + iTemp[3];    pRes[kiIdx1] = iTemp[1] + iTemp[2];    pRes[kiIdx2] = iTemp[1] - iTemp[2];    pRes[kiIdx3] = iTemp[0] - iTemp[3];  }   i = 4;  while (--i >= 0) {    const int32_t kiI4	= 4 + i;    const int32_t kiI8	= 4 + kiI4;    const int32_t kiI12	= 4 + kiI8;     iTemp[0] = pRes[i  ] + pRes[kiI8 ];    iTemp[1] = pRes[i  ] - pRes[kiI8 ];    iTemp[2] = pRes[kiI4 ] - pRes[kiI12];    iTemp[3] = pRes[kiI4 ] + pRes[kiI12];     pRes[i  ] = iTemp[0] + iTemp[3];    pRes[kiI4 ] = iTemp[1] + iTemp[2];    pRes[kiI8 ] = iTemp[1] - iTemp[2];    pRes[kiI12] = iTemp[0] - iTemp[3];  }} /* for qp < 12 */void WelsDequantLumaDc4x4 (int16_t* pRes, const int32_t kiQp) {  int32_t i	= 15;  const uint16_t kuiDequantValue	= g_kuiDequantCoeff[kiQp % 6][0];  const int16_t kiQF0		= kiQp / 6;  const int16_t kiQF1		= 2 - kiQF0;  const int16_t kiQF0S	= 1 << (1 - kiQF0);   while (i >= 0) {    pRes[i  ] = (pRes[i  ] * kuiDequantValue + kiQF0S) >> kiQF1;    pRes[i - 1] = (pRes[i - 1] * kuiDequantValue + kiQF0S) >> kiQF1;    pRes[i - 2] = (pRes[i - 2] * kuiDequantValue + kiQF0S) >> kiQF1;    pRes[i - 3] = (pRes[i - 3] * kuiDequantValue + kiQF0S) >> kiQF1;     i -= 4;  }} /* for qp >= 12 */void WelsDequantIHadamard4x4_c (int16_t* pRes, const uint16_t kuiMF) {  int16_t iTemp[4];  int32_t i;   for (i = 0; i < 16; i += 4) {    iTemp[0] = pRes[i  ] + pRes[i + 2];    iTemp[1] = pRes[i  ] - pRes[i + 2];    iTemp[2] = pRes[i + 1] - pRes[i + 3];    iTemp[3] = pRes[i + 1] + pRes[i + 3];     pRes[i  ] = iTemp[0] + iTemp[3];    pRes[i + 1] = iTemp[1] + iTemp[2];    pRes[i + 2] = iTemp[1] - iTemp[2];    pRes[i + 3] = iTemp[0] - iTemp[3];  }   for (i = 0; i < 4; i++) {    iTemp[0] = pRes[i   ] + pRes[i + 8 ];    iTemp[1] = pRes[i   ] - pRes[i + 8 ];    iTemp[2] = pRes[i + 4 ] - pRes[i + 12];    iTemp[3] = pRes[i + 4 ] + pRes[i + 12];     pRes[i  ]  = (iTemp[0] + iTemp[3]) * kuiMF;    pRes[i + 4 ] = (iTemp[1] + iTemp[2]) * kuiMF;    pRes[i + 8 ] = (iTemp[1] - iTemp[2]) * kuiMF;    pRes[i + 12] = (iTemp[0] - iTemp[3]) * kuiMF;  }} void WelsDequantIHadamard2x2Dc (int16_t* pDct, const uint16_t kuiMF) {  const int16_t kiSumU = pDct[0] + pDct[2];  const int16_t kiDelU =   pDct[0] -  pDct[2];  const int16_t kiSumD = pDct[1] + pDct[3];  const int16_t kiDelD =   pDct[1] -  pDct[3];   pDct[0] = ((kiSumU + kiSumD) * kuiMF) >> 1;  pDct[1] = ((kiSumU - kiSumD) * kuiMF) >> 1;  pDct[2] = ((kiDelU + kiDelD) * kuiMF) >> 1;  pDct[3] = ((kiDelU - kiDelD) * kuiMF) >> 1;} void WelsDequant4x4_c (int16_t* pRes, const uint16_t* kpMF) {  int32_t i;  for (i = 0; i < 8; i++) {    pRes[i]	*=	kpMF[i];    pRes[i + 8]	*= kpMF[i];  }} void WelsDequantFour4x4_c (int16_t* pRes, const uint16_t* kpMF) {  int32_t i;  for (i = 0; i < 8; i++) {    pRes[i]	*=	kpMF[i];    pRes[i + 8]	*=	kpMF[i];    pRes[i + 16] *=	kpMF[i];    pRes[i + 24] *=	kpMF[i];    pRes[i + 32] *=	kpMF[i];    pRes[i + 40] *=	kpMF[i];    pRes[i + 48] *=	kpMF[i];    pRes[i + 56] *=	kpMF[i];  }} /**************************************************************************** * IDCT functions, final output = prediction(CS) + IDCT(scaled_coeff) ****************************************************************************/void WelsIDctT4Rec_c (uint8_t* pRec, int32_t iStride, uint8_t* pPred, int32_t iPredStride, int16_t* pDct) {  int32_t i;  int16_t iTemp[16];   int32_t iDstStridex2 = iStride << 1;  int32_t iDstStridex3 = iStride + iDstStridex2;  int32_t iPredStridex2 = iPredStride << 1;  int32_t iPredStridex3 = iPredStride + iPredStridex2;   for (i = 0; i < 4; i ++) { //horizon    int32_t iIdx = i << 2;    const int32_t kiHorSumU = pDct[iIdx] + pDct[iIdx + 2];	// add 0-2    const int32_t kiHorDelU = pDct[iIdx] - pDct[iIdx + 2];	// sub 0-2    const int32_t kiHorSumD = pDct[iIdx + 1] + (pDct[iIdx + 3] >> 1);    const int32_t kiHorDelD = (pDct[iIdx + 1] >> 1) - pDct[iIdx + 3];     iTemp[iIdx  ]   = kiHorSumU  + kiHorSumD;    iTemp[iIdx + 1] = kiHorDelU   + kiHorDelD;    iTemp[iIdx + 2] = kiHorDelU   -  kiHorDelD;    iTemp[iIdx + 3] = kiHorSumU  -  kiHorSumD;  }   for (i = 0; i < 4; i ++) { //vertical    const int32_t kiVerSumL = iTemp[i]                 + iTemp[8 + i];    const int32_t kiVerDelL   = iTemp[i]                 - iTemp[8 + i];    const int32_t kiVerDelR   = (iTemp[4 + i] >> 1) - iTemp[12 + i];    const int32_t kiVerSumR = iTemp[4 + i]             + (iTemp[12 + i] >> 1);     pRec[i				]         = WelsClip1 (pPred[i              ]         + ((kiVerSumL + kiVerSumR + 32) >> 6));    pRec[iStride + i		]     = WelsClip1 (pPred[iPredStride + i  ]  + ((kiVerDelL + kiVerDelR + 32) >> 6));    pRec[iDstStridex2 + i] = WelsClip1 (pPred[iPredStridex2 + i] + ((kiVerDelL - kiVerDelR + 32) >> 6));    pRec[iDstStridex3 + i] = WelsClip1 (pPred[iPredStridex3 + i] + ((kiVerSumL - kiVerSumR + 32) >> 6));  }} void WelsIDctFourT4Rec_c (uint8_t* pRec, int32_t iStride, uint8_t* pPred, int32_t iPredStride, int16_t* pDct) {  int32_t iDstStridex4  = iStride << 2;  int32_t iPredStridex4 = iPredStride << 2;  WelsIDctT4Rec_c (pRec,                  iStride, pPred,						iPredStride, pDct);  WelsIDctT4Rec_c (&pRec[4],              iStride, &pPred[4],					iPredStride, pDct + 16);  WelsIDctT4Rec_c (&pRec[iDstStridex4  ], iStride, &pPred[iPredStridex4  ],	iPredStride, pDct + 32);  WelsIDctT4Rec_c (&pRec[iDstStridex4 + 4], iStride, &pPred[iPredStridex4 + 4],	iPredStride, pDct + 48); } void WelsIDctT4RecOnMb (uint8_t* pDst, int32_t iDstStride, uint8_t* pPred, int32_t iPredStride, int16_t* pDct,                        PIDctFunc pfIDctFourT4) {  int32_t iDstStridex8  = iDstStride << 3;  int32_t iPredStridex8 = iPredStride << 3;   pfIDctFourT4 (&pDst[0], iDstStride, &pPred[0], iPredStride, pDct);  pfIDctFourT4 (&pDst[8], iDstStride, &pPred[8], iPredStride, pDct + 64);  pfIDctFourT4 (&pDst[iDstStridex8], iDstStride, &pPred[iPredStridex8], iPredStride, pDct + 128);  pfIDctFourT4 (&pDst[iDstStridex8 + 8], iDstStride, &pPred[iPredStridex8 + 8], iPredStride, pDct + 192);} /* * pfIDctI16x16Dc: do luma idct of an MB for I16x16 mode, when only dc value are non-zero */void WelsIDctRecI16x16Dc_c (uint8_t* pRec, int32_t iStride, uint8_t* pPred, int32_t iPredStride, int16_t* pDctDc) {  int32_t i, j;   for (i = 0; i < 16; i ++) {    for (j = 0; j < 16; j++) {      pRec[j] = WelsClip1 (pPred[j] + ((pDctDc[ (i & 0x0C) + (j >> 2)] + 32) >> 6));    }    pRec += iStride;    pPred += iPredStride;  }} void WelsGetEncBlockStrideOffset (int32_t* pBlock, const int32_t kiStrideY, const int32_t kiStrideUV) {  int32_t i, j, k, r;  for (j = 0; j < 4; j++) {    i = j << 2;    k = (j & 0x01) << 1;    r = j & 0x02;    pBlock[i]		= (0 + k + (0 + r) * kiStrideY) << 2;    pBlock[i + 1]	= (1 + k + (0 + r) * kiStrideY) << 2;    pBlock[i + 2]	= (0 + k + (1 + r) * kiStrideY) << 2;    pBlock[i + 3]	= (1 + k + (1 + r) * kiStrideY) << 2;     pBlock[16 + j]	=      pBlock[20 + j]	= ((j & 0x01) + r * kiStrideUV) << 2;  }} void WelsInitReconstructionFuncs (SWelsFuncPtrList* pFuncList, uint32_t  uiCpuFlag) {  pFuncList->pfDequantization4x4			= WelsDequant4x4_c;  pFuncList->pfDequantizationFour4x4		= WelsDequantFour4x4_c;  pFuncList->pfDequantizationIHadamard4x4	= WelsDequantIHadamard4x4_c;   pFuncList->pfIDctT4		= WelsIDctT4Rec_c;  pFuncList->pfIDctFourT4		= WelsIDctFourT4Rec_c;  pFuncList->pfIDctI16x16Dc = WelsIDctRecI16x16Dc_c; #if defined(X86_ASM)  if (uiCpuFlag & WELS_CPU_MMXEXT) {    pFuncList->pfIDctT4		= WelsIDctT4Rec_mmx;  }  if (uiCpuFlag & WELS_CPU_SSE2) {    pFuncList->pfDequantization4x4			= WelsDequant4x4_sse2;    pFuncList->pfDequantizationFour4x4		= WelsDequantFour4x4_sse2;    pFuncList->pfDequantizationIHadamard4x4	= WelsDequantIHadamard4x4_sse2;     pFuncList->pfIDctFourT4		= WelsIDctFourT4Rec_sse2;    pFuncList->pfIDctI16x16Dc = WelsIDctRecI16x16Dc_sse2;  }#endif//X86_ASM #if defined(HAVE_NEON)  if (uiCpuFlag & WELS_CPU_NEON) {    pFuncList->pfDequantization4x4			= WelsDequant4x4_neon;    pFuncList->pfDequantizationFour4x4		= WelsDequantFour4x4_neon;    pFuncList->pfDequantizationIHadamard4x4	= WelsDequantIHadamard4x4_neon;     pFuncList->pfIDctFourT4		= WelsIDctFourT4Rec_neon;    pFuncList->pfIDctT4		= WelsIDctT4Rec_neon;    pFuncList->pfIDctI16x16Dc = WelsIDctRecI16x16Dc_neon;  }#endif #if defined(HAVE_NEON_AARCH64)  if (uiCpuFlag & WELS_CPU_NEON) {    pFuncList->pfDequantization4x4			= WelsDequant4x4_AArch64_neon;    pFuncList->pfDequantizationFour4x4		= WelsDequantFour4x4_AArch64_neon;    pFuncList->pfDequantizationIHadamard4x4	= WelsDequantIHadamard4x4_AArch64_neon;     pFuncList->pfIDctFourT4		= WelsIDctFourT4Rec_AArch64_neon;    pFuncList->pfIDctT4		= WelsIDctT4Rec_AArch64_neon;    pFuncList->pfIDctI16x16Dc = WelsIDctRecI16x16Dc_AArch64_neon;  }#endif}}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t