Showing the changes to codec/processing/src (43 of 124 files). Show all
Unified · Split
| @@ -0,0 +1,256 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | #include "AdaptiveQuantization.h" | ||
| 33 | #include "../common/cpu.h" | ||
| 34 | |||
| 35 | WELSVP_NAMESPACE_BEGIN | ||
| 36 | |||
| 37 | |||
| 38 | |||
| 39 | #define AVERAGE_TIME_MOTION (0.3) //0.3046875 // 1/4 + 1/16 - 1/128 ~ 0.3 | ||
| 40 | #define AVERAGE_TIME_TEXTURE_QUALITYMODE (1.0) //0.5 // 1/2 | ||
| 41 | #define AVERAGE_TIME_TEXTURE_BITRATEMODE (0.875) //0.5 // 1/2 | ||
| 42 | #define MODEL_ALPHA (0.9910) //1.5 //1.1102 | ||
| 43 | #define MODEL_TIME (5.8185) //9.0 //5.9842 | ||
| 44 | |||
| 45 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 46 | |||
| 47 | CAdaptiveQuantization::CAdaptiveQuantization (int32_t iCpuFlag) { | ||
| 48 | m_CPUFlag = iCpuFlag; | ||
| 49 | m_eMethod = METHOD_ADAPTIVE_QUANT; | ||
| 50 | m_pfVar = NULL; | ||
| 51 | WelsMemset (&m_sAdaptiveQuantParam, 0, sizeof (m_sAdaptiveQuantParam)); | ||
| 52 | WelsInitVarFunc (m_pfVar, m_CPUFlag); | ||
| 53 | } | ||
| 54 | |||
| 55 | CAdaptiveQuantization::~CAdaptiveQuantization() { | ||
| 56 | } | ||
| 57 | |||
| 58 | EResult CAdaptiveQuantization::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 59 | EResult eReturn = RET_INVALIDPARAM; | ||
| 60 | |||
| 61 | int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 62 | int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 63 | int32_t iMbWidth = iWidth >> 4; | ||
| 64 | int32_t iMbHeight = iHeight >> 4; | ||
| 65 | int32_t iMbTotalNum = iMbWidth * iMbHeight; | ||
| 66 | |||
| 67 | SMotionTextureUnit* pMotionTexture = NULL; | ||
| 68 | SVAACalcResult* pVaaCalcResults = NULL; | ||
| 69 | int8_t iMotionTextureIndexToDeltaQp = 0; | ||
| 70 | int32_t iAverMotionTextureIndexToDeltaQp = 0; // double to uint32 | ||
| 71 | double_t dAverageMotionIndex = 0.0; // double to float | ||
| 72 | double_t dAverageTextureIndex = 0.0; | ||
| 73 | |||
| 74 | double_t dQStep = 0.0; | ||
| 75 | double_t dLumaMotionDeltaQp = 0; | ||
| 76 | double_t dLumaTextureDeltaQp = 0; | ||
| 77 | |||
| 78 | uint8_t* pRefFrameY = NULL, *pCurFrameY = NULL; | ||
| 79 | int32_t iRefStride = 0, iCurStride = 0; | ||
| 80 | |||
| 81 | uint8_t* pRefFrameTmp = NULL, *pCurFrameTmp = NULL; | ||
| 82 | int32_t i = 0, j = 0; | ||
| 83 | |||
| 84 | pRefFrameY = (uint8_t*)pRefPixMap->pPixel[0]; | ||
| 85 | pCurFrameY = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 86 | |||
| 87 | iRefStride = pRefPixMap->iStride[0]; | ||
| 88 | iCurStride = pSrcPixMap->iStride[0]; | ||
| 89 | |||
| 90 | /////////////////////////////////////// motion ////////////////////////////////// | ||
| 91 | // motion MB residual variance | ||
| 92 | dAverageMotionIndex = 0.0; | ||
| 93 | dAverageTextureIndex = 0.0; | ||
| 94 | pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit; | ||
| 95 | pVaaCalcResults = m_sAdaptiveQuantParam.pCalcResult; | ||
| 96 | |||
| 97 | if (pVaaCalcResults->pRefY == pRefFrameY && pVaaCalcResults->pCurY == pCurFrameY) { | ||
| 98 | int32_t iMbIndex = 0; | ||
| 99 | int32_t iSumDiff, iSQDiff, uiSum, iSQSum; | ||
| 100 | for (j = 0; j < iMbHeight; j ++) { | ||
| 101 | pRefFrameTmp = pRefFrameY; | ||
| 102 | pCurFrameTmp = pCurFrameY; | ||
| 103 | for (i = 0; i < iMbWidth; i++) { | ||
| 104 | iSumDiff = pVaaCalcResults->pSad8x8[iMbIndex][0]; | ||
| 105 | iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][1]; | ||
| 106 | iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][2]; | ||
| 107 | iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][3]; | ||
| 108 | |||
| 109 | iSQDiff = pVaaCalcResults->pSsd16x16[iMbIndex]; | ||
| 110 | uiSum = pVaaCalcResults->pSum16x16[iMbIndex]; | ||
| 111 | iSQSum = pVaaCalcResults->pSumOfSquare16x16[iMbIndex]; | ||
| 112 | |||
| 113 | iSumDiff = iSumDiff >> 8; | ||
| 114 | pMotionTexture->uiMotionIndex = (iSQDiff >> 8) - (iSumDiff * iSumDiff); | ||
| 115 | |||
| 116 | uiSum = uiSum >> 8; | ||
| 117 | pMotionTexture->uiTextureIndex = (iSQSum >> 8) - (uiSum * uiSum); | ||
| 118 | |||
| 119 | dAverageMotionIndex += pMotionTexture->uiMotionIndex; | ||
| 120 | dAverageTextureIndex += pMotionTexture->uiTextureIndex; | ||
| 121 | pMotionTexture++; | ||
| 122 | ++iMbIndex; | ||
| 123 | pRefFrameTmp += MB_WIDTH_LUMA; | ||
| 124 | pCurFrameTmp += MB_WIDTH_LUMA; | ||
| 125 | } | ||
| 126 | pRefFrameY += (iRefStride) << 4; | ||
| 127 | pCurFrameY += (iCurStride) << 4; | ||
| 128 | } | ||
| 129 | } else { | ||
| 130 | for (j = 0; j < iMbHeight; j ++) { | ||
| 131 | pRefFrameTmp = pRefFrameY; | ||
| 132 | pCurFrameTmp = pCurFrameY; | ||
| 133 | for (i = 0; i < iMbWidth; i++) { | ||
| 134 | m_pfVar (pRefFrameTmp, iRefStride, pCurFrameTmp, iCurStride, pMotionTexture); | ||
| 135 | dAverageMotionIndex += pMotionTexture->uiMotionIndex; | ||
| 136 | dAverageTextureIndex += pMotionTexture->uiTextureIndex; | ||
| 137 | pMotionTexture++; | ||
| 138 | pRefFrameTmp += MB_WIDTH_LUMA; | ||
| 139 | pCurFrameTmp += MB_WIDTH_LUMA; | ||
| 140 | |||
| 141 | } | ||
| 142 | pRefFrameY += (iRefStride) << 4; | ||
| 143 | pCurFrameY += (iCurStride) << 4; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | dAverageMotionIndex = dAverageMotionIndex / iMbTotalNum; | ||
| 147 | dAverageTextureIndex = dAverageTextureIndex / iMbTotalNum; | ||
| 148 | if ((dAverageMotionIndex <= PESN) && (dAverageMotionIndex >= -PESN)) { | ||
| 149 | dAverageMotionIndex = 1.0; | ||
| 150 | } | ||
| 151 | if ((dAverageTextureIndex <= PESN) && (dAverageTextureIndex >= -PESN)) { | ||
| 152 | dAverageTextureIndex = 1.0; | ||
| 153 | } | ||
| 154 | // motion mb residual map to QP | ||
| 155 | // texture mb original map to QP | ||
| 156 | iAverMotionTextureIndexToDeltaQp = 0; | ||
| 157 | dAverageMotionIndex = AVERAGE_TIME_MOTION * dAverageMotionIndex; | ||
| 158 | |||
| 159 | if (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE) { | ||
| 160 | dAverageTextureIndex = AVERAGE_TIME_TEXTURE_QUALITYMODE * dAverageTextureIndex; | ||
| 161 | } else { | ||
| 162 | dAverageTextureIndex = AVERAGE_TIME_TEXTURE_BITRATEMODE * dAverageTextureIndex; | ||
| 163 | } | ||
| 164 | |||
| 165 | pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit; | ||
| 166 | for (j = 0; j < iMbHeight; j ++) { | ||
| 167 | for (i = 0; i < iMbWidth; i++) { | ||
| 168 | double_t a = pMotionTexture->uiTextureIndex / dAverageTextureIndex; | ||
| 169 | dQStep = (a - 1) / (a + MODEL_ALPHA); | ||
| 170 | dLumaTextureDeltaQp = MODEL_TIME * dQStep;// range +- 6 | ||
| 171 | |||
| 172 | iMotionTextureIndexToDeltaQp = (int8_t)dLumaTextureDeltaQp; | ||
| 173 | |||
| 174 | a = pMotionTexture->uiMotionIndex / dAverageMotionIndex; | ||
| 175 | dQStep = (a - 1) / (a + MODEL_ALPHA); | ||
| 176 | dLumaMotionDeltaQp = MODEL_TIME * dQStep;// range +- 6 | ||
| 177 | |||
| 178 | if ((m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_QUALITY_MODE && dLumaMotionDeltaQp < -PESN) | ||
| 179 | || (m_sAdaptiveQuantParam.iAdaptiveQuantMode == AQ_BITRATE_MODE)) { | ||
| 180 | iMotionTextureIndexToDeltaQp += (int8_t)dLumaMotionDeltaQp; | ||
| 181 | } | ||
| 182 | |||
| 183 | m_sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[j * iMbWidth + i] = iMotionTextureIndexToDeltaQp; | ||
| 184 | iAverMotionTextureIndexToDeltaQp += iMotionTextureIndexToDeltaQp; | ||
| 185 | pMotionTexture++; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp = (1.0 * iAverMotionTextureIndexToDeltaQp) / iMbTotalNum; | ||
| 189 | |||
| 190 | eReturn = RET_SUCCESS; | ||
| 191 | |||
| 192 | return eReturn; | ||
| 193 | } | ||
| 194 | |||
| 195 | |||
| 196 | |||
| 197 | EResult CAdaptiveQuantization::Set (int32_t iType, void* pParam) { | ||
| 198 | if (pParam == NULL) { | ||
| 199 | return RET_INVALIDPARAM; | ||
| 200 | } | ||
| 201 | |||
| 202 | m_sAdaptiveQuantParam = * (SAdaptiveQuantizationParam*)pParam; | ||
| 203 | |||
| 204 | return RET_SUCCESS; | ||
| 205 | } | ||
| 206 | |||
| 207 | EResult CAdaptiveQuantization::Get (int32_t iType, void* pParam) { | ||
| 208 | if (pParam == NULL) { | ||
| 209 | return RET_INVALIDPARAM; | ||
| 210 | } | ||
| 211 | |||
| 212 | SAdaptiveQuantizationParam* sAdaptiveQuantParam = (SAdaptiveQuantizationParam*)pParam; | ||
| 213 | |||
| 214 | sAdaptiveQuantParam->dAverMotionTextureIndexToDeltaQp = m_sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp; | ||
| 215 | |||
| 216 | return RET_SUCCESS; | ||
| 217 | } | ||
| 218 | |||
| 219 | /////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 220 | |||
| 221 | void CAdaptiveQuantization::WelsInitVarFunc (PVarFunc& pfVar, int32_t iCpuFlag) { | ||
| 222 | pfVar = SampleVariance16x16_c; | ||
| 223 | |||
| 224 | #ifdef X86_ASM | ||
| 225 | if (iCpuFlag & WELS_CPU_SSE2) { | ||
| 226 | // pfVar = SampleVariance16x16_sse2; | ||
| 227 | } | ||
| 228 | #endif | ||
| 229 | } | ||
| 230 | |||
| 231 | void SampleVariance16x16_c (uint8_t* pRefY, int32_t iRefStride, uint8_t* pSrcY, int32_t iSrcStride, | ||
| 232 | SMotionTextureUnit* pMotionTexture) { | ||
| 233 | uint32_t uiCurSquare = 0, uiSquare = 0; | ||
| 234 | uint16_t uiCurSum = 0, uiSum = 0; | ||
| 235 | |||
| 236 | for (int32_t y = 0; y < MB_WIDTH_LUMA; y++) { | ||
| 237 | for (int32_t x = 0; x < MB_WIDTH_LUMA; x++) { | ||
| 238 | uint32_t uiDiff = WELS_ABS (pRefY[x] - pSrcY[x]); | ||
| 239 | uiSum += uiDiff; | ||
| 240 | uiSquare += uiDiff * uiDiff; | ||
| 241 | |||
| 242 | uiCurSum += pSrcY[x]; | ||
| 243 | uiCurSquare += pSrcY[x] * pSrcY[x]; | ||
| 244 | } | ||
| 245 | pRefY += iRefStride; | ||
| 246 | pSrcY += iSrcStride; | ||
| 247 | } | ||
| 248 | |||
| 249 | uiSum = uiSum >> 8; | ||
| 250 | pMotionTexture->uiMotionIndex = (uiSquare >> 8) - (uiSum * uiSum); | ||
| 251 | |||
| 252 | uiCurSum = uiCurSum >> 8; | ||
| 253 | pMotionTexture->uiTextureIndex = (uiCurSquare >> 8) - (uiCurSum * uiCurSum); | ||
| 254 | } | ||
| 255 | |||
| 256 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,85 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : AdaptiveQuantization.h | ||
| 32 | * | ||
| 33 | * \brief : adaptive quantization class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/21 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of scene change detection class | ||
| 38 | * | ||
| 39 | */ | ||
| 40 | |||
| 41 | #ifndef WELSVP_ADAPTIVEQUANTIZATION_H | ||
| 42 | #define WELSVP_ADAPTIVEQUANTIZATION_H | ||
| 43 | |||
| 44 | #include "../common/util.h" | ||
| 45 | #include "../common/memory.h" | ||
| 46 | #include "../common/WelsFrameWork.h" | ||
| 47 | #include "../../interface/IWelsVP.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | typedef void (VarFunc) (uint8_t* pRefY, int32_t iRefStrideY, uint8_t* pSrc, int32_t iSrcStrideY, | ||
| 52 | SMotionTextureUnit* pMotionTexture); | ||
| 53 | |||
| 54 | typedef VarFunc* PVarFunc; | ||
| 55 | |||
| 56 | VarFunc SampleVariance16x16_c; | ||
| 57 | |||
| 58 | #ifdef X86_ASM | ||
| 59 | WELSVP_EXTERN_C_BEGIN | ||
| 60 | VarFunc SampleVariance16x16_sse2; | ||
| 61 | WELSVP_EXTERN_C_END | ||
| 62 | #endif | ||
| 63 | |||
| 64 | |||
| 65 | class CAdaptiveQuantization : public IStrategy { | ||
| 66 | public: | ||
| 67 | CAdaptiveQuantization (int32_t iCpuFlag); | ||
| 68 | ~CAdaptiveQuantization(); | ||
| 69 | |||
| 70 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef); | ||
| 71 | EResult Set (int32_t iType, void* pParam); | ||
| 72 | EResult Get (int32_t iType, void* pParam); | ||
| 73 | |||
| 74 | private: | ||
| 75 | void WelsInitVarFunc (PVarFunc& pfVar, int32_t iCpuFlag); | ||
| 76 | |||
| 77 | private: | ||
| 78 | PVarFunc m_pfVar; | ||
| 79 | int32_t m_CPUFlag; | ||
| 80 | SAdaptiveQuantizationParam m_sAdaptiveQuantParam; | ||
| 81 | }; | ||
| 82 | |||
| 83 | WELSVP_NAMESPACE_END | ||
| 84 | |||
| 85 | #endif | ||
| @@ -0,0 +1,279 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2010-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | ;* predenoise.asm | ||
| 33 | ;* | ||
| 34 | ;* Abstract | ||
| 35 | ;* denoise for SVC2.1 | ||
| 36 | ;* History | ||
| 37 | ;* 4/13/2010 Created | ||
| 38 | ;* 7/30/2010 Modified | ||
| 39 | ;* | ||
| 40 | ;* | ||
| 41 | ;*************************************************************************/ | ||
| 42 | %include "asm_inc.asm" | ||
| 43 | |||
| 44 | ;*********************************************************************** | ||
| 45 | ; Constant | ||
| 46 | ;*********************************************************************** | ||
| 47 | SECTION .rodata align=16 | ||
| 48 | |||
| 49 | sse2_32 times 8 dw 32 | ||
| 50 | sse2_20 times 8 dw 20 | ||
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | ;*********************************************************************** | ||
| 55 | ; Code | ||
| 56 | ;*********************************************************************** | ||
| 57 | SECTION .text | ||
| 58 | |||
| 59 | %macro WEIGHT_LINE 9 | ||
| 60 | movq %2, %9 | ||
| 61 | punpcklbw %2, %7 | ||
| 62 | movdqa %8, %2 | ||
| 63 | |||
| 64 | movdqa %1, %6 | ||
| 65 | psubusb %1, %8 | ||
| 66 | psubusb %8, %6 | ||
| 67 | por %8, %1 ; ABS(curPixel - centerPixel); | ||
| 68 | |||
| 69 | movdqa %1, %3 | ||
| 70 | psubusb %1, %8 | ||
| 71 | |||
| 72 | pmullw %1, %1 | ||
| 73 | psrlw %1, 5 | ||
| 74 | pmullw %2, %1 | ||
| 75 | paddusw %4, %1 | ||
| 76 | paddusw %5, %2 | ||
| 77 | %endmacro | ||
| 78 | |||
| 79 | %macro WEIGHT_LINE1_UV 4 | ||
| 80 | movdqa %2, %1 | ||
| 81 | punpcklbw %2, %4 | ||
| 82 | paddw %3, %2 | ||
| 83 | |||
| 84 | movdqa %2, %1 | ||
| 85 | psrldq %2, 1 | ||
| 86 | punpcklbw %2, %4 | ||
| 87 | paddw %3, %2 | ||
| 88 | |||
| 89 | movdqa %2, %1 | ||
| 90 | psrldq %2, 2 | ||
| 91 | punpcklbw %2, %4 | ||
| 92 | psllw %2, 1 | ||
| 93 | paddw %3, %2 | ||
| 94 | |||
| 95 | movdqa %2, %1 | ||
| 96 | psrldq %2, 3 | ||
| 97 | punpcklbw %2, %4 | ||
| 98 | paddw %3, %2 | ||
| 99 | |||
| 100 | movdqa %2, %1 | ||
| 101 | psrldq %2, 4 | ||
| 102 | punpcklbw %2, %4 | ||
| 103 | paddw %3, %2 | ||
| 104 | %endmacro | ||
| 105 | |||
| 106 | %macro WEIGHT_LINE2_UV 4 | ||
| 107 | movdqa %2, %1 | ||
| 108 | punpcklbw %2, %4 | ||
| 109 | paddw %3, %2 | ||
| 110 | |||
| 111 | movdqa %2, %1 | ||
| 112 | psrldq %2, 1 | ||
| 113 | punpcklbw %2, %4 | ||
| 114 | psllw %2, 1 | ||
| 115 | paddw %3, %2 | ||
| 116 | |||
| 117 | movdqa %2, %1 | ||
| 118 | psrldq %2, 2 | ||
| 119 | punpcklbw %2, %4 | ||
| 120 | psllw %2, 2 | ||
| 121 | paddw %3, %2 | ||
| 122 | |||
| 123 | movdqa %2, %1 | ||
| 124 | psrldq %2, 3 | ||
| 125 | punpcklbw %2, %4 | ||
| 126 | psllw %2, 1 | ||
| 127 | paddw %3, %2 | ||
| 128 | |||
| 129 | movdqa %2, %1 | ||
| 130 | psrldq %2, 4 | ||
| 131 | punpcklbw %2, %4 | ||
| 132 | paddw %3, %2 | ||
| 133 | %endmacro | ||
| 134 | |||
| 135 | %macro WEIGHT_LINE3_UV 4 | ||
| 136 | movdqa %2, %1 | ||
| 137 | punpcklbw %2, %4 | ||
| 138 | psllw %2, 1 | ||
| 139 | paddw %3, %2 | ||
| 140 | |||
| 141 | movdqa %2, %1 | ||
| 142 | psrldq %2, 1 | ||
| 143 | punpcklbw %2, %4 | ||
| 144 | psllw %2, 2 | ||
| 145 | paddw %3, %2 | ||
| 146 | |||
| 147 | movdqa %2, %1 | ||
| 148 | psrldq %2, 2 | ||
| 149 | punpcklbw %2, %4 | ||
| 150 | pmullw %2, [sse2_20] | ||
| 151 | paddw %3, %2 | ||
| 152 | |||
| 153 | movdqa %2, %1 | ||
| 154 | psrldq %2, 3 | ||
| 155 | punpcklbw %2, %4 | ||
| 156 | psllw %2, 2 | ||
| 157 | paddw %3, %2 | ||
| 158 | |||
| 159 | movdqa %2, %1 | ||
| 160 | psrldq %2, 4 | ||
| 161 | punpcklbw %2, %4 | ||
| 162 | psllw %2, 1 | ||
| 163 | paddw %3, %2 | ||
| 164 | %endmacro | ||
| 165 | |||
| 166 | ALIGN 16 | ||
| 167 | WELS_EXTERN BilateralLumaFilter8_sse2 | ||
| 168 | ;*********************************************************************** | ||
| 169 | ; BilateralLumaFilter8_sse2(uint8_t *pixels, int stride); | ||
| 170 | ;*********************************************************************** | ||
| 171 | ; 1 2 3 | ||
| 172 | ; 4 0 5 | ||
| 173 | ; 6 7 8 | ||
| 174 | ; 0: the center point | ||
| 175 | %define pushsize 4 | ||
| 176 | ;%define pixel esp + pushsize + 4 | ||
| 177 | ;%define stride esp + pushsize + 8 | ||
| 178 | ;%define pixel r0 | ||
| 179 | ;%define stride r1 | ||
| 180 | |||
| 181 | BilateralLumaFilter8_sse2: | ||
| 182 | |||
| 183 | push r3 | ||
| 184 | %assign push_num 1 | ||
| 185 | LOAD_2_PARA | ||
| 186 | |||
| 187 | pxor xmm7, xmm7 | ||
| 188 | |||
| 189 | mov r3, r0 | ||
| 190 | |||
| 191 | movq xmm6, [r0] | ||
| 192 | punpcklbw xmm6, xmm7 | ||
| 193 | movdqa xmm3, [sse2_32] | ||
| 194 | pxor xmm4, xmm4 ; nTotWeight | ||
| 195 | pxor xmm5, xmm5 ; nSum | ||
| 196 | |||
| 197 | dec r0 | ||
| 198 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0] ; pixel 4 | ||
| 199 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0 + 2] ; pixel 5 | ||
| 200 | |||
| 201 | sub r0, r1 | ||
| 202 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0] ; pixel 1 | ||
| 203 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0 + 1] ; pixel 2 | ||
| 204 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0 + 2] ; pixel 3 | ||
| 205 | |||
| 206 | lea r0, [r0 + r1 * 2] | ||
| 207 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0] ; pixel 6 | ||
| 208 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0 + 1] ; pixel 7 | ||
| 209 | WEIGHT_LINE xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, [r0 + 2] ; pixel 8 | ||
| 210 | |||
| 211 | pcmpeqw xmm0, xmm0 | ||
| 212 | psrlw xmm0, 15 | ||
| 213 | psllw xmm0, 8 | ||
| 214 | psubusw xmm0, xmm4 | ||
| 215 | pmullw xmm0, xmm6 | ||
| 216 | paddusw xmm5, xmm0 | ||
| 217 | psrlw xmm5, 8 | ||
| 218 | packuswb xmm5, xmm5 | ||
| 219 | movq [r3], xmm5 | ||
| 220 | |||
| 221 | |||
| 222 | pop r3 | ||
| 223 | %assign push_num 0 | ||
| 224 | |||
| 225 | ret | ||
| 226 | |||
| 227 | WELS_EXTERN WaverageChromaFilter8_sse2 | ||
| 228 | ;*********************************************************************** | ||
| 229 | ; void WaverageChromaFilter8_sse2(uint8_t *pixels, int stride); | ||
| 230 | ;*********************************************************************** | ||
| 231 | ;5x5 filter: | ||
| 232 | ;1 1 2 1 1 | ||
| 233 | ;1 2 4 2 1 | ||
| 234 | ;2 4 20 4 2 | ||
| 235 | ;1 2 4 2 1 | ||
| 236 | ;1 1 2 1 1 | ||
| 237 | |||
| 238 | ALIGN 16 | ||
| 239 | WaverageChromaFilter8_sse2: | ||
| 240 | |||
| 241 | push r3 | ||
| 242 | |||
| 243 | %assign push_num 1 | ||
| 244 | |||
| 245 | LOAD_2_PARA | ||
| 246 | |||
| 247 | mov r3, r1 | ||
| 248 | add r3, r3 | ||
| 249 | sub r0, r3 ; pixels - 2 * stride | ||
| 250 | sub r0, 2 | ||
| 251 | |||
| 252 | pxor xmm0, xmm0 | ||
| 253 | pxor xmm3, xmm3 | ||
| 254 | |||
| 255 | movdqu xmm1, [r0] | ||
| 256 | WEIGHT_LINE1_UV xmm1, xmm2, xmm3, xmm0 | ||
| 257 | |||
| 258 | movdqu xmm1, [r0 + r1] | ||
| 259 | WEIGHT_LINE2_UV xmm1, xmm2, xmm3, xmm0 | ||
| 260 | |||
| 261 | add r0, r3 | ||
| 262 | movdqu xmm1, [r0] | ||
| 263 | WEIGHT_LINE3_UV xmm1, xmm2, xmm3, xmm0 | ||
| 264 | |||
| 265 | movdqu xmm1, [r0 + r1] | ||
| 266 | WEIGHT_LINE2_UV xmm1, xmm2, xmm3, xmm0 | ||
| 267 | |||
| 268 | movdqu xmm1, [r0 + r1 * 2] | ||
| 269 | WEIGHT_LINE1_UV xmm1, xmm2, xmm3, xmm0 | ||
| 270 | |||
| 271 | psrlw xmm3, 6 | ||
| 272 | packuswb xmm3, xmm3 | ||
| 273 | movq [r0 + 2], xmm3 | ||
| 274 | |||
| 275 | |||
| 276 | pop r3 | ||
| 277 | |||
| 278 | %assign push_num 0 | ||
| 279 | ret | ||
| @@ -0,0 +1,1225 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | ;* upsampling.asm | ||
| 33 | ;* | ||
| 34 | ;* Abstract | ||
| 35 | ;* SIMD for pixel domain down sampling | ||
| 36 | ;* | ||
| 37 | ;* History | ||
| 38 | ;* 10/22/2009 Created | ||
| 39 | ;* | ||
| 40 | ;*************************************************************************/ | ||
| 41 | %include "asm_inc.asm" | ||
| 42 | %ifdef X86_32 | ||
| 43 | ;*********************************************************************** | ||
| 44 | ; Macros and other preprocessor constants | ||
| 45 | ;*********************************************************************** | ||
| 46 | |||
| 47 | |||
| 48 | ;*********************************************************************** | ||
| 49 | ; Some constants | ||
| 50 | ;*********************************************************************** | ||
| 51 | |||
| 52 | ;*********************************************************************** | ||
| 53 | ; Local Data (Read Only) | ||
| 54 | ;*********************************************************************** | ||
| 55 | |||
| 56 | SECTION .rodata align=16 | ||
| 57 | |||
| 58 | ;*********************************************************************** | ||
| 59 | ; Various memory constants (trigonometric values or rounding values) | ||
| 60 | ;*********************************************************************** | ||
| 61 | |||
| 62 | ALIGN 16 | ||
| 63 | shufb_mask_low: | ||
| 64 | db 00h, 80h, 02h, 80h, 04h, 80h, 06h, 80h, 08h, 80h, 0ah, 80h, 0ch, 80h, 0eh, 80h | ||
| 65 | shufb_mask_high: | ||
| 66 | db 01h, 80h, 03h, 80h, 05h, 80h, 07h, 80h, 09h, 80h, 0bh, 80h, 0dh, 80h, 0fh, 80h | ||
| 67 | |||
| 68 | |||
| 69 | ALIGN 16 | ||
| 70 | |||
| 71 | ;*********************************************************************** | ||
| 72 | ; Code | ||
| 73 | ;*********************************************************************** | ||
| 74 | |||
| 75 | SECTION .text | ||
| 76 | |||
| 77 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_sse | ||
| 78 | ;*********************************************************************** | ||
| 79 | ; void DyadicBilinearDownsamplerWidthx32_sse( unsigned char* pDst, const int iDstStride, | ||
| 80 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 81 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 82 | ;*********************************************************************** | ||
| 83 | ALIGN 16 | ||
| 84 | DyadicBilinearDownsamplerWidthx32_sse: | ||
| 85 | push ebx | ||
| 86 | push edx | ||
| 87 | push esi | ||
| 88 | push edi | ||
| 89 | push ebp | ||
| 90 | |||
| 91 | mov edi, [esp+24] ; pDst | ||
| 92 | mov edx, [esp+28] ; iDstStride | ||
| 93 | mov esi, [esp+32] ; pSrc | ||
| 94 | mov ecx, [esp+36] ; iSrcStride | ||
| 95 | mov ebp, [esp+44] ; iSrcHeight | ||
| 96 | |||
| 97 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 98 | |||
| 99 | .yloops: | ||
| 100 | mov eax, [esp+40] ; iSrcWidth | ||
| 101 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 102 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 103 | sar eax, $4 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | ||
| 104 | neg ebx ; - (iSrcWidth >> 1) | ||
| 105 | ; each loop = source bandwidth: 32 bytes | ||
| 106 | .xloops: | ||
| 107 | ; 1st part horizonal loop: x16 bytes | ||
| 108 | ; mem hi<- ->lo | ||
| 109 | ;1st Line Src: mm0: d D c C b B a A mm1: h H g G f F e E | ||
| 110 | ;2nd Line Src: mm2: l L k K j J i I mm3: p P o O n N m M | ||
| 111 | ;=> target: | ||
| 112 | ;: H G F E D C B A, P O N M L K J I | ||
| 113 | ;: h g f e d c b a, p o n m l k j i | ||
| 114 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 115 | movq mm0, [esi] ; 1st pSrc line | ||
| 116 | movq mm1, [esi+8] ; 1st pSrc line + 8 | ||
| 117 | movq mm2, [esi+ecx] ; 2nd pSrc line | ||
| 118 | movq mm3, [esi+ecx+8] ; 2nd pSrc line + 8 | ||
| 119 | |||
| 120 | ; to handle mm0, mm1, mm2, mm3 | ||
| 121 | pshufw mm4, mm0, 0d8h ; d D b B c C a A ; 11011000 B | ||
| 122 | pshufw mm5, mm4, 04eh ; c C a A d D b B ; 01001110 B | ||
| 123 | punpcklbw mm4, mm5 ; d c D C b a B A | ||
| 124 | pshufw mm4, mm4, 0d8h ; d c b a D C B A ; 11011000 B: mm4 | ||
| 125 | |||
| 126 | pshufw mm5, mm1, 0d8h ; h H f F g G e E ; 11011000 B | ||
| 127 | pshufw mm6, mm5, 04eh ; g G e E h H f F ; 01001110 B | ||
| 128 | punpcklbw mm5, mm6 ; h g H G f e F E | ||
| 129 | pshufw mm5, mm5, 0d8h ; h g f e H G F E ; 11011000 B: mm5 | ||
| 130 | |||
| 131 | pshufw mm6, mm2, 0d8h ; l L j J k K i I ; 11011000 B | ||
| 132 | pshufw mm7, mm6, 04eh ; k K i I l L j J ; 01001110 B | ||
| 133 | punpcklbw mm6, mm7 ; l k L K j i J I | ||
| 134 | pshufw mm6, mm6, 0d8h ; l k j i L K J I ; 11011000 B: mm6 | ||
| 135 | |||
| 136 | pshufw mm7, mm3, 0d8h ; p P n N o O m M ; 11011000 B | ||
| 137 | pshufw mm0, mm7, 04eh ; o O m M p P n N ; 01001110 B | ||
| 138 | punpcklbw mm7, mm0 ; p o P O n m N M | ||
| 139 | pshufw mm7, mm7, 0d8h ; p o n m P O N M ; 11011000 B: mm7 | ||
| 140 | |||
| 141 | ; to handle mm4, mm5, mm6, mm7 | ||
| 142 | movq mm0, mm4 ; | ||
| 143 | punpckldq mm0, mm5 ; H G F E D C B A | ||
| 144 | punpckhdq mm4, mm5 ; h g f e d c b a | ||
| 145 | |||
| 146 | movq mm1, mm6 | ||
| 147 | punpckldq mm1, mm7 ; P O N M L K J I | ||
| 148 | punpckhdq mm6, mm7 ; p o n m l k j i | ||
| 149 | |||
| 150 | ; avg within MB horizon width (16 x 2 lines) | ||
| 151 | pavgb mm0, mm4 ; (A+a+1)>>1, .., (H+h+1)>>1, temp_row1 | ||
| 152 | pavgb mm1, mm6 ; (I+i+1)>>1, .., (P+p+1)>>1, temp_row2 | ||
| 153 | pavgb mm0, mm1 ; (temp_row1+temp_row2+1)>>1, pending here and wait another horizonal part done then write memory once | ||
| 154 | |||
| 155 | ; 2nd part horizonal loop: x16 bytes | ||
| 156 | ; mem hi<- ->lo | ||
| 157 | ;1st Line Src: mm0: d D c C b B a A mm1: h H g G f F e E | ||
| 158 | ;2nd Line Src: mm2: l L k K j J i I mm3: p P o O n N m M | ||
| 159 | ;=> target: | ||
| 160 | ;: H G F E D C B A, P O N M L K J I | ||
| 161 | ;: h g f e d c b a, p o n m l k j i | ||
| 162 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 163 | movq mm1, [esi+16] ; 1st pSrc line + 16 | ||
| 164 | movq mm2, [esi+24] ; 1st pSrc line + 24 | ||
| 165 | movq mm3, [esi+ecx+16] ; 2nd pSrc line + 16 | ||
| 166 | movq mm4, [esi+ecx+24] ; 2nd pSrc line + 24 | ||
| 167 | |||
| 168 | ; to handle mm1, mm2, mm3, mm4 | ||
| 169 | pshufw mm5, mm1, 0d8h ; d D b B c C a A ; 11011000 B | ||
| 170 | pshufw mm6, mm5, 04eh ; c C a A d D b B ; 01001110 B | ||
| 171 | punpcklbw mm5, mm6 ; d c D C b a B A | ||
| 172 | pshufw mm5, mm5, 0d8h ; d c b a D C B A ; 11011000 B: mm5 | ||
| 173 | |||
| 174 | pshufw mm6, mm2, 0d8h ; h H f F g G e E ; 11011000 B | ||
| 175 | pshufw mm7, mm6, 04eh ; g G e E h H f F ; 01001110 B | ||
| 176 | punpcklbw mm6, mm7 ; h g H G f e F E | ||
| 177 | pshufw mm6, mm6, 0d8h ; h g f e H G F E ; 11011000 B: mm6 | ||
| 178 | |||
| 179 | pshufw mm7, mm3, 0d8h ; l L j J k K i I ; 11011000 B | ||
| 180 | pshufw mm1, mm7, 04eh ; k K i I l L j J ; 01001110 B | ||
| 181 | punpcklbw mm7, mm1 ; l k L K j i J I | ||
| 182 | pshufw mm7, mm7, 0d8h ; l k j i L K J I ; 11011000 B: mm7 | ||
| 183 | |||
| 184 | pshufw mm1, mm4, 0d8h ; p P n N o O m M ; 11011000 B | ||
| 185 | pshufw mm2, mm1, 04eh ; o O m M p P n N ; 01001110 B | ||
| 186 | punpcklbw mm1, mm2 ; p o P O n m N M | ||
| 187 | pshufw mm1, mm1, 0d8h ; p o n m P O N M ; 11011000 B: mm1 | ||
| 188 | |||
| 189 | ; to handle mm5, mm6, mm7, mm1 | ||
| 190 | movq mm2, mm5 | ||
| 191 | punpckldq mm2, mm6 ; H G F E D C B A | ||
| 192 | punpckhdq mm5, mm6 ; h g f e d c b a | ||
| 193 | |||
| 194 | movq mm3, mm7 | ||
| 195 | punpckldq mm3, mm1 ; P O N M L K J I | ||
| 196 | punpckhdq mm7, mm1 ; p o n m l k j i | ||
| 197 | |||
| 198 | ; avg within MB horizon width (16 x 2 lines) | ||
| 199 | pavgb mm2, mm5 ; (A+a+1)>>1, .., (H+h+1)>>1, temp_row1 | ||
| 200 | pavgb mm3, mm7 ; (I+i+1)>>1, .., (P+p+1)>>1, temp_row2 | ||
| 201 | pavgb mm2, mm3 ; (temp_row1+temp_row2+1)>>1, done in another 2nd horizonal part | ||
| 202 | |||
| 203 | movq [edi ], mm0 | ||
| 204 | movq [edi+8], mm2 | ||
| 205 | |||
| 206 | ; next SMB | ||
| 207 | lea esi, [esi+32] | ||
| 208 | lea edi, [edi+16] | ||
| 209 | |||
| 210 | dec eax | ||
| 211 | jg near .xloops | ||
| 212 | |||
| 213 | ; next line | ||
| 214 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 215 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 216 | lea edi, [edi+edx] | ||
| 217 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 218 | |||
| 219 | dec ebp | ||
| 220 | jg near .yloops | ||
| 221 | |||
| 222 | WELSEMMS | ||
| 223 | pop ebp | ||
| 224 | pop edi | ||
| 225 | pop esi | ||
| 226 | pop edx | ||
| 227 | pop ebx | ||
| 228 | ret | ||
| 229 | |||
| 230 | WELS_EXTERN DyadicBilinearDownsamplerWidthx16_sse | ||
| 231 | ;*********************************************************************** | ||
| 232 | ; void DyadicBilinearDownsamplerWidthx16_sse( unsigned char* pDst, const int iDstStride, | ||
| 233 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 234 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 235 | ;*********************************************************************** | ||
| 236 | ALIGN 16 | ||
| 237 | DyadicBilinearDownsamplerWidthx16_sse: | ||
| 238 | push ebx | ||
| 239 | push edx | ||
| 240 | push esi | ||
| 241 | push edi | ||
| 242 | push ebp | ||
| 243 | |||
| 244 | mov edi, [esp+24] ; pDst | ||
| 245 | mov edx, [esp+28] ; iDstStride | ||
| 246 | mov esi, [esp+32] ; pSrc | ||
| 247 | mov ecx, [esp+36] ; iSrcStride | ||
| 248 | mov ebp, [esp+44] ; iSrcHeight | ||
| 249 | |||
| 250 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 251 | |||
| 252 | .yloops: | ||
| 253 | mov eax, [esp+40] ; iSrcWidth | ||
| 254 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 255 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 256 | sar eax, $3 ; (iSrcWidth >> 1) / 8 ; loop count = num_of_mb | ||
| 257 | neg ebx ; - (iSrcWidth >> 1) | ||
| 258 | ; each loop = source bandwidth: 16 bytes | ||
| 259 | .xloops: | ||
| 260 | ; 1st part horizonal loop: x16 bytes | ||
| 261 | ; mem hi<- ->lo | ||
| 262 | ;1st Line Src: mm0: d D c C b B a A mm1: h H g G f F e E | ||
| 263 | ;2nd Line Src: mm2: l L k K j J i I mm3: p P o O n N m M | ||
| 264 | ;=> target: | ||
| 265 | ;: H G F E D C B A, P O N M L K J I | ||
| 266 | ;: h g f e d c b a, p o n m l k j i | ||
| 267 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 268 | movq mm0, [esi] ; 1st pSrc line | ||
| 269 | movq mm1, [esi+8] ; 1st pSrc line + 8 | ||
| 270 | movq mm2, [esi+ecx] ; 2nd pSrc line | ||
| 271 | movq mm3, [esi+ecx+8] ; 2nd pSrc line + 8 | ||
| 272 | |||
| 273 | ; to handle mm0, mm1, mm2, mm3 | ||
| 274 | pshufw mm4, mm0, 0d8h ; d D b B c C a A ; 11011000 B | ||
| 275 | pshufw mm5, mm4, 04eh ; c C a A d D b B ; 01001110 B | ||
| 276 | punpcklbw mm4, mm5 ; d c D C b a B A | ||
| 277 | pshufw mm4, mm4, 0d8h ; d c b a D C B A ; 11011000 B: mm4 | ||
| 278 | |||
| 279 | pshufw mm5, mm1, 0d8h ; h H f F g G e E ; 11011000 B | ||
| 280 | pshufw mm6, mm5, 04eh ; g G e E h H f F ; 01001110 B | ||
| 281 | punpcklbw mm5, mm6 ; h g H G f e F E | ||
| 282 | pshufw mm5, mm5, 0d8h ; h g f e H G F E ; 11011000 B: mm5 | ||
| 283 | |||
| 284 | pshufw mm6, mm2, 0d8h ; l L j J k K i I ; 11011000 B | ||
| 285 | pshufw mm7, mm6, 04eh ; k K i I l L j J ; 01001110 B | ||
| 286 | punpcklbw mm6, mm7 ; l k L K j i J I | ||
| 287 | pshufw mm6, mm6, 0d8h ; l k j i L K J I ; 11011000 B: mm6 | ||
| 288 | |||
| 289 | pshufw mm7, mm3, 0d8h ; p P n N o O m M ; 11011000 B | ||
| 290 | pshufw mm0, mm7, 04eh ; o O m M p P n N ; 01001110 B | ||
| 291 | punpcklbw mm7, mm0 ; p o P O n m N M | ||
| 292 | pshufw mm7, mm7, 0d8h ; p o n m P O N M ; 11011000 B: mm7 | ||
| 293 | |||
| 294 | ; to handle mm4, mm5, mm6, mm7 | ||
| 295 | movq mm0, mm4 ; | ||
| 296 | punpckldq mm0, mm5 ; H G F E D C B A | ||
| 297 | punpckhdq mm4, mm5 ; h g f e d c b a | ||
| 298 | |||
| 299 | movq mm1, mm6 | ||
| 300 | punpckldq mm1, mm7 ; P O N M L K J I | ||
| 301 | punpckhdq mm6, mm7 ; p o n m l k j i | ||
| 302 | |||
| 303 | ; avg within MB horizon width (16 x 2 lines) | ||
| 304 | pavgb mm0, mm4 ; (A+a+1)>>1, .., (H+h+1)>>1, temp_row1 | ||
| 305 | pavgb mm1, mm6 ; (I+i+1)>>1, .., (P+p+1)>>1, temp_row2 | ||
| 306 | pavgb mm0, mm1 ; (temp_row1+temp_row2+1)>>1, pending here and wait another horizonal part done then write memory once | ||
| 307 | |||
| 308 | movq [edi ], mm0 | ||
| 309 | |||
| 310 | ; next SMB | ||
| 311 | lea esi, [esi+16] | ||
| 312 | lea edi, [edi+8] | ||
| 313 | |||
| 314 | dec eax | ||
| 315 | jg near .xloops | ||
| 316 | |||
| 317 | ; next line | ||
| 318 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 319 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 320 | lea edi, [edi+edx] | ||
| 321 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 322 | |||
| 323 | dec ebp | ||
| 324 | jg near .yloops | ||
| 325 | |||
| 326 | WELSEMMS | ||
| 327 | pop ebp | ||
| 328 | pop edi | ||
| 329 | pop esi | ||
| 330 | pop edx | ||
| 331 | pop ebx | ||
| 332 | ret | ||
| 333 | |||
| 334 | WELS_EXTERN DyadicBilinearDownsamplerWidthx8_sse | ||
| 335 | ;*********************************************************************** | ||
| 336 | ; void DyadicBilinearDownsamplerWidthx8_sse( unsigned char* pDst, const int iDstStride, | ||
| 337 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 338 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 339 | ;*********************************************************************** | ||
| 340 | ALIGN 16 | ||
| 341 | DyadicBilinearDownsamplerWidthx8_sse: | ||
| 342 | push ebx | ||
| 343 | push edx | ||
| 344 | push esi | ||
| 345 | push edi | ||
| 346 | push ebp | ||
| 347 | |||
| 348 | mov edi, [esp+24] ; pDst | ||
| 349 | mov edx, [esp+28] ; iDstStride | ||
| 350 | mov esi, [esp+32] ; pSrc | ||
| 351 | mov ecx, [esp+36] ; iSrcStride | ||
| 352 | mov ebp, [esp+44] ; iSrcHeight | ||
| 353 | |||
| 354 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 355 | |||
| 356 | .yloops: | ||
| 357 | mov eax, [esp+40] ; iSrcWidth | ||
| 358 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 359 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 360 | sar eax, $2 ; (iSrcWidth >> 1) / 4 ; loop count = num_of_mb | ||
| 361 | neg ebx ; - (iSrcWidth >> 1) | ||
| 362 | ; each loop = source bandwidth: 8 bytes | ||
| 363 | .xloops: | ||
| 364 | ; 1st part horizonal loop: x8 bytes | ||
| 365 | ; mem hi<- ->lo | ||
| 366 | ;1st Line Src: mm0: d D c C b B a A | ||
| 367 | ;2nd Line Src: mm1: h H g G f F e E | ||
| 368 | ;=> target: | ||
| 369 | ;: H G F E D C B A | ||
| 370 | ;: h g f e d c b a | ||
| 371 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 372 | movq mm0, [esi] ; 1st pSrc line | ||
| 373 | movq mm1, [esi+ecx] ; 2nd pSrc line | ||
| 374 | |||
| 375 | ; to handle mm0, mm1, mm2, mm3 | ||
| 376 | pshufw mm2, mm0, 0d8h ; d D b B c C a A ; 11011000 B | ||
| 377 | pshufw mm3, mm2, 04eh ; c C a A d D b B ; 01001110 B | ||
| 378 | punpcklbw mm2, mm3 ; d c D C b a B A | ||
| 379 | pshufw mm2, mm2, 0d8h ; d c b a D C B A ; 11011000 B: mm4 | ||
| 380 | |||
| 381 | pshufw mm4, mm1, 0d8h ; h H f F g G e E ; 11011000 B | ||
| 382 | pshufw mm5, mm4, 04eh ; g G e E h H f F ; 01001110 B | ||
| 383 | punpcklbw mm4, mm5 ; h g H G f e F E | ||
| 384 | pshufw mm4, mm4, 0d8h ; h g f e H G F E ; 11011000 B: mm5 | ||
| 385 | |||
| 386 | ; to handle mm2, mm4 | ||
| 387 | movq mm0, mm2 ; | ||
| 388 | punpckldq mm0, mm4 ; H G F E D C B A | ||
| 389 | punpckhdq mm2, mm4 ; h g f e d c b a | ||
| 390 | |||
| 391 | ; avg within MB horizon width (16 x 2 lines) | ||
| 392 | pavgb mm0, mm2 ; (H+h+1)>>1, .., (A+a+1)>>1, temp_row1, 2 | ||
| 393 | pshufw mm1, mm0, 04eh ; 01001110 B | ||
| 394 | pavgb mm0, mm1 ; (temp_row1+temp_row2+1)>>1, pending here and wait another horizonal part done then write memory once | ||
| 395 | |||
| 396 | movd [edi], mm0 | ||
| 397 | |||
| 398 | ; next unit | ||
| 399 | lea esi, [esi+8] | ||
| 400 | lea edi, [edi+4] | ||
| 401 | |||
| 402 | dec eax | ||
| 403 | jg near .xloops | ||
| 404 | |||
| 405 | ; next line | ||
| 406 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 407 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 408 | lea edi, [edi+edx] | ||
| 409 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 410 | |||
| 411 | dec ebp | ||
| 412 | jg near .yloops | ||
| 413 | |||
| 414 | WELSEMMS | ||
| 415 | pop ebp | ||
| 416 | pop edi | ||
| 417 | pop esi | ||
| 418 | pop edx | ||
| 419 | pop ebx | ||
| 420 | ret | ||
| 421 | |||
| 422 | |||
| 423 | |||
| 424 | ; got about 50% improvement over DyadicBilinearDownsamplerWidthx32_sse | ||
| 425 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_ssse3 | ||
| 426 | ;*********************************************************************** | ||
| 427 | ; void DyadicBilinearDownsamplerWidthx32_ssse3( unsigned char* pDst, const int iDstStride, | ||
| 428 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 429 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 430 | ;*********************************************************************** | ||
| 431 | ALIGN 16 | ||
| 432 | DyadicBilinearDownsamplerWidthx32_ssse3: | ||
| 433 | push ebx | ||
| 434 | push edx | ||
| 435 | push esi | ||
| 436 | push edi | ||
| 437 | push ebp | ||
| 438 | |||
| 439 | mov edi, [esp+24] ; pDst | ||
| 440 | mov edx, [esp+28] ; iDstStride | ||
| 441 | mov esi, [esp+32] ; pSrc | ||
| 442 | mov ecx, [esp+36] ; iSrcStride | ||
| 443 | mov ebp, [esp+44] ; iSrcHeight | ||
| 444 | |||
| 445 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 446 | |||
| 447 | movdqa xmm7, [shufb_mask_low] ; mask low | ||
| 448 | movdqa xmm6, [shufb_mask_high] ; mask high | ||
| 449 | |||
| 450 | .yloops: | ||
| 451 | mov eax, [esp+40] ; iSrcWidth | ||
| 452 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 453 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 454 | sar eax, $4 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | ||
| 455 | neg ebx ; - (iSrcWidth >> 1) | ||
| 456 | ; each loop = source bandwidth: 32 bytes | ||
| 457 | .xloops: | ||
| 458 | ; 1st part horizonal loop: x16 bytes | ||
| 459 | ; mem hi<- ->lo | ||
| 460 | ;1st Line Src: xmm0: h H g G f F e E d D c C b B a A | ||
| 461 | ; xmm1: p P o O n N m M l L k K j J i I | ||
| 462 | ;2nd Line Src: xmm2: h H g G f F e E d D c C b B a A | ||
| 463 | ; xmm3: p P o O n N m M l L k K j J i I | ||
| 464 | ;=> target: | ||
| 465 | ;: P O N M L K J I H G F E D C B A | ||
| 466 | ;: p o n m l k j i h g f e d c b a | ||
| 467 | ;: P .. A | ||
| 468 | ;: p .. a | ||
| 469 | |||
| 470 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 471 | movdqa xmm0, [esi] ; 1st_src_line | ||
| 472 | movdqa xmm1, [esi+16] ; 1st_src_line + 16 | ||
| 473 | movdqa xmm2, [esi+ecx] ; 2nd_src_line | ||
| 474 | movdqa xmm3, [esi+ecx+16] ; 2nd_src_line + 16 | ||
| 475 | |||
| 476 | ; packing & avg | ||
| 477 | movdqa xmm4, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 478 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 479 | pshufb xmm4, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 480 | ; another implementation for xmm4 high bits | ||
| 481 | ; psubb xmm4, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 482 | ; psrlw xmm4, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 483 | pavgb xmm0, xmm4 | ||
| 484 | |||
| 485 | movdqa xmm5, xmm1 | ||
| 486 | pshufb xmm1, xmm7 | ||
| 487 | pshufb xmm5, xmm6 | ||
| 488 | ; psubb xmm5, xmm1 | ||
| 489 | ; psrlw xmm5, 8 | ||
| 490 | pavgb xmm1, xmm5 | ||
| 491 | |||
| 492 | movdqa xmm4, xmm2 | ||
| 493 | pshufb xmm2, xmm7 | ||
| 494 | pshufb xmm4, xmm6 | ||
| 495 | ; psubb xmm4, xmm2 | ||
| 496 | ; psrlw xmm4, 8 | ||
| 497 | pavgb xmm2, xmm4 | ||
| 498 | |||
| 499 | movdqa xmm5, xmm3 | ||
| 500 | pshufb xmm3, xmm7 | ||
| 501 | pshufb xmm5, xmm6 | ||
| 502 | ; psubb xmm5, xmm3 | ||
| 503 | ; psrlw xmm5, 8 | ||
| 504 | pavgb xmm3, xmm5 | ||
| 505 | |||
| 506 | packuswb xmm0, xmm1 | ||
| 507 | packuswb xmm2, xmm3 | ||
| 508 | pavgb xmm0, xmm2 | ||
| 509 | |||
| 510 | ; write pDst | ||
| 511 | movdqa [edi], xmm0 | ||
| 512 | |||
| 513 | ; next SMB | ||
| 514 | lea esi, [esi+32] | ||
| 515 | lea edi, [edi+16] | ||
| 516 | |||
| 517 | dec eax | ||
| 518 | jg near .xloops | ||
| 519 | |||
| 520 | ; next line | ||
| 521 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 522 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 523 | lea edi, [edi+edx] | ||
| 524 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 525 | |||
| 526 | dec ebp | ||
| 527 | jg near .yloops | ||
| 528 | |||
| 529 | pop ebp | ||
| 530 | pop edi | ||
| 531 | pop esi | ||
| 532 | pop edx | ||
| 533 | pop ebx | ||
| 534 | ret | ||
| 535 | |||
| 536 | WELS_EXTERN DyadicBilinearDownsamplerWidthx16_ssse3 | ||
| 537 | ;*********************************************************************** | ||
| 538 | ; void DyadicBilinearDownsamplerWidthx16_ssse3( unsigned char* pDst, const int iDstStride, | ||
| 539 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 540 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 541 | ;*********************************************************************** | ||
| 542 | ALIGN 16 | ||
| 543 | DyadicBilinearDownsamplerWidthx16_ssse3: | ||
| 544 | push ebx | ||
| 545 | push edx | ||
| 546 | push esi | ||
| 547 | push edi | ||
| 548 | push ebp | ||
| 549 | |||
| 550 | mov edi, [esp+24] ; pDst | ||
| 551 | mov edx, [esp+28] ; iDstStride | ||
| 552 | mov esi, [esp+32] ; pSrc | ||
| 553 | mov ecx, [esp+36] ; iSrcStride | ||
| 554 | mov ebp, [esp+44] ; iSrcHeight | ||
| 555 | |||
| 556 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 557 | movdqa xmm7, [shufb_mask_low] ; mask low | ||
| 558 | movdqa xmm6, [shufb_mask_high] ; mask high | ||
| 559 | |||
| 560 | .yloops: | ||
| 561 | mov eax, [esp+40] ; iSrcWidth | ||
| 562 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 563 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 564 | sar eax, $3 ; (iSrcWidth >> 1) / 8 ; loop count = num_of_mb | ||
| 565 | neg ebx ; - (iSrcWidth >> 1) | ||
| 566 | ; each loop = source bandwidth: 16 bytes | ||
| 567 | .xloops: | ||
| 568 | ; horizonal loop: x16 bytes by source | ||
| 569 | ; mem hi<- ->lo | ||
| 570 | ;1st line pSrc: xmm0: h H g G f F e E d D c C b B a A | ||
| 571 | ;2nd line pSrc: xmm1: p P o O n N m M l L k K j J i I | ||
| 572 | ;=> target: | ||
| 573 | ;: H G F E D C B A, P O N M L K J I | ||
| 574 | ;: h g f e d c b a, p o n m l k j i | ||
| 575 | |||
| 576 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 577 | movdqa xmm0, [esi] ; 1st_src_line | ||
| 578 | movdqa xmm1, [esi+ecx] ; 2nd_src_line | ||
| 579 | |||
| 580 | ; packing & avg | ||
| 581 | movdqa xmm2, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 582 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 583 | pshufb xmm2, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 584 | ; another implementation for xmm2 high bits | ||
| 585 | ; psubb xmm2, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 586 | ; psrlw xmm2, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 587 | pavgb xmm0, xmm2 | ||
| 588 | |||
| 589 | movdqa xmm3, xmm1 | ||
| 590 | pshufb xmm1, xmm7 | ||
| 591 | pshufb xmm3, xmm6 | ||
| 592 | ; psubb xmm3, xmm1 | ||
| 593 | ; psrlw xmm3, 8 | ||
| 594 | pavgb xmm1, xmm3 | ||
| 595 | |||
| 596 | pavgb xmm0, xmm1 | ||
| 597 | packuswb xmm0, xmm1 | ||
| 598 | |||
| 599 | ; write pDst | ||
| 600 | movq [edi], xmm0 | ||
| 601 | |||
| 602 | ; next SMB | ||
| 603 | lea esi, [esi+16] | ||
| 604 | lea edi, [edi+8] | ||
| 605 | |||
| 606 | dec eax | ||
| 607 | jg near .xloops | ||
| 608 | |||
| 609 | ; next line | ||
| 610 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 611 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 612 | lea edi, [edi+edx] | ||
| 613 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 614 | |||
| 615 | dec ebp | ||
| 616 | jg near .yloops | ||
| 617 | |||
| 618 | pop ebp | ||
| 619 | pop edi | ||
| 620 | pop esi | ||
| 621 | pop edx | ||
| 622 | pop ebx | ||
| 623 | ret | ||
| 624 | |||
| 625 | ; got about 65% improvement over DyadicBilinearDownsamplerWidthx32_sse | ||
| 626 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_sse4 | ||
| 627 | ;*********************************************************************** | ||
| 628 | ; void DyadicBilinearDownsamplerWidthx32_sse4( unsigned char* pDst, const int iDstStride, | ||
| 629 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 630 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 631 | ;*********************************************************************** | ||
| 632 | ALIGN 16 | ||
| 633 | DyadicBilinearDownsamplerWidthx32_sse4: | ||
| 634 | push ebx | ||
| 635 | push edx | ||
| 636 | push esi | ||
| 637 | push edi | ||
| 638 | push ebp | ||
| 639 | |||
| 640 | mov edi, [esp+24] ; pDst | ||
| 641 | mov edx, [esp+28] ; iDstStride | ||
| 642 | mov esi, [esp+32] ; pSrc | ||
| 643 | mov ecx, [esp+36] ; iSrcStride | ||
| 644 | mov ebp, [esp+44] ; iSrcHeight | ||
| 645 | |||
| 646 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 647 | |||
| 648 | movdqa xmm7, [shufb_mask_low] ; mask low | ||
| 649 | movdqa xmm6, [shufb_mask_high] ; mask high | ||
| 650 | |||
| 651 | .yloops: | ||
| 652 | mov eax, [esp+40] ; iSrcWidth | ||
| 653 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 654 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 655 | sar eax, $4 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | ||
| 656 | neg ebx ; - (iSrcWidth >> 1) | ||
| 657 | ; each loop = source bandwidth: 32 bytes | ||
| 658 | .xloops: | ||
| 659 | ; 1st part horizonal loop: x16 bytes | ||
| 660 | ; mem hi<- ->lo | ||
| 661 | ;1st Line Src: xmm0: h H g G f F e E d D c C b B a A | ||
| 662 | ; xmm1: p P o O n N m M l L k K j J i I | ||
| 663 | ;2nd Line Src: xmm2: h H g G f F e E d D c C b B a A | ||
| 664 | ; xmm3: p P o O n N m M l L k K j J i I | ||
| 665 | ;=> target: | ||
| 666 | ;: P O N M L K J I H G F E D C B A | ||
| 667 | ;: p o n m l k j i h g f e d c b a | ||
| 668 | ;: P .. A | ||
| 669 | ;: p .. a | ||
| 670 | |||
| 671 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 672 | movntdqa xmm0, [esi] ; 1st_src_line | ||
| 673 | movntdqa xmm1, [esi+16] ; 1st_src_line + 16 | ||
| 674 | movntdqa xmm2, [esi+ecx] ; 2nd_src_line | ||
| 675 | movntdqa xmm3, [esi+ecx+16] ; 2nd_src_line + 16 | ||
| 676 | |||
| 677 | ; packing & avg | ||
| 678 | movdqa xmm4, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 679 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 680 | pshufb xmm4, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 681 | ; psubb xmm4, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 682 | ; psrlw xmm4, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 683 | pavgb xmm0, xmm4 | ||
| 684 | |||
| 685 | movdqa xmm5, xmm1 | ||
| 686 | pshufb xmm1, xmm7 | ||
| 687 | pshufb xmm5, xmm6 | ||
| 688 | ; psubb xmm5, xmm1 | ||
| 689 | ; psrlw xmm5, 8 | ||
| 690 | pavgb xmm1, xmm5 | ||
| 691 | |||
| 692 | movdqa xmm4, xmm2 | ||
| 693 | pshufb xmm2, xmm7 | ||
| 694 | pshufb xmm4, xmm6 | ||
| 695 | ; psubb xmm4, xmm2 | ||
| 696 | ; psrlw xmm4, 8 | ||
| 697 | pavgb xmm2, xmm4 | ||
| 698 | |||
| 699 | movdqa xmm5, xmm3 | ||
| 700 | pshufb xmm3, xmm7 | ||
| 701 | pshufb xmm5, xmm6 | ||
| 702 | ; psubb xmm5, xmm3 | ||
| 703 | ; psrlw xmm5, 8 | ||
| 704 | pavgb xmm3, xmm5 | ||
| 705 | |||
| 706 | packuswb xmm0, xmm1 | ||
| 707 | packuswb xmm2, xmm3 | ||
| 708 | pavgb xmm0, xmm2 | ||
| 709 | |||
| 710 | ; write pDst | ||
| 711 | movdqa [edi], xmm0 | ||
| 712 | |||
| 713 | ; next SMB | ||
| 714 | lea esi, [esi+32] | ||
| 715 | lea edi, [edi+16] | ||
| 716 | |||
| 717 | dec eax | ||
| 718 | jg near .xloops | ||
| 719 | |||
| 720 | ; next line | ||
| 721 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 722 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 723 | lea edi, [edi+edx] | ||
| 724 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 725 | |||
| 726 | dec ebp | ||
| 727 | jg near .yloops | ||
| 728 | |||
| 729 | pop ebp | ||
| 730 | pop edi | ||
| 731 | pop esi | ||
| 732 | pop edx | ||
| 733 | pop ebx | ||
| 734 | ret | ||
| 735 | |||
| 736 | WELS_EXTERN DyadicBilinearDownsamplerWidthx16_sse4 | ||
| 737 | ;*********************************************************************** | ||
| 738 | ; void DyadicBilinearDownsamplerWidthx16_sse4( unsigned char* pDst, const int iDstStride, | ||
| 739 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 740 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 741 | ;*********************************************************************** | ||
| 742 | ALIGN 16 | ||
| 743 | DyadicBilinearDownsamplerWidthx16_sse4: | ||
| 744 | push ebx | ||
| 745 | push edx | ||
| 746 | push esi | ||
| 747 | push edi | ||
| 748 | push ebp | ||
| 749 | |||
| 750 | mov edi, [esp+24] ; pDst | ||
| 751 | mov edx, [esp+28] ; iDstStride | ||
| 752 | mov esi, [esp+32] ; pSrc | ||
| 753 | mov ecx, [esp+36] ; iSrcStride | ||
| 754 | mov ebp, [esp+44] ; iSrcHeight | ||
| 755 | |||
| 756 | sar ebp, $1 ; iSrcHeight >> 1 | ||
| 757 | movdqa xmm7, [shufb_mask_low] ; mask low | ||
| 758 | movdqa xmm6, [shufb_mask_high] ; mask high | ||
| 759 | |||
| 760 | .yloops: | ||
| 761 | mov eax, [esp+40] ; iSrcWidth | ||
| 762 | sar eax, $1 ; iSrcWidth >> 1 | ||
| 763 | mov ebx, eax ; iDstWidth restored at ebx | ||
| 764 | sar eax, $3 ; (iSrcWidth >> 1) / 8 ; loop count = num_of_mb | ||
| 765 | neg ebx ; - (iSrcWidth >> 1) | ||
| 766 | ; each loop = source bandwidth: 16 bytes | ||
| 767 | .xloops: | ||
| 768 | ; horizonal loop: x16 bytes by source | ||
| 769 | ; mem hi<- ->lo | ||
| 770 | ;1st line pSrc: xmm0: h H g G f F e E d D c C b B a A | ||
| 771 | ;2nd line pSrc: xmm1: p P o O n N m M l L k K j J i I | ||
| 772 | ;=> target: | ||
| 773 | ;: H G F E D C B A, P O N M L K J I | ||
| 774 | ;: h g f e d c b a, p o n m l k j i | ||
| 775 | |||
| 776 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 777 | movntdqa xmm0, [esi] ; 1st_src_line | ||
| 778 | movntdqa xmm1, [esi+ecx] ; 2nd_src_line | ||
| 779 | |||
| 780 | ; packing & avg | ||
| 781 | movdqa xmm2, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 782 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 783 | pshufb xmm2, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 784 | ; psubb xmm2, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 785 | ; psrlw xmm2, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 786 | pavgb xmm0, xmm2 | ||
| 787 | |||
| 788 | movdqa xmm3, xmm1 | ||
| 789 | pshufb xmm1, xmm7 | ||
| 790 | pshufb xmm3, xmm6 | ||
| 791 | ; psubb xmm3, xmm1 | ||
| 792 | ; psrlw xmm3, 8 | ||
| 793 | pavgb xmm1, xmm3 | ||
| 794 | |||
| 795 | pavgb xmm0, xmm1 | ||
| 796 | packuswb xmm0, xmm1 | ||
| 797 | |||
| 798 | ; write pDst | ||
| 799 | movq [edi], xmm0 | ||
| 800 | |||
| 801 | ; next SMB | ||
| 802 | lea esi, [esi+16] | ||
| 803 | lea edi, [edi+8] | ||
| 804 | |||
| 805 | dec eax | ||
| 806 | jg near .xloops | ||
| 807 | |||
| 808 | ; next line | ||
| 809 | lea esi, [esi+2*ecx] ; next end of lines | ||
| 810 | lea esi, [esi+2*ebx] ; reset to base 0 [- 2 * iDstWidth] | ||
| 811 | lea edi, [edi+edx] | ||
| 812 | lea edi, [edi+ebx] ; reset to base 0 [- iDstWidth] | ||
| 813 | |||
| 814 | dec ebp | ||
| 815 | jg near .yloops | ||
| 816 | |||
| 817 | pop ebp | ||
| 818 | pop edi | ||
| 819 | pop esi | ||
| 820 | pop edx | ||
| 821 | pop ebx | ||
| 822 | ret | ||
| 823 | |||
| 824 | |||
| 825 | |||
| 826 | |||
| 827 | |||
| 828 | WELS_EXTERN GeneralBilinearAccurateDownsampler_sse2 | ||
| 829 | ;************************************************************************************************************** | ||
| 830 | ;int GeneralBilinearAccurateDownsampler_sse2( unsigned char* pDst, const int iDstStride, const int iDstWidth, const int iDstHeight, | ||
| 831 | ; unsigned char* pSrc, const int iSrcStride, const int iSrcWidth, const int iSrcHeight, | ||
| 832 | ; unsigned int uiScaleX, unsigned int uiScaleY ); | ||
| 833 | ;{ | ||
| 834 | ;************************************************************************************************************** | ||
| 835 | |||
| 836 | ALIGN 16 | ||
| 837 | GeneralBilinearAccurateDownsampler_sse2: | ||
| 838 | push ebp | ||
| 839 | push esi | ||
| 840 | push edi | ||
| 841 | push ebx | ||
| 842 | %define pushsize 16 | ||
| 843 | %define localsize 28 | ||
| 844 | %define pDstData esp + pushsize + localsize + 4 | ||
| 845 | %define dwDstStride esp + pushsize + localsize + 8 | ||
| 846 | %define dwDstWidth esp + pushsize + localsize + 12 | ||
| 847 | %define dwDstHeight esp + pushsize + localsize + 16 | ||
| 848 | %define pSrcData esp + pushsize + localsize + 20 | ||
| 849 | %define dwSrcStride esp + pushsize + localsize + 24 | ||
| 850 | %define dwSrcWidth esp + pushsize + localsize + 28 | ||
| 851 | %define dwSrcHeight esp + pushsize + localsize + 32 | ||
| 852 | %define scale esp + 0 | ||
| 853 | %define uiScaleX esp + pushsize + localsize + 36 | ||
| 854 | %define uiScaleY esp + pushsize + localsize + 40 | ||
| 855 | %define tmpHeight esp + 12 | ||
| 856 | %define yInverse esp + 16 | ||
| 857 | %define xInverse esp + 20 | ||
| 858 | %define dstStep esp + 24 | ||
| 859 | sub esp, localsize | ||
| 860 | |||
| 861 | pxor xmm0, xmm0 | ||
| 862 | mov edx, 32767 | ||
| 863 | mov eax, [uiScaleX] | ||
| 864 | and eax, 32767 | ||
| 865 | mov ebx, eax | ||
| 866 | neg ebx | ||
| 867 | and ebx, 32767 | ||
| 868 | movd xmm1, eax ; uinc(uiScaleX mod 32767) | ||
| 869 | movd xmm2, ebx ; -uinc | ||
| 870 | psllq xmm1, 32 | ||
| 871 | por xmm1, xmm2 ; 0 0 uinc -uinc (dword) | ||
| 872 | pshufd xmm7, xmm1, 01000100b ; xmm7: uinc -uinc uinc -uinc | ||
| 873 | |||
| 874 | mov eax, [uiScaleY] | ||
| 875 | and eax, 32767 | ||
| 876 | mov ebx, eax | ||
| 877 | neg ebx | ||
| 878 | and ebx, 32767 | ||
| 879 | movd xmm6, eax ; vinc(uiScaleY mod 32767) | ||
| 880 | movd xmm2, ebx ; -vinc | ||
| 881 | psllq xmm6, 32 | ||
| 882 | por xmm6, xmm2 ; 0 0 vinc -vinc (dword) | ||
| 883 | pshufd xmm6, xmm6, 01010000b ; xmm6: vinc vinc -vinc -vinc | ||
| 884 | |||
| 885 | mov edx, 40003fffh | ||
| 886 | movd xmm5, edx | ||
| 887 | punpcklwd xmm5, xmm0 ; 16384 16383 | ||
| 888 | pshufd xmm5, xmm5, 01000100b ; xmm5: 16384 16383 16384 16383 | ||
| 889 | |||
| 890 | |||
| 891 | DOWNSAMPLE: | ||
| 892 | |||
| 893 | mov eax, [dwDstHeight] | ||
| 894 | mov edi, [pDstData] | ||
| 895 | mov edx, [dwDstStride] | ||
| 896 | mov ecx, [dwDstWidth] | ||
| 897 | sub edx, ecx | ||
| 898 | mov [dstStep], edx ; stride - width | ||
| 899 | dec eax | ||
| 900 | mov [tmpHeight], eax | ||
| 901 | mov eax, 16384 | ||
| 902 | mov [yInverse], eax | ||
| 903 | |||
| 904 | pshufd xmm4, xmm5, 01010000b ; initial v to 16384 16384 16383 16383 | ||
| 905 | |||
| 906 | HEIGHT: | ||
| 907 | mov eax, [yInverse] | ||
| 908 | mov esi, [pSrcData] | ||
| 909 | shr eax, 15 | ||
| 910 | mul dword [dwSrcStride] | ||
| 911 | add esi, eax ; get current row address | ||
| 912 | mov ebp, esi | ||
| 913 | add ebp, [dwSrcStride] | ||
| 914 | |||
| 915 | mov eax, 16384 | ||
| 916 | mov [xInverse], eax | ||
| 917 | mov ecx, [dwDstWidth] | ||
| 918 | dec ecx | ||
| 919 | |||
| 920 | movdqa xmm3, xmm5 ; initial u to 16384 16383 16384 16383 | ||
| 921 | |||
| 922 | WIDTH: | ||
| 923 | mov eax, [xInverse] | ||
| 924 | shr eax, 15 | ||
| 925 | |||
| 926 | movd xmm1, [esi+eax] ; xxxxxxba | ||
| 927 | movd xmm2, [ebp+eax] ; xxxxxxdc | ||
| 928 | pxor xmm0, xmm0 | ||
| 929 | punpcklwd xmm1, xmm2 ; xxxxdcba | ||
| 930 | punpcklbw xmm1, xmm0 ; 0d0c0b0a | ||
| 931 | punpcklwd xmm1, xmm0 ; 000d000c000b000a | ||
| 932 | |||
| 933 | movdqa xmm2, xmm4 ; xmm2: vv(1-v)(1-v) tmpv | ||
| 934 | pmaddwd xmm2, xmm3 ; mul u(1-u)u(1-u) on xmm2 | ||
| 935 | movdqa xmm0, xmm2 | ||
| 936 | pmuludq xmm2, xmm1 | ||
| 937 | psrlq xmm0, 32 | ||
| 938 | psrlq xmm1, 32 | ||
| 939 | pmuludq xmm0, xmm1 | ||
| 940 | paddq xmm2, xmm0 | ||
| 941 | pshufd xmm1, xmm2, 00001110b | ||
| 942 | paddq xmm2, xmm1 | ||
| 943 | psrlq xmm2, 29 | ||
| 944 | |||
| 945 | movd eax, xmm2 | ||
| 946 | inc eax | ||
| 947 | shr eax, 1 | ||
| 948 | mov [edi], al | ||
| 949 | inc edi | ||
| 950 | |||
| 951 | mov eax, [uiScaleX] | ||
| 952 | add [xInverse], eax | ||
| 953 | |||
| 954 | paddw xmm3, xmm7 ; inc u | ||
| 955 | psllw xmm3, 1 | ||
| 956 | psrlw xmm3, 1 | ||
| 957 | |||
| 958 | loop WIDTH | ||
| 959 | |||
| 960 | WIDTH_END: | ||
| 961 | mov eax, [xInverse] | ||
| 962 | shr eax, 15 | ||
| 963 | mov cl, [esi+eax] | ||
| 964 | mov [edi], cl | ||
| 965 | inc edi | ||
| 966 | |||
| 967 | mov eax, [uiScaleY] | ||
| 968 | add [yInverse], eax | ||
| 969 | add edi, [dstStep] | ||
| 970 | |||
| 971 | paddw xmm4, xmm6 ; inc v | ||
| 972 | psllw xmm4, 1 | ||
| 973 | psrlw xmm4, 1 | ||
| 974 | |||
| 975 | dec dword [tmpHeight] | ||
| 976 | jg HEIGHT | ||
| 977 | |||
| 978 | |||
| 979 | LAST_ROW: | ||
| 980 | mov eax, [yInverse] | ||
| 981 | mov esi, [pSrcData] | ||
| 982 | shr eax, 15 | ||
| 983 | mul dword [dwSrcStride] | ||
| 984 | add esi, eax ; get current row address | ||
| 985 | |||
| 986 | mov eax, 16384 | ||
| 987 | mov [xInverse], eax | ||
| 988 | mov ecx, [dwDstWidth] | ||
| 989 | |||
| 990 | LAST_ROW_WIDTH: | ||
| 991 | mov eax, [xInverse] | ||
| 992 | shr eax, 15 | ||
| 993 | |||
| 994 | mov al, [esi+eax] | ||
| 995 | mov [edi], al | ||
| 996 | inc edi | ||
| 997 | |||
| 998 | mov eax, [uiScaleX] | ||
| 999 | add [xInverse], eax | ||
| 1000 | |||
| 1001 | loop LAST_ROW_WIDTH | ||
| 1002 | |||
| 1003 | LAST_ROW_END: | ||
| 1004 | |||
| 1005 | add esp, localsize | ||
| 1006 | pop ebx | ||
| 1007 | pop edi | ||
| 1008 | pop esi | ||
| 1009 | pop ebp | ||
| 1010 | %undef pushsize | ||
| 1011 | %undef localsize | ||
| 1012 | %undef pSrcData | ||
| 1013 | %undef dwSrcWidth | ||
| 1014 | %undef dwSrcHeight | ||
| 1015 | %undef dwSrcStride | ||
| 1016 | %undef pDstData | ||
| 1017 | %undef dwDstWidth | ||
| 1018 | %undef dwDstHeight | ||
| 1019 | %undef dwDstStride | ||
| 1020 | %undef scale | ||
| 1021 | %undef uiScaleX | ||
| 1022 | %undef uiScaleY | ||
| 1023 | %undef tmpHeight | ||
| 1024 | %undef yInverse | ||
| 1025 | %undef xInverse | ||
| 1026 | %undef dstStep | ||
| 1027 | ret | ||
| 1028 | |||
| 1029 | |||
| 1030 | |||
| 1031 | |||
| 1032 | WELS_EXTERN GeneralBilinearFastDownsampler_sse2 | ||
| 1033 | ;************************************************************************************************************** | ||
| 1034 | ;int GeneralBilinearFastDownsampler_sse2( unsigned char* pDst, const int iDstStride, const int iDstWidth, const int iDstHeight, | ||
| 1035 | ; unsigned char* pSrc, const int iSrcStride, const int iSrcWidth, const int iSrcHeight, | ||
| 1036 | ; unsigned int uiScaleX, unsigned int uiScaleY ); | ||
| 1037 | ;{ | ||
| 1038 | ;************************************************************************************************************** | ||
| 1039 | |||
| 1040 | ALIGN 16 | ||
| 1041 | GeneralBilinearFastDownsampler_sse2: | ||
| 1042 | push ebp | ||
| 1043 | push esi | ||
| 1044 | push edi | ||
| 1045 | push ebx | ||
| 1046 | %define pushsize 16 | ||
| 1047 | %define localsize 28 | ||
| 1048 | %define pDstData esp + pushsize + localsize + 4 | ||
| 1049 | %define dwDstStride esp + pushsize + localsize + 8 | ||
| 1050 | %define dwDstWidth esp + pushsize + localsize + 12 | ||
| 1051 | %define dwDstHeight esp + pushsize + localsize + 16 | ||
| 1052 | %define pSrcData esp + pushsize + localsize + 20 | ||
| 1053 | %define dwSrcStride esp + pushsize + localsize + 24 | ||
| 1054 | %define dwSrcWidth esp + pushsize + localsize + 28 | ||
| 1055 | %define dwSrcHeight esp + pushsize + localsize + 32 | ||
| 1056 | %define scale esp + 0 | ||
| 1057 | %define uiScaleX esp + pushsize + localsize + 36 | ||
| 1058 | %define uiScaleY esp + pushsize + localsize + 40 | ||
| 1059 | %define tmpHeight esp + 12 | ||
| 1060 | %define yInverse esp + 16 | ||
| 1061 | %define xInverse esp + 20 | ||
| 1062 | %define dstStep esp + 24 | ||
| 1063 | sub esp, localsize | ||
| 1064 | |||
| 1065 | pxor xmm0, xmm0 | ||
| 1066 | mov edx, 65535 | ||
| 1067 | mov eax, [uiScaleX] | ||
| 1068 | and eax, edx | ||
| 1069 | mov ebx, eax | ||
| 1070 | neg ebx | ||
| 1071 | and ebx, 65535 | ||
| 1072 | movd xmm1, eax ; uinc(uiScaleX mod 65536) | ||
| 1073 | movd xmm2, ebx ; -uinc | ||
| 1074 | psllq xmm1, 32 | ||
| 1075 | por xmm1, xmm2 ; 0 uinc 0 -uinc | ||
| 1076 | pshuflw xmm7, xmm1, 10001000b ; xmm7: uinc -uinc uinc -uinc | ||
| 1077 | |||
| 1078 | mov eax, [uiScaleY] | ||
| 1079 | and eax, 32767 | ||
| 1080 | mov ebx, eax | ||
| 1081 | neg ebx | ||
| 1082 | and ebx, 32767 | ||
| 1083 | movd xmm6, eax ; vinc(uiScaleY mod 32767) | ||
| 1084 | movd xmm2, ebx ; -vinc | ||
| 1085 | psllq xmm6, 32 | ||
| 1086 | por xmm6, xmm2 ; 0 vinc 0 -vinc | ||
| 1087 | pshuflw xmm6, xmm6, 10100000b ; xmm6: vinc vinc -vinc -vinc | ||
| 1088 | |||
| 1089 | mov edx, 80007fffh ; 32768 32767 | ||
| 1090 | movd xmm5, edx | ||
| 1091 | pshuflw xmm5, xmm5, 01000100b ; 32768 32767 32768 32767 | ||
| 1092 | mov ebx, 16384 | ||
| 1093 | |||
| 1094 | |||
| 1095 | FAST_DOWNSAMPLE: | ||
| 1096 | |||
| 1097 | mov eax, [dwDstHeight] | ||
| 1098 | mov edi, [pDstData] | ||
| 1099 | mov edx, [dwDstStride] | ||
| 1100 | mov ecx, [dwDstWidth] | ||
| 1101 | sub edx, ecx | ||
| 1102 | mov [dstStep], edx ; stride - width | ||
| 1103 | dec eax | ||
| 1104 | mov [tmpHeight], eax | ||
| 1105 | mov eax, 16384 | ||
| 1106 | mov [yInverse], eax | ||
| 1107 | |||
| 1108 | pshuflw xmm4, xmm5, 01010000b | ||
| 1109 | psrlw xmm4, 1 ; initial v to 16384 16384 16383 16383 | ||
| 1110 | |||
| 1111 | FAST_HEIGHT: | ||
| 1112 | mov eax, [yInverse] | ||
| 1113 | mov esi, [pSrcData] | ||
| 1114 | shr eax, 15 | ||
| 1115 | mul dword [dwSrcStride] | ||
| 1116 | add esi, eax ; get current row address | ||
| 1117 | mov ebp, esi | ||
| 1118 | add ebp, [dwSrcStride] | ||
| 1119 | |||
| 1120 | mov eax, 32768 | ||
| 1121 | mov [xInverse], eax | ||
| 1122 | mov ecx, [dwDstWidth] | ||
| 1123 | dec ecx | ||
| 1124 | |||
| 1125 | movdqa xmm3, xmm5 ; initial u to 32768 32767 32768 32767 | ||
| 1126 | |||
| 1127 | FAST_WIDTH: | ||
| 1128 | mov eax, [xInverse] | ||
| 1129 | shr eax, 16 | ||
| 1130 | |||
| 1131 | movd xmm1, [esi+eax] ; xxxxxxba | ||
| 1132 | movd xmm2, [ebp+eax] ; xxxxxxdc | ||
| 1133 | punpcklwd xmm1, xmm2 ; xxxxdcba | ||
| 1134 | punpcklbw xmm1, xmm0 ; 0d0c0b0a | ||
| 1135 | |||
| 1136 | movdqa xmm2, xmm4 ; xmm2: vv(1-v)(1-v) tmpv | ||
| 1137 | pmulhuw xmm2, xmm3 ; mul u(1-u)u(1-u) on xmm2 | ||
| 1138 | pmaddwd xmm2, xmm1 | ||
| 1139 | pshufd xmm1, xmm2, 00000001b | ||
| 1140 | paddd xmm2, xmm1 | ||
| 1141 | movd xmm1, ebx | ||
| 1142 | paddd xmm2, xmm1 | ||
| 1143 | psrld xmm2, 15 | ||
| 1144 | |||
| 1145 | packuswb xmm2, xmm0 | ||
| 1146 | movd eax, xmm2 | ||
| 1147 | mov [edi], al | ||
| 1148 | inc edi | ||
| 1149 | |||
| 1150 | mov eax, [uiScaleX] | ||
| 1151 | add [xInverse], eax | ||
| 1152 | |||
| 1153 | paddw xmm3, xmm7 ; inc u | ||
| 1154 | |||
| 1155 | loop FAST_WIDTH | ||
| 1156 | |||
| 1157 | FAST_WIDTH_END: | ||
| 1158 | mov eax, [xInverse] | ||
| 1159 | shr eax, 16 | ||
| 1160 | mov cl, [esi+eax] | ||
| 1161 | mov [edi], cl | ||
| 1162 | inc edi | ||
| 1163 | |||
| 1164 | mov eax, [uiScaleY] | ||
| 1165 | add [yInverse], eax | ||
| 1166 | add edi, [dstStep] | ||
| 1167 | |||
| 1168 | paddw xmm4, xmm6 ; inc v | ||
| 1169 | psllw xmm4, 1 | ||
| 1170 | psrlw xmm4, 1 | ||
| 1171 | |||
| 1172 | dec dword [tmpHeight] | ||
| 1173 | jg FAST_HEIGHT | ||
| 1174 | |||
| 1175 | |||
| 1176 | FAST_LAST_ROW: | ||
| 1177 | mov eax, [yInverse] | ||
| 1178 | mov esi, [pSrcData] | ||
| 1179 | shr eax, 15 | ||
| 1180 | mul dword [dwSrcStride] | ||
| 1181 | add esi, eax ; get current row address | ||
| 1182 | |||
| 1183 | mov eax, 32768 | ||
| 1184 | mov [xInverse], eax | ||
| 1185 | mov ecx, [dwDstWidth] | ||
| 1186 | |||
| 1187 | FAST_LAST_ROW_WIDTH: | ||
| 1188 | mov eax, [xInverse] | ||
| 1189 | shr eax, 16 | ||
| 1190 | |||
| 1191 | mov al, [esi+eax] | ||
| 1192 | mov [edi], al | ||
| 1193 | inc edi | ||
| 1194 | |||
| 1195 | mov eax, [uiScaleX] | ||
| 1196 | add [xInverse], eax | ||
| 1197 | |||
| 1198 | loop FAST_LAST_ROW_WIDTH | ||
| 1199 | |||
| 1200 | FAST_LAST_ROW_END: | ||
| 1201 | |||
| 1202 | add esp, localsize | ||
| 1203 | pop ebx | ||
| 1204 | pop edi | ||
| 1205 | pop esi | ||
| 1206 | pop ebp | ||
| 1207 | %undef pushsize | ||
| 1208 | %undef localsize | ||
| 1209 | %undef pSrcData | ||
| 1210 | %undef dwSrcWidth | ||
| 1211 | %undef dwSrcHeight | ||
| 1212 | %undef dwSrcStride | ||
| 1213 | %undef pDstData | ||
| 1214 | %undef dwDstWidth | ||
| 1215 | %undef dwDstHeight | ||
| 1216 | %undef dwDstStride | ||
| 1217 | %undef scale | ||
| 1218 | %undef uiScaleX | ||
| 1219 | %undef uiScaleY | ||
| 1220 | %undef tmpHeight | ||
| 1221 | %undef yInverse | ||
| 1222 | %undef xInverse | ||
| 1223 | %undef dstStep | ||
| 1224 | ret | ||
| 1225 | %endif | ||
| @@ -0,0 +1,1505 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | ;* intra_pred.asm | ||
| 33 | ;* | ||
| 34 | ;* Abstract | ||
| 35 | ;* sse2 function for intra predict operations | ||
| 36 | ;* | ||
| 37 | ;* History | ||
| 38 | ;* 18/09/2009 Created | ||
| 39 | ;* | ||
| 40 | ;* | ||
| 41 | ;*************************************************************************/ | ||
| 42 | %include "asm_inc.asm" | ||
| 43 | |||
| 44 | ;*********************************************************************** | ||
| 45 | ; Local Data (Read Only) | ||
| 46 | ;*********************************************************************** | ||
| 47 | |||
| 48 | %ifdef FORMAT_COFF | ||
| 49 | SECTION .rodata pData | ||
| 50 | %else | ||
| 51 | SECTION .rodata align=16 | ||
| 52 | %endif | ||
| 53 | |||
| 54 | align 16 | ||
| 55 | sse2_plane_inc_minus dw -7, -6, -5, -4, -3, -2, -1, 0 | ||
| 56 | align 16 | ||
| 57 | sse2_plane_inc dw 1, 2, 3, 4, 5, 6, 7, 8 | ||
| 58 | align 16 | ||
| 59 | sse2_plane_dec dw 8, 7, 6, 5, 4, 3, 2, 1 | ||
| 60 | |||
| 61 | ; for chroma plane mode | ||
| 62 | sse2_plane_inc_c dw 1, 2, 3, 4 | ||
| 63 | sse2_plane_dec_c dw 4, 3, 2, 1 | ||
| 64 | align 16 | ||
| 65 | sse2_plane_mul_b_c dw -3, -2, -1, 0, 1, 2, 3, 4 | ||
| 66 | |||
| 67 | align 16 | ||
| 68 | mmx_01bytes: times 16 db 1 | ||
| 69 | ;align 16 | ||
| 70 | ;sse_0x0004bytes: times 8 dw 4 | ||
| 71 | ;ALIGN 16 | ||
| 72 | ;sse_f000 db 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | ||
| 73 | |||
| 74 | align 16 | ||
| 75 | mmx_0x02: dw 0x02, 0x00, 0x00, 0x00 | ||
| 76 | |||
| 77 | |||
| 78 | ;*********************************************************************** | ||
| 79 | ; macros | ||
| 80 | ;*********************************************************************** | ||
| 81 | ;dB 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | ||
| 82 | ;%1 will keep the last result | ||
| 83 | %macro SSE_DB_1_2REG 2 | ||
| 84 | pxor %1, %1 | ||
| 85 | pcmpeqw %2, %2 | ||
| 86 | psubb %1, %2 | ||
| 87 | %endmacro | ||
| 88 | |||
| 89 | ;xmm0, xmm1, xmm2, eax, ecx | ||
| 90 | ;lower 64 bits of xmm0 save the result | ||
| 91 | %macro SSE2_PRED_H_4X4_TWO_LINE 5 | ||
| 92 | movd %1, [%4-1] | ||
| 93 | movdqa %3, %1 | ||
| 94 | punpcklbw %1, %3 | ||
| 95 | movdqa %3, %1 | ||
| 96 | punpcklbw %1, %3 | ||
| 97 | |||
| 98 | ;add %4, %5 | ||
| 99 | movd %2, [%4+%5-1] | ||
| 100 | movdqa %3, %2 | ||
| 101 | punpcklbw %2, %3 | ||
| 102 | movdqa %3, %2 | ||
| 103 | punpcklbw %2, %3 | ||
| 104 | punpckldq %1, %2 | ||
| 105 | %endmacro | ||
| 106 | |||
| 107 | %macro SUMW_HORIZON1 2 | ||
| 108 | movdqa %2, %1 | ||
| 109 | psrldq %2, 8 | ||
| 110 | paddusw %1, %2 | ||
| 111 | movdqa %2, %1 | ||
| 112 | psrldq %2, 4 | ||
| 113 | paddusw %1, %2 | ||
| 114 | movdqa %2, %1 | ||
| 115 | psrldq %2, 2 | ||
| 116 | paddusw %1, %2 | ||
| 117 | %endmacro | ||
| 118 | |||
| 119 | %macro LOAD_COLUMN 6 | ||
| 120 | movd %1, [%5] | ||
| 121 | movd %2, [%5+%6] | ||
| 122 | punpcklbw %1, %2 | ||
| 123 | lea %5, [%5+2*%6] | ||
| 124 | movd %3, [%5] | ||
| 125 | movd %2, [%5+%6] | ||
| 126 | punpcklbw %3, %2 | ||
| 127 | punpcklwd %1, %3 | ||
| 128 | lea %5, [%5+2*%6] | ||
| 129 | movd %4, [%5] | ||
| 130 | movd %2, [%5+%6] | ||
| 131 | punpcklbw %4, %2 | ||
| 132 | lea %5, [%5+2*%6] | ||
| 133 | movd %3, [%5] | ||
| 134 | movd %2, [%5+%6] | ||
| 135 | lea %5, [%5+2*%6] | ||
| 136 | punpcklbw %3, %2 | ||
| 137 | punpcklwd %4, %3 | ||
| 138 | punpckhdq %1, %4 | ||
| 139 | %endmacro | ||
| 140 | |||
| 141 | %macro SUMW_HORIZON 3 | ||
| 142 | movhlps %2, %1 ; x2 = xx xx xx xx d7 d6 d5 d4 | ||
| 143 | paddw %1, %2 ; x1 = xx xx xx xx d37 d26 d15 d04 | ||
| 144 | punpcklwd %1, %3 ; x1 = d37 d26 d15 d04 | ||
| 145 | movhlps %2, %1 ; x2 = xxxx xxxx d37 d26 | ||
| 146 | paddd %1, %2 ; x1 = xxxx xxxx d1357 d0246 | ||
| 147 | pshuflw %2, %1, 0x4e ; x2 = xxxx xxxx d0246 d1357 | ||
| 148 | paddd %1, %2 ; x1 = xxxx xxxx xxxx d01234567 | ||
| 149 | %endmacro | ||
| 150 | |||
| 151 | |||
| 152 | %macro COPY_16_TIMES 2 | ||
| 153 | movdqa %2, [%1-16] | ||
| 154 | psrldq %2, 15 | ||
| 155 | pmuludq %2, [mmx_01bytes] | ||
| 156 | pshufd %2, %2, 0 | ||
| 157 | %endmacro | ||
| 158 | |||
| 159 | %macro COPY_16_TIMESS 3 | ||
| 160 | movdqa %2, [%1+%3-16] | ||
| 161 | psrldq %2, 15 | ||
| 162 | pmuludq %2, [mmx_01bytes] | ||
| 163 | pshufd %2, %2, 0 | ||
| 164 | %endmacro | ||
| 165 | |||
| 166 | %macro LOAD_COLUMN_C 6 | ||
| 167 | movd %1, [%5] | ||
| 168 | movd %2, [%5+%6] | ||
| 169 | punpcklbw %1,%2 | ||
| 170 | lea %5, [%5+2*%6] | ||
| 171 | movd %3, [%5] | ||
| 172 | movd %2, [%5+%6] | ||
| 173 | punpcklbw %3, %2 | ||
| 174 | punpckhwd %1, %3 | ||
| 175 | lea %5, [%5+2*%6] | ||
| 176 | %endmacro | ||
| 177 | |||
| 178 | %macro LOAD_2_LEFT_AND_ADD 0 | ||
| 179 | lea r1, [r1+2*r2] | ||
| 180 | movzx r4, byte [r1-0x01] | ||
| 181 | add r3, r4 | ||
| 182 | movzx r4, byte [r1+r2-0x01] | ||
| 183 | add r3, r4 | ||
| 184 | %endmacro | ||
| 185 | |||
| 186 | ;*********************************************************************** | ||
| 187 | ; Code | ||
| 188 | ;*********************************************************************** | ||
| 189 | |||
| 190 | SECTION .text | ||
| 191 | WELS_EXTERN WelsI4x4LumaPredH_sse2 | ||
| 192 | WELS_EXTERN WelsI4x4LumaPredDDR_mmx | ||
| 193 | WELS_EXTERN WelsI4x4LumaPredDc_sse2 | ||
| 194 | WELS_EXTERN WelsI16x16LumaPredPlane_sse2 | ||
| 195 | |||
| 196 | ALIGN 16 | ||
| 197 | ;*********************************************************************** | ||
| 198 | ; void __cdecl WelsI4x4LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 199 | ; | ||
| 200 | ; pred must align to 16 | ||
| 201 | ;*********************************************************************** | ||
| 202 | WelsI4x4LumaPredH_sse2: | ||
| 203 | push r3 | ||
| 204 | %assign push_num 1 | ||
| 205 | LOAD_3_PARA | ||
| 206 | %ifndef X86_32 | ||
| 207 | movsx r2, r2d | ||
| 208 | %endif | ||
| 209 | movzx r3, byte [r1-1] | ||
| 210 | movd xmm0, r3d | ||
| 211 | pmuludq xmm0, [mmx_01bytes] | ||
| 212 | |||
| 213 | movzx r3, byte [r1+r2-1] | ||
| 214 | movd xmm1, r3d | ||
| 215 | pmuludq xmm1, [mmx_01bytes] | ||
| 216 | |||
| 217 | unpcklps xmm0, xmm1 | ||
| 218 | |||
| 219 | lea r1, [r1+r2*2] | ||
| 220 | movzx r3, byte [r1-1] | ||
| 221 | movd xmm2, r3d | ||
| 222 | pmuludq xmm2, [mmx_01bytes] | ||
| 223 | |||
| 224 | movzx r3, byte [r1+r2-1] | ||
| 225 | movd xmm3, r3d | ||
| 226 | pmuludq xmm3, [mmx_01bytes] | ||
| 227 | |||
| 228 | unpcklps xmm2, xmm3 | ||
| 229 | unpcklpd xmm0, xmm2 | ||
| 230 | |||
| 231 | movdqa [r0], xmm0 | ||
| 232 | pop r3 | ||
| 233 | ret | ||
| 234 | |||
| 235 | ;*********************************************************************** | ||
| 236 | ; void WelsI16x16LumaPredPlane_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride); | ||
| 237 | ;*********************************************************************** | ||
| 238 | WelsI16x16LumaPredPlane_sse2: | ||
| 239 | ;%define pushsize 4 | ||
| 240 | ;push esi | ||
| 241 | ;mov esi, [esp + pushsize + 8] | ||
| 242 | ;mov ecx, [esp + pushsize + 12] | ||
| 243 | push r3 | ||
| 244 | push r4 | ||
| 245 | %assign push_num 2 | ||
| 246 | LOAD_3_PARA | ||
| 247 | %ifndef X86_32 | ||
| 248 | movsx r2, r2d | ||
| 249 | %endif | ||
| 250 | sub r1, 1 | ||
| 251 | sub r1, r2 | ||
| 252 | |||
| 253 | ;for H | ||
| 254 | pxor xmm7, xmm7 | ||
| 255 | movq xmm0, [r1] | ||
| 256 | movdqa xmm5, [sse2_plane_dec] | ||
| 257 | punpcklbw xmm0, xmm7 | ||
| 258 | pmullw xmm0, xmm5 | ||
| 259 | movq xmm1, [r1 + 9] | ||
| 260 | movdqa xmm6, [sse2_plane_inc] | ||
| 261 | punpcklbw xmm1, xmm7 | ||
| 262 | pmullw xmm1, xmm6 | ||
| 263 | psubw xmm1, xmm0 | ||
| 264 | |||
| 265 | SUMW_HORIZON xmm1,xmm0,xmm2 | ||
| 266 | movd r3d, xmm1 ; H += (i + 1) * (top[8 + i] - top[6 - i]); | ||
| 267 | movsx r3, r3w | ||
| 268 | imul r3, 5 | ||
| 269 | add r3, 32 | ||
| 270 | sar r3, 6 ; b = (5 * H + 32) >> 6; | ||
| 271 | SSE2_Copy8Times xmm1, r3d ; xmm1 = b,b,b,b,b,b,b,b | ||
| 272 | |||
| 273 | movzx r4, BYTE [r1+16] | ||
| 274 | sub r1, 3 | ||
| 275 | LOAD_COLUMN xmm0, xmm2, xmm3, xmm4, r1, r2 | ||
| 276 | |||
| 277 | add r1, 3 | ||
| 278 | movzx r3, BYTE [r1+8*r2] | ||
| 279 | add r4, r3 | ||
| 280 | shl r4, 4 ; a = (left[15*stride] + top[15]) << 4; | ||
| 281 | |||
| 282 | sub r1, 3 | ||
| 283 | add r1, r2 | ||
| 284 | LOAD_COLUMN xmm7, xmm2, xmm3, xmm4, r1, r2 | ||
| 285 | pxor xmm4, xmm4 | ||
| 286 | punpckhbw xmm0, xmm4 | ||
| 287 | pmullw xmm0, xmm5 | ||
| 288 | punpckhbw xmm7, xmm4 | ||
| 289 | pmullw xmm7, xmm6 | ||
| 290 | psubw xmm7, xmm0 | ||
| 291 | |||
| 292 | SUMW_HORIZON xmm7,xmm0,xmm2 | ||
| 293 | movd r3d, xmm7 ; V | ||
| 294 | movsx r3, r3w | ||
| 295 | imul r3, 5 | ||
| 296 | add r3, 32 | ||
| 297 | sar r3, 6 ; c = (5 * V + 32) >> 6; | ||
| 298 | SSE2_Copy8Times xmm4, r3d ; xmm4 = c,c,c,c,c,c,c,c | ||
| 299 | |||
| 300 | ;mov esi, [esp + pushsize + 4] | ||
| 301 | add r4, 16 | ||
| 302 | imul r3, -7 | ||
| 303 | add r3, r4 ; s = a + 16 + (-7)*c | ||
| 304 | SSE2_Copy8Times xmm0, r3d ; xmm0 = s,s,s,s,s,s,s,s | ||
| 305 | |||
| 306 | xor r3, r3 | ||
| 307 | movdqa xmm5, [sse2_plane_inc_minus] | ||
| 308 | |||
| 309 | get_i16x16_luma_pred_plane_sse2_1: | ||
| 310 | movdqa xmm2, xmm1 | ||
| 311 | pmullw xmm2, xmm5 | ||
| 312 | paddw xmm2, xmm0 | ||
| 313 | psraw xmm2, 5 | ||
| 314 | movdqa xmm3, xmm1 | ||
| 315 | pmullw xmm3, xmm6 | ||
| 316 | paddw xmm3, xmm0 | ||
| 317 | psraw xmm3, 5 | ||
| 318 | packuswb xmm2, xmm3 | ||
| 319 | movdqa [r0], xmm2 | ||
| 320 | paddw xmm0, xmm4 | ||
| 321 | add r0, 16 | ||
| 322 | inc r3 | ||
| 323 | cmp r3, 16 | ||
| 324 | jnz get_i16x16_luma_pred_plane_sse2_1 | ||
| 325 | pop r4 | ||
| 326 | pop r3 | ||
| 327 | ret | ||
| 328 | |||
| 329 | ;*********************************************************************** | ||
| 330 | ; void WelsI16x16LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride); | ||
| 331 | ;*********************************************************************** | ||
| 332 | |||
| 333 | %macro SSE2_PRED_H_16X16_ONE_LINE 0 | ||
| 334 | add r0, 16 | ||
| 335 | add r1, r2 | ||
| 336 | movzx r3, byte [r1] | ||
| 337 | SSE2_Copy16Times xmm0, r3d | ||
| 338 | movdqa [r0], xmm0 | ||
| 339 | %endmacro | ||
| 340 | |||
| 341 | WELS_EXTERN WelsI16x16LumaPredH_sse2 | ||
| 342 | WelsI16x16LumaPredH_sse2: | ||
| 343 | push r3 | ||
| 344 | %assign push_num 1 | ||
| 345 | LOAD_3_PARA | ||
| 346 | %ifndef X86_32 | ||
| 347 | movsx r2, r2d | ||
| 348 | %endif | ||
| 349 | dec r1 | ||
| 350 | movzx r3, byte [r1] | ||
| 351 | SSE2_Copy16Times xmm0, r3d | ||
| 352 | movdqa [r0], xmm0 | ||
| 353 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 354 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 355 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 356 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 357 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 358 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 359 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 360 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 361 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 362 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 363 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 364 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 365 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 366 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 367 | SSE2_PRED_H_16X16_ONE_LINE | ||
| 368 | pop r3 | ||
| 369 | ret | ||
| 370 | |||
| 371 | ;*********************************************************************** | ||
| 372 | ; void WelsI16x16LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride); | ||
| 373 | ;*********************************************************************** | ||
| 374 | WELS_EXTERN WelsI16x16LumaPredV_sse2 | ||
| 375 | WelsI16x16LumaPredV_sse2: | ||
| 376 | ;mov edx, [esp+4] ; pred | ||
| 377 | ;mov eax, [esp+8] ; pRef | ||
| 378 | ;mov ecx, [esp+12] ; stride | ||
| 379 | %assign push_num 0 | ||
| 380 | LOAD_3_PARA | ||
| 381 | %ifndef X86_32 | ||
| 382 | movsx r2, r2d | ||
| 383 | %endif | ||
| 384 | sub r1, r2 | ||
| 385 | movdqa xmm0, [r1] | ||
| 386 | |||
| 387 | movdqa [r0], xmm0 | ||
| 388 | movdqa [r0+10h], xmm0 | ||
| 389 | movdqa [r0+20h], xmm0 | ||
| 390 | movdqa [r0+30h], xmm0 | ||
| 391 | movdqa [r0+40h], xmm0 | ||
| 392 | movdqa [r0+50h], xmm0 | ||
| 393 | movdqa [r0+60h], xmm0 | ||
| 394 | movdqa [r0+70h], xmm0 | ||
| 395 | movdqa [r0+80h], xmm0 | ||
| 396 | movdqa [r0+90h], xmm0 | ||
| 397 | movdqa [r0+160], xmm0 | ||
| 398 | movdqa [r0+176], xmm0 | ||
| 399 | movdqa [r0+192], xmm0 | ||
| 400 | movdqa [r0+208], xmm0 | ||
| 401 | movdqa [r0+224], xmm0 | ||
| 402 | movdqa [r0+240], xmm0 | ||
| 403 | |||
| 404 | ret | ||
| 405 | |||
| 406 | ;*********************************************************************** | ||
| 407 | ; void WelsIChromaPredPlane_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride); | ||
| 408 | ;*********************************************************************** | ||
| 409 | WELS_EXTERN WelsIChromaPredPlane_sse2 | ||
| 410 | WelsIChromaPredPlane_sse2: | ||
| 411 | ;%define pushsize 4 | ||
| 412 | ;push esi | ||
| 413 | ;mov esi, [esp + pushsize + 8] ;pRef | ||
| 414 | ;mov ecx, [esp + pushsize + 12] ;stride | ||
| 415 | push r3 | ||
| 416 | push r4 | ||
| 417 | %assign push_num 2 | ||
| 418 | LOAD_3_PARA | ||
| 419 | %ifndef X86_32 | ||
| 420 | movsx r2, r2d | ||
| 421 | %endif | ||
| 422 | sub r1, 1 | ||
| 423 | sub r1, r2 | ||
| 424 | |||
| 425 | pxor mm7, mm7 | ||
| 426 | movq mm0, [r1] | ||
| 427 | movq mm5, [sse2_plane_dec_c] | ||
| 428 | punpcklbw mm0, mm7 | ||
| 429 | pmullw mm0, mm5 | ||
| 430 | movq mm1, [r1 + 5] | ||
| 431 | movq mm6, [sse2_plane_inc_c] | ||
| 432 | punpcklbw mm1, mm7 | ||
| 433 | pmullw mm1, mm6 | ||
| 434 | psubw mm1, mm0 | ||
| 435 | |||
| 436 | movq2dq xmm1, mm1 | ||
| 437 | pxor xmm2, xmm2 | ||
| 438 | SUMW_HORIZON xmm1,xmm0,xmm2 | ||
| 439 | movd r3d, xmm1 | ||
| 440 | movsx r3, r3w | ||
| 441 | imul r3, 17 | ||
| 442 | add r3, 16 | ||
| 443 | sar r3, 5 ; b = (17 * H + 16) >> 5; | ||
| 444 | SSE2_Copy8Times xmm1, r3d ; mm1 = b,b,b,b,b,b,b,b | ||
| 445 | |||
| 446 | movzx r3, BYTE [r1+8] | ||
| 447 | sub r1, 3 | ||
| 448 | LOAD_COLUMN_C mm0, mm2, mm3, mm4, r1, r2 | ||
| 449 | |||
| 450 | add r1, 3 | ||
| 451 | movzx r4, BYTE [r1+4*r2] | ||
| 452 | add r4, r3 | ||
| 453 | shl r4, 4 ; a = (left[7*stride] + top[7]) << 4; | ||
| 454 | |||
| 455 | sub r1, 3 | ||
| 456 | add r1, r2 | ||
| 457 | LOAD_COLUMN_C mm7, mm2, mm3, mm4, r1, r2 | ||
| 458 | pxor mm4, mm4 | ||
| 459 | punpckhbw mm0, mm4 | ||
| 460 | pmullw mm0, mm5 | ||
| 461 | punpckhbw mm7, mm4 | ||
| 462 | pmullw mm7, mm6 | ||
| 463 | psubw mm7, mm0 | ||
| 464 | |||
| 465 | movq2dq xmm7, mm7 | ||
| 466 | pxor xmm2, xmm2 | ||
| 467 | SUMW_HORIZON xmm7,xmm0,xmm2 | ||
| 468 | movd r3d, xmm7 ; V | ||
| 469 | movsx r3, r3w | ||
| 470 | imul r3, 17 | ||
| 471 | add r3, 16 | ||
| 472 | sar r3, 5 ; c = (17 * V + 16) >> 5; | ||
| 473 | SSE2_Copy8Times xmm4, r3d ; mm4 = c,c,c,c,c,c,c,c | ||
| 474 | |||
| 475 | ;mov esi, [esp + pushsize + 4] | ||
| 476 | add r4, 16 | ||
| 477 | imul r3, -3 | ||
| 478 | add r3, r4 ; s = a + 16 + (-3)*c | ||
| 479 | SSE2_Copy8Times xmm0, r3d ; xmm0 = s,s,s,s,s,s,s,s | ||
| 480 | |||
| 481 | xor r3, r3 | ||
| 482 | movdqa xmm5, [sse2_plane_mul_b_c] | ||
| 483 | |||
| 484 | get_i_chroma_pred_plane_sse2_1: | ||
| 485 | movdqa xmm2, xmm1 | ||
| 486 | pmullw xmm2, xmm5 | ||
| 487 | paddw xmm2, xmm0 | ||
| 488 | psraw xmm2, 5 | ||
| 489 | packuswb xmm2, xmm2 | ||
| 490 | movq [r0], xmm2 | ||
| 491 | paddw xmm0, xmm4 | ||
| 492 | add r0, 8 | ||
| 493 | inc r3 | ||
| 494 | cmp r3, 8 | ||
| 495 | jnz get_i_chroma_pred_plane_sse2_1 | ||
| 496 | pop r4 | ||
| 497 | pop r3 | ||
| 498 | WELSEMMS | ||
| 499 | ret | ||
| 500 | |||
| 501 | ALIGN 16 | ||
| 502 | ;*********************************************************************** | ||
| 503 | ; 0 |1 |2 |3 |4 | | ||
| 504 | ; 6 |7 |8 |9 |10| | ||
| 505 | ; 11|12|13|14|15| | ||
| 506 | ; 16|17|18|19|20| | ||
| 507 | ; 21|22|23|24|25| | ||
| 508 | ; 7 is the start pixel of current 4x4 block | ||
| 509 | ; pred[7] = ([6]+[0]*2+[1]+2)/4 | ||
| 510 | ; | ||
| 511 | ; void __cdecl WelsI4x4LumaPredDDR_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 512 | ; | ||
| 513 | ;*********************************************************************** | ||
| 514 | WelsI4x4LumaPredDDR_mmx: | ||
| 515 | ;mov edx,[esp+4] ;pred | ||
| 516 | ;mov eax,[esp+8] ;pRef | ||
| 517 | ;mov ecx,[esp+12] ;stride | ||
| 518 | %assign push_num 0 | ||
| 519 | LOAD_3_PARA | ||
| 520 | %ifndef X86_32 | ||
| 521 | movsx r2, r2d | ||
| 522 | %endif | ||
| 523 | movq mm1,[r1+r2-8] ;get value of 11,decreasing 8 is trying to improve the performance of movq mm1[8] = 11 | ||
| 524 | movq mm2,[r1-8] ;get value of 6 mm2[8] = 6 | ||
| 525 | sub r1, r2 ;mov eax to above line of current block(postion of 1) | ||
| 526 | punpckhbw mm2,[r1-8] ;mm2[8](high 8th byte of mm2) = [0](value of 0), mm2[7]= [6] | ||
| 527 | movd mm3,[r1] ;get value 1, mm3[1] = [1],mm3[2]=[2],mm3[3]=[3] | ||
| 528 | punpckhwd mm1,mm2 ;mm1[8]=[0],mm1[7]=[6],mm1[6]=[11] | ||
| 529 | psllq mm3,18h ;mm3[5]=[1] | ||
| 530 | psrlq mm1,28h ;mm1[3]=[0],mm1[2]=[6],mm1[1]=[11] | ||
| 531 | por mm3,mm1 ;mm3[6]=[3],mm3[5]=[2],mm3[4]=[1],mm3[3]=[0],mm3[2]=[6],mm3[1]=[11] | ||
| 532 | movq mm1,mm3 ;mm1[6]=[3],mm1[5]=[2],mm1[4]=[1],mm1[3]=[0],mm1[2]=[6],mm1[1]=[11] | ||
| 533 | lea r1,[r1+r2*2-8h] ;set eax point to 12 | ||
| 534 | movq mm4,[r1+r2] ;get value of 16, mm4[8]=[16] | ||
| 535 | psllq mm3,8 ;mm3[7]=[3],mm3[6]=[2],mm3[5]=[1],mm3[4]=[0],mm3[3]=[6],mm3[2]=[11],mm3[1]=0 | ||
| 536 | psrlq mm4,38h ;mm4[1]=[16] | ||
| 537 | por mm3,mm4 ;mm3[7]=[3],mm3[6]=[2],mm3[5]=[1],mm3[4]=[0],mm3[3]=[6],mm3[2]=[11],mm3[1]=[16] | ||
| 538 | movq mm2,mm3 ;mm2[7]=[3],mm2[6]=[2],mm2[5]=[1],mm2[4]=[0],mm2[3]=[6],mm2[2]=[11],mm2[1]=[16] | ||
| 539 | movq mm4,[r1+r2*2] ;mm4[8]=[21] | ||
| 540 | psllq mm3,8 ;mm3[8]=[3],mm3[7]=[2],mm3[6]=[1],mm3[5]=[0],mm3[4]=[6],mm3[3]=[11],mm3[2]=[16],mm3[1]=0 | ||
| 541 | psrlq mm4,38h ;mm4[1]=[21] | ||
| 542 | por mm3,mm4 ;mm3[8]=[3],mm3[7]=[2],mm3[6]=[1],mm3[5]=[0],mm3[4]=[6],mm3[3]=[11],mm3[2]=[16],mm3[1]=[21] | ||
| 543 | movq mm4,mm3 ;mm4[8]=[3],mm4[7]=[2],mm4[6]=[1],mm4[5]=[0],mm4[4]=[6],mm4[3]=[11],mm4[2]=[16],mm4[1]=[21] | ||
| 544 | pavgb mm3,mm1 ;mm3=([11]+[21]+1)/2 | ||
| 545 | pxor mm1,mm4 ;find odd value in the lowest bit of each byte | ||
| 546 | pand mm1,[mmx_01bytes] ;set the odd bit | ||
| 547 | psubusb mm3,mm1 ;decrease 1 from odd bytes | ||
| 548 | pavgb mm2,mm3 ;mm2=(([11]+[21]+1)/2+1+[16])/2 | ||
| 549 | |||
| 550 | movd [r0+12],mm2 | ||
| 551 | psrlq mm2,8 | ||
| 552 | movd [r0+8],mm2 | ||
| 553 | psrlq mm2,8 | ||
| 554 | movd [r0+4],mm2 | ||
| 555 | psrlq mm2,8 | ||
| 556 | movd [r0],mm2 | ||
| 557 | WELSEMMS | ||
| 558 | ret | ||
| 559 | |||
| 560 | ALIGN 16 | ||
| 561 | ;*********************************************************************** | ||
| 562 | ; 0 |1 |2 |3 |4 | | ||
| 563 | ; 5 |6 |7 |8 |9 | | ||
| 564 | ; 10|11|12|13|14| | ||
| 565 | ; 15|16|17|18|19| | ||
| 566 | ; 20|21|22|23|24| | ||
| 567 | ; 6 is the start pixel of current 4x4 block | ||
| 568 | ; pred[6] = ([1]+[2]+[3]+[4]+[5]+[10]+[15]+[20]+4)/8 | ||
| 569 | ; | ||
| 570 | ; void __cdecl WelsI4x4LumaPredDc_sse2(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 571 | ; | ||
| 572 | ;*********************************************************************** | ||
| 573 | WelsI4x4LumaPredDc_sse2: | ||
| 574 | push r3 | ||
| 575 | push r4 | ||
| 576 | %assign push_num 2 | ||
| 577 | LOAD_3_PARA | ||
| 578 | %ifndef X86_32 | ||
| 579 | movsx r2, r2d | ||
| 580 | %endif | ||
| 581 | movzx r4, byte [r1-1h] | ||
| 582 | sub r1, r2 | ||
| 583 | movd xmm0, [r1] | ||
| 584 | pxor xmm1, xmm1 | ||
| 585 | psadbw xmm0, xmm1 | ||
| 586 | xor r3, r3 | ||
| 587 | movd r3d, xmm0 | ||
| 588 | add r3, r4 | ||
| 589 | movzx r4, byte [r1+r2*2-1h] | ||
| 590 | add r3, r4 | ||
| 591 | |||
| 592 | lea r1, [r1+r2*2-1] | ||
| 593 | movzx r4, byte [r1+r2] | ||
| 594 | add r3, r4 | ||
| 595 | |||
| 596 | movzx r4, byte [r1+r2*2] | ||
| 597 | add r3, r4 | ||
| 598 | add r3, 4 | ||
| 599 | sar r3, 3 | ||
| 600 | imul r3, 0x01010101 | ||
| 601 | |||
| 602 | movd xmm0, r3d | ||
| 603 | pshufd xmm0, xmm0, 0 | ||
| 604 | movdqa [r0], xmm0 | ||
| 605 | pop r4 | ||
| 606 | pop r3 | ||
| 607 | ret | ||
| 608 | |||
| 609 | ALIGN 16 | ||
| 610 | ;*********************************************************************** | ||
| 611 | ; void __cdecl WelsIChromaPredH_mmx(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 612 | ; copy 8 pixel of 8 line from left | ||
| 613 | ;*********************************************************************** | ||
| 614 | %macro MMX_PRED_H_8X8_ONE_LINE 4 | ||
| 615 | movq %1, [%3-8] | ||
| 616 | psrlq %1, 38h | ||
| 617 | |||
| 618 | ;pmuludq %1, [mmx_01bytes] ;extend to 4 bytes | ||
| 619 | pmullw %1, [mmx_01bytes] | ||
| 620 | pshufw %1, %1, 0 | ||
| 621 | movq [%4], %1 | ||
| 622 | %endmacro | ||
| 623 | |||
| 624 | %macro MMX_PRED_H_8X8_ONE_LINEE 4 | ||
| 625 | movq %1, [%3+r2-8] | ||
| 626 | psrlq %1, 38h | ||
| 627 | |||
| 628 | ;pmuludq %1, [mmx_01bytes] ;extend to 4 bytes | ||
| 629 | pmullw %1, [mmx_01bytes] | ||
| 630 | pshufw %1, %1, 0 | ||
| 631 | movq [%4], %1 | ||
| 632 | %endmacro | ||
| 633 | |||
| 634 | WELS_EXTERN WelsIChromaPredH_mmx | ||
| 635 | WelsIChromaPredH_mmx: | ||
| 636 | ;mov edx, [esp+4] ;pred | ||
| 637 | ;mov eax, [esp+8] ;pRef | ||
| 638 | ;mov ecx, [esp+12] ;stride | ||
| 639 | %assign push_num 0 | ||
| 640 | LOAD_3_PARA | ||
| 641 | %ifndef X86_32 | ||
| 642 | movsx r2, r2d | ||
| 643 | %endif | ||
| 644 | movq mm0, [r1-8] | ||
| 645 | psrlq mm0, 38h | ||
| 646 | |||
| 647 | ;pmuludq mm0, [mmx_01bytes] ;extend to 4 bytes | ||
| 648 | pmullw mm0, [mmx_01bytes] | ||
| 649 | pshufw mm0, mm0, 0 | ||
| 650 | movq [r0], mm0 | ||
| 651 | |||
| 652 | MMX_PRED_H_8X8_ONE_LINEE mm0, mm1, r1,r0+8 | ||
| 653 | |||
| 654 | lea r1,[r1+r2*2] | ||
| 655 | MMX_PRED_H_8X8_ONE_LINE mm0, mm1, r1,r0+16 | ||
| 656 | |||
| 657 | MMX_PRED_H_8X8_ONE_LINEE mm0, mm1, r1,r0+24 | ||
| 658 | |||
| 659 | lea r1,[r1+r2*2] | ||
| 660 | MMX_PRED_H_8X8_ONE_LINE mm0, mm1, r1,r0+32 | ||
| 661 | |||
| 662 | MMX_PRED_H_8X8_ONE_LINEE mm0, mm1, r1,r0+40 | ||
| 663 | |||
| 664 | lea r1,[r1+r2*2] | ||
| 665 | MMX_PRED_H_8X8_ONE_LINE mm0, mm1, r1,r0+48 | ||
| 666 | |||
| 667 | MMX_PRED_H_8X8_ONE_LINEE mm0, mm1, r1,r0+56 | ||
| 668 | WELSEMMS | ||
| 669 | ret | ||
| 670 | |||
| 671 | ALIGN 16 | ||
| 672 | ;*********************************************************************** | ||
| 673 | ; void __cdecl WelsI4x4LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 674 | ; copy pixels from top 4 pixels | ||
| 675 | ;*********************************************************************** | ||
| 676 | WELS_EXTERN WelsI4x4LumaPredV_sse2 | ||
| 677 | WelsI4x4LumaPredV_sse2: | ||
| 678 | %assign push_num 0 | ||
| 679 | LOAD_3_PARA | ||
| 680 | %ifndef X86_32 | ||
| 681 | movsx r2, r2d | ||
| 682 | %endif | ||
| 683 | sub r1, r2 | ||
| 684 | movd xmm0, [r1] | ||
| 685 | pshufd xmm0, xmm0, 0 | ||
| 686 | movdqa [r0], xmm0 | ||
| 687 | ret | ||
| 688 | |||
| 689 | ALIGN 16 | ||
| 690 | ;*********************************************************************** | ||
| 691 | ; void __cdecl WelsIChromaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 692 | ; copy 8 pixels from top 8 pixels | ||
| 693 | ;*********************************************************************** | ||
| 694 | WELS_EXTERN WelsIChromaPredV_sse2 | ||
| 695 | WelsIChromaPredV_sse2: | ||
| 696 | %assign push_num 0 | ||
| 697 | LOAD_3_PARA | ||
| 698 | %ifndef X86_32 | ||
| 699 | movsx r2, r2d | ||
| 700 | %endif | ||
| 701 | sub r1, r2 | ||
| 702 | movq xmm0, [r1] | ||
| 703 | movdqa xmm1, xmm0 | ||
| 704 | punpcklqdq xmm0, xmm1 | ||
| 705 | movdqa [r0], xmm0 | ||
| 706 | movdqa [r0+16], xmm0 | ||
| 707 | movdqa [r0+32], xmm0 | ||
| 708 | movdqa [r0+48], xmm0 | ||
| 709 | ret | ||
| 710 | |||
| 711 | ALIGN 16 | ||
| 712 | ;*********************************************************************** | ||
| 713 | ; lt|t0|t1|t2|t3| | ||
| 714 | ; l0| | ||
| 715 | ; l1| | ||
| 716 | ; l2| | ||
| 717 | ; l3| | ||
| 718 | ; t3 will never been used | ||
| 719 | ; destination: | ||
| 720 | ; |a |b |c |d | | ||
| 721 | ; |e |f |a |b | | ||
| 722 | ; |g |h |e |f | | ||
| 723 | ; |i |j |g |h | | ||
| 724 | |||
| 725 | ; a = (1 + lt + l0)>>1 | ||
| 726 | ; e = (1 + l0 + l1)>>1 | ||
| 727 | ; g = (1 + l1 + l2)>>1 | ||
| 728 | ; i = (1 + l2 + l3)>>1 | ||
| 729 | |||
| 730 | ; d = (2 + t0 + (t1<<1) + t2)>>2 | ||
| 731 | ; c = (2 + lt + (t0<<1) + t1)>>2 | ||
| 732 | ; b = (2 + l0 + (lt<<1) + t0)>>2 | ||
| 733 | |||
| 734 | ; f = (2 + l1 + (l0<<1) + lt)>>2 | ||
| 735 | ; h = (2 + l2 + (l1<<1) + l0)>>2 | ||
| 736 | ; j = (2 + l3 + (l2<<1) + l1)>>2 | ||
| 737 | ; [b a f e h g j i] + [d c b a] --> mov to memory | ||
| 738 | ; | ||
| 739 | ; void WelsI4x4LumaPredHD_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 740 | ;*********************************************************************** | ||
| 741 | WELS_EXTERN WelsI4x4LumaPredHD_mmx | ||
| 742 | WelsI4x4LumaPredHD_mmx: | ||
| 743 | %assign push_num 0 | ||
| 744 | LOAD_3_PARA | ||
| 745 | %ifndef X86_32 | ||
| 746 | movsx r2, r2d | ||
| 747 | %endif | ||
| 748 | sub r1, r2 | ||
| 749 | movd mm0, [r1-1] ; mm0 = [xx xx xx xx t2 t1 t0 lt] | ||
| 750 | psllq mm0, 20h ; mm0 = [t2 t1 t0 lt xx xx xx xx] | ||
| 751 | |||
| 752 | movd mm1, [r1+2*r2-4] | ||
| 753 | punpcklbw mm1, [r1+r2-4] ; mm1[7] = l0, mm1[6] = l1 | ||
| 754 | lea r1, [r1+2*r2] | ||
| 755 | movd mm2, [r1+2*r2-4] | ||
| 756 | punpcklbw mm2, [r1+r2-4] ; mm2[7] = l2, mm2[6] = l3 | ||
| 757 | punpckhwd mm2, mm1 ; mm2 = [l0 l1 l2 l3 xx xx xx xx] | ||
| 758 | psrlq mm2, 20h | ||
| 759 | pxor mm0, mm2 ; mm0 = [t2 t1 t0 lt l0 l1 l2 l3] | ||
| 760 | |||
| 761 | movq mm1, mm0 | ||
| 762 | psrlq mm1, 10h ; mm1 = [xx xx t2 t1 t0 lt l0 l1] | ||
| 763 | movq mm2, mm0 | ||
| 764 | psrlq mm2, 8h ; mm2 = [xx t2 t1 t0 lt l0 l1 l2] | ||
| 765 | movq mm3, mm2 | ||
| 766 | movq mm4, mm1 | ||
| 767 | pavgb mm1, mm0 | ||
| 768 | |||
| 769 | pxor mm4, mm0 ; find odd value in the lowest bit of each byte | ||
| 770 | pand mm4, [mmx_01bytes] ; set the odd bit | ||
| 771 | psubusb mm1, mm4 ; decrease 1 from odd bytes | ||
| 772 | |||
| 773 | pavgb mm2, mm1 ; mm2 = [xx xx d c b f h j] | ||
| 774 | |||
| 775 | movq mm4, mm0 | ||
| 776 | pavgb mm3, mm4 ; mm3 = [xx xx xx xx a e g i] | ||
| 777 | punpcklbw mm3, mm2 ; mm3 = [b a f e h g j i] | ||
| 778 | |||
| 779 | psrlq mm2, 20h | ||
| 780 | psllq mm2, 30h ; mm2 = [d c 0 0 0 0 0 0] | ||
| 781 | movq mm4, mm3 | ||
| 782 | psrlq mm4, 10h ; mm4 = [0 0 b a f e h j] | ||
| 783 | pxor mm2, mm4 ; mm2 = [d c b a xx xx xx xx] | ||
| 784 | psrlq mm2, 20h ; mm2 = [xx xx xx xx d c b a] | ||
| 785 | |||
| 786 | movd [r0], mm2 | ||
| 787 | movd [r0+12], mm3 | ||
| 788 | psrlq mm3, 10h | ||
| 789 | movd [r0+8], mm3 | ||
| 790 | psrlq mm3, 10h | ||
| 791 | movd [r0+4], mm3 | ||
| 792 | WELSEMMS | ||
| 793 | ret | ||
| 794 | |||
| 795 | ALIGN 16 | ||
| 796 | ;*********************************************************************** | ||
| 797 | ; lt|t0|t1|t2|t3| | ||
| 798 | ; l0| | ||
| 799 | ; l1| | ||
| 800 | ; l2| | ||
| 801 | ; l3| | ||
| 802 | ; t3 will never been used | ||
| 803 | ; destination: | ||
| 804 | ; |a |b |c |d | | ||
| 805 | ; |c |d |e |f | | ||
| 806 | ; |e |f |g |g | | ||
| 807 | ; |g |g |g |g | | ||
| 808 | |||
| 809 | ; a = (1 + l0 + l1)>>1 | ||
| 810 | ; c = (1 + l1 + l2)>>1 | ||
| 811 | ; e = (1 + l2 + l3)>>1 | ||
| 812 | ; g = l3 | ||
| 813 | |||
| 814 | ; b = (2 + l0 + (l1<<1) + l2)>>2 | ||
| 815 | ; d = (2 + l1 + (l2<<1) + l3)>>2 | ||
| 816 | ; f = (2 + l2 + (l3<<1) + l3)>>2 | ||
| 817 | |||
| 818 | ; [g g f e d c b a] + [g g g g] --> mov to memory | ||
| 819 | ; | ||
| 820 | ; void WelsI4x4LumaPredHU_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 821 | ;*********************************************************************** | ||
| 822 | WELS_EXTERN WelsI4x4LumaPredHU_mmx | ||
| 823 | WelsI4x4LumaPredHU_mmx: | ||
| 824 | %assign push_num 0 | ||
| 825 | LOAD_3_PARA | ||
| 826 | %ifndef X86_32 | ||
| 827 | movsx r2, r2d | ||
| 828 | %endif | ||
| 829 | movd mm0, [r1-4] ; mm0[3] = l0 | ||
| 830 | punpcklbw mm0, [r1+r2-4] ; mm0[7] = l1, mm0[6] = l0 | ||
| 831 | lea r1, [r1+2*r2] | ||
| 832 | movd mm2, [r1-4] ; mm2[3] = l2 | ||
| 833 | movd mm4, [r1+r2-4] ; mm4[3] = l3 | ||
| 834 | punpcklbw mm2, mm4 | ||
| 835 | punpckhwd mm0, mm2 ; mm0 = [l3 l2 l1 l0 xx xx xx xx] | ||
| 836 | |||
| 837 | psrlq mm4, 18h | ||
| 838 | psllq mm4, 38h ; mm4 = [l3 xx xx xx xx xx xx xx] | ||
| 839 | psrlq mm0, 8h | ||
| 840 | pxor mm0, mm4 ; mm0 = [l3 l3 l2 l1 l0 xx xx xx] | ||
| 841 | |||
| 842 | movq mm1, mm0 | ||
| 843 | psllq mm1, 8h ; mm1 = [l3 l2 l1 l0 xx xx xx xx] | ||
| 844 | movq mm3, mm1 ; mm3 = [l3 l2 l1 l0 xx xx xx xx] | ||
| 845 | pavgb mm1, mm0 ; mm1 = [g e c a xx xx xx xx] | ||
| 846 | |||
| 847 | movq mm2, mm0 | ||
| 848 | psllq mm2, 10h ; mm2 = [l2 l1 l0 xx xx xx xx xx] | ||
| 849 | movq mm5, mm2 | ||
| 850 | pavgb mm2, mm0 | ||
| 851 | |||
| 852 | pxor mm5, mm0 ; find odd value in the lowest bit of each byte | ||
| 853 | pand mm5, [mmx_01bytes] ; set the odd bit | ||
| 854 | psubusb mm2, mm5 ; decrease 1 from odd bytes | ||
| 855 | |||
| 856 | pavgb mm2, mm3 ; mm2 = [f d b xx xx xx xx xx] | ||
| 857 | |||
| 858 | psrlq mm2, 8h | ||
| 859 | pxor mm2, mm4 ; mm2 = [g f d b xx xx xx xx] | ||
| 860 | |||
| 861 | punpckhbw mm1, mm2 ; mm1 = [g g f e d c b a] | ||
| 862 | punpckhbw mm4, mm4 ; mm4 = [g g xx xx xx xx xx xx] | ||
| 863 | punpckhbw mm4, mm4 ; mm4 = [g g g g xx xx xx xx] | ||
| 864 | |||
| 865 | psrlq mm4, 20h | ||
| 866 | movd [r0+12], mm4 | ||
| 867 | |||
| 868 | movd [r0], mm1 | ||
| 869 | psrlq mm1, 10h | ||
| 870 | movd [r0+4], mm1 | ||
| 871 | psrlq mm1, 10h | ||
| 872 | movd [r0+8], mm1 | ||
| 873 | WELSEMMS | ||
| 874 | ret | ||
| 875 | |||
| 876 | |||
| 877 | |||
| 878 | ALIGN 16 | ||
| 879 | ;*********************************************************************** | ||
| 880 | ; lt|t0|t1|t2|t3| | ||
| 881 | ; l0| | ||
| 882 | ; l1| | ||
| 883 | ; l2| | ||
| 884 | ; l3| | ||
| 885 | ; l3 will never been used | ||
| 886 | ; destination: | ||
| 887 | ; |a |b |c |d | | ||
| 888 | ; |e |f |g |h | | ||
| 889 | ; |i |a |b |c | | ||
| 890 | ; |j |e |f |g | | ||
| 891 | |||
| 892 | ; a = (1 + lt + t0)>>1 | ||
| 893 | ; b = (1 + t0 + t1)>>1 | ||
| 894 | ; c = (1 + t1 + t2)>>1 | ||
| 895 | ; d = (1 + t2 + t3)>>1 | ||
| 896 | |||
| 897 | ; e = (2 + l0 + (lt<<1) + t0)>>2 | ||
| 898 | ; f = (2 + lt + (t0<<1) + t1)>>2 | ||
| 899 | ; g = (2 + t0 + (t1<<1) + t2)>>2 | ||
| 900 | |||
| 901 | ; h = (2 + t1 + (t2<<1) + t3)>>2 | ||
| 902 | ; i = (2 + lt + (l0<<1) + l1)>>2 | ||
| 903 | ; j = (2 + l0 + (l1<<1) + l2)>>2 | ||
| 904 | ; | ||
| 905 | ; void WelsI4x4LumaPredVR_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 906 | ;*********************************************************************** | ||
| 907 | WELS_EXTERN WelsI4x4LumaPredVR_mmx | ||
| 908 | WelsI4x4LumaPredVR_mmx: | ||
| 909 | %assign push_num 0 | ||
| 910 | LOAD_3_PARA | ||
| 911 | %ifndef X86_32 | ||
| 912 | movsx r2, r2d | ||
| 913 | %endif | ||
| 914 | sub r1, r2 | ||
| 915 | movq mm0, [r1-1] ; mm0 = [xx xx xx t3 t2 t1 t0 lt] | ||
| 916 | psllq mm0, 18h ; mm0 = [t3 t2 t1 t0 lt xx xx xx] | ||
| 917 | |||
| 918 | movd mm1, [r1+2*r2-4] | ||
| 919 | punpcklbw mm1, [r1+r2-4] ; mm1[7] = l0, mm1[6] = l1 | ||
| 920 | lea r1, [r1+2*r2] | ||
| 921 | movq mm2, [r1+r2-8] ; mm2[7] = l2 | ||
| 922 | punpckhwd mm2, mm1 ; mm2 = [l0 l1 l2 xx xx xx xx xx] | ||
| 923 | psrlq mm2, 28h | ||
| 924 | pxor mm0, mm2 ; mm0 = [t3 t2 t1 t0 lt l0 l1 l2] | ||
| 925 | |||
| 926 | movq mm1, mm0 | ||
| 927 | psllq mm1, 8h ; mm1 = [t2 t1 t0 lt l0 l1 l2 xx] | ||
| 928 | pavgb mm1, mm0 ; mm1 = [d c b a xx xx xx xx] | ||
| 929 | |||
| 930 | movq mm2, mm0 | ||
| 931 | psllq mm2, 10h ; mm2 = [t1 t0 lt l0 l1 l2 xx xx] | ||
| 932 | movq mm3, mm2 | ||
| 933 | pavgb mm2, mm0 | ||
| 934 | |||
| 935 | pxor mm3, mm0 ; find odd value in the lowest bit of each byte | ||
| 936 | pand mm3, [mmx_01bytes] ; set the odd bit | ||
| 937 | psubusb mm2, mm3 ; decrease 1 from odd bytes | ||
| 938 | |||
| 939 | movq mm3, mm0 | ||
| 940 | psllq mm3, 8h ; mm3 = [t2 t1 t0 lt l0 l1 l2 xx] | ||
| 941 | pavgb mm3, mm2 ; mm3 = [h g f e i j xx xx] | ||
| 942 | movq mm2, mm3 | ||
| 943 | |||
| 944 | psrlq mm1, 20h ; mm1 = [xx xx xx xx d c b a] | ||
| 945 | movd [r0], mm1 | ||
| 946 | |||
| 947 | psrlq mm2, 20h ; mm2 = [xx xx xx xx h g f e] | ||
| 948 | movd [r0+4], mm2 | ||
| 949 | |||
| 950 | movq mm4, mm3 | ||
| 951 | psllq mm4, 20h | ||
| 952 | psrlq mm4, 38h ; mm4 = [xx xx xx xx xx xx xx i] | ||
| 953 | |||
| 954 | movq mm5, mm3 | ||
| 955 | psllq mm5, 28h | ||
| 956 | psrlq mm5, 38h ; mm5 = [xx xx xx xx xx xx xx j] | ||
| 957 | |||
| 958 | psllq mm1, 8h | ||
| 959 | pxor mm4, mm1 ; mm4 = [xx xx xx xx c b a i] | ||
| 960 | movd [r0+8], mm4 | ||
| 961 | |||
| 962 | psllq mm2, 8h | ||
| 963 | pxor mm5, mm2 ; mm5 = [xx xx xx xx g f e j] | ||
| 964 | movd [r0+12], mm5 | ||
| 965 | WELSEMMS | ||
| 966 | ret | ||
| 967 | |||
| 968 | ALIGN 16 | ||
| 969 | ;*********************************************************************** | ||
| 970 | ; lt|t0|t1|t2|t3|t4|t5|t6|t7 | ||
| 971 | ; l0| | ||
| 972 | ; l1| | ||
| 973 | ; l2| | ||
| 974 | ; l3| | ||
| 975 | ; lt,t0,t1,t2,t3 will never been used | ||
| 976 | ; destination: | ||
| 977 | ; |a |b |c |d | | ||
| 978 | ; |b |c |d |e | | ||
| 979 | ; |c |d |e |f | | ||
| 980 | ; |d |e |f |g | | ||
| 981 | |||
| 982 | ; a = (2 + t0 + t2 + (t1<<1))>>2 | ||
| 983 | ; b = (2 + t1 + t3 + (t2<<1))>>2 | ||
| 984 | ; c = (2 + t2 + t4 + (t3<<1))>>2 | ||
| 985 | ; d = (2 + t3 + t5 + (t4<<1))>>2 | ||
| 986 | |||
| 987 | ; e = (2 + t4 + t6 + (t5<<1))>>2 | ||
| 988 | ; f = (2 + t5 + t7 + (t6<<1))>>2 | ||
| 989 | ; g = (2 + t6 + t7 + (t7<<1))>>2 | ||
| 990 | |||
| 991 | ; [g f e d c b a] --> mov to memory | ||
| 992 | ; | ||
| 993 | ; void WelsI4x4LumaPredDDL_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 994 | ;*********************************************************************** | ||
| 995 | WELS_EXTERN WelsI4x4LumaPredDDL_mmx | ||
| 996 | WelsI4x4LumaPredDDL_mmx: | ||
| 997 | %assign push_num 0 | ||
| 998 | LOAD_3_PARA | ||
| 999 | %ifndef X86_32 | ||
| 1000 | movsx r2, r2d | ||
| 1001 | %endif | ||
| 1002 | sub r1, r2 | ||
| 1003 | movq mm0, [r1] ; mm0 = [t7 t6 t5 t4 t3 t2 t1 t0] | ||
| 1004 | movq mm1, mm0 | ||
| 1005 | movq mm2, mm0 | ||
| 1006 | |||
| 1007 | movq mm3, mm0 | ||
| 1008 | psrlq mm3, 38h | ||
| 1009 | psllq mm3, 38h ; mm3 = [t7 xx xx xx xx xx xx xx] | ||
| 1010 | |||
| 1011 | psllq mm1, 8h ; mm1 = [t6 t5 t4 t3 t2 t1 t0 xx] | ||
| 1012 | psrlq mm2, 8h | ||
| 1013 | pxor mm2, mm3 ; mm2 = [t7 t7 t6 t5 t4 t3 t2 t1] | ||
| 1014 | |||
| 1015 | movq mm3, mm1 | ||
| 1016 | pavgb mm1, mm2 | ||
| 1017 | pxor mm3, mm2 ; find odd value in the lowest bit of each byte | ||
| 1018 | pand mm3, [mmx_01bytes] ; set the odd bit | ||
| 1019 | psubusb mm1, mm3 ; decrease 1 from odd bytes | ||
| 1020 | |||
| 1021 | pavgb mm0, mm1 ; mm0 = [g f e d c b a xx] | ||
| 1022 | |||
| 1023 | psrlq mm0, 8h | ||
| 1024 | movd [r0], mm0 | ||
| 1025 | psrlq mm0, 8h | ||
| 1026 | movd [r0+4], mm0 | ||
| 1027 | psrlq mm0, 8h | ||
| 1028 | movd [r0+8], mm0 | ||
| 1029 | psrlq mm0, 8h | ||
| 1030 | movd [r0+12], mm0 | ||
| 1031 | WELSEMMS | ||
| 1032 | ret | ||
| 1033 | |||
| 1034 | |||
| 1035 | ALIGN 16 | ||
| 1036 | ;*********************************************************************** | ||
| 1037 | ; lt|t0|t1|t2|t3|t4|t5|t6|t7 | ||
| 1038 | ; l0| | ||
| 1039 | ; l1| | ||
| 1040 | ; l2| | ||
| 1041 | ; l3| | ||
| 1042 | ; lt,t0,t1,t2,t3 will never been used | ||
| 1043 | ; destination: | ||
| 1044 | ; |a |b |c |d | | ||
| 1045 | ; |e |f |g |h | | ||
| 1046 | ; |b |c |d |i | | ||
| 1047 | ; |f |g |h |j | | ||
| 1048 | |||
| 1049 | ; a = (1 + t0 + t1)>>1 | ||
| 1050 | ; b = (1 + t1 + t2)>>1 | ||
| 1051 | ; c = (1 + t2 + t3)>>1 | ||
| 1052 | ; d = (1 + t3 + t4)>>1 | ||
| 1053 | ; i = (1 + t4 + t5)>>1 | ||
| 1054 | |||
| 1055 | ; e = (2 + t0 + (t1<<1) + t2)>>2 | ||
| 1056 | ; f = (2 + t1 + (t2<<1) + t3)>>2 | ||
| 1057 | ; g = (2 + t2 + (t3<<1) + t4)>>2 | ||
| 1058 | ; h = (2 + t3 + (t4<<1) + t5)>>2 | ||
| 1059 | ; j = (2 + t4 + (t5<<1) + t6)>>2 | ||
| 1060 | |||
| 1061 | ; [i d c b a] + [j h g f e] --> mov to memory | ||
| 1062 | ; | ||
| 1063 | ; void WelsI4x4LumaPredVL_mmx(uint8_t *pred,uint8_t *pRef,int32_t stride) | ||
| 1064 | ;*********************************************************************** | ||
| 1065 | WELS_EXTERN WelsI4x4LumaPredVL_mmx | ||
| 1066 | WelsI4x4LumaPredVL_mmx: | ||
| 1067 | %assign push_num 0 | ||
| 1068 | LOAD_3_PARA | ||
| 1069 | %ifndef X86_32 | ||
| 1070 | movsx r2, r2d | ||
| 1071 | %endif | ||
| 1072 | sub r1, r2 | ||
| 1073 | movq mm0, [r1] ; mm0 = [t7 t6 t5 t4 t3 t2 t1 t0] | ||
| 1074 | movq mm1, mm0 | ||
| 1075 | movq mm2, mm0 | ||
| 1076 | |||
| 1077 | psrlq mm1, 8h ; mm1 = [xx t7 t6 t5 t4 t3 t2 t1] | ||
| 1078 | psrlq mm2, 10h ; mm2 = [xx xx t7 t6 t5 t4 t3 t2] | ||
| 1079 | |||
| 1080 | movq mm3, mm1 | ||
| 1081 | pavgb mm3, mm0 ; mm3 = [xx xx xx i d c b a] | ||
| 1082 | |||
| 1083 | movq mm4, mm2 | ||
| 1084 | pavgb mm2, mm0 | ||
| 1085 | pxor mm4, mm0 ; find odd value in the lowest bit of each byte | ||
| 1086 | pand mm4, [mmx_01bytes] ; set the odd bit | ||
| 1087 | psubusb mm2, mm4 ; decrease 1 from odd bytes | ||
| 1088 | |||
| 1089 | pavgb mm2, mm1 ; mm2 = [xx xx xx j h g f e] | ||
| 1090 | |||
| 1091 | movd [r0], mm3 | ||
| 1092 | psrlq mm3, 8h | ||
| 1093 | movd [r0+8], mm3 | ||
| 1094 | |||
| 1095 | movd [r0+4], mm2 | ||
| 1096 | psrlq mm2, 8h | ||
| 1097 | movd [r0+12], mm2 | ||
| 1098 | WELSEMMS | ||
| 1099 | ret | ||
| 1100 | |||
| 1101 | ALIGN 16 | ||
| 1102 | ;*********************************************************************** | ||
| 1103 | ; | ||
| 1104 | ; void WelsIChromaPredDc_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 1105 | ;*********************************************************************** | ||
| 1106 | WELS_EXTERN WelsIChromaPredDc_sse2 | ||
| 1107 | WelsIChromaPredDc_sse2: | ||
| 1108 | push r3 | ||
| 1109 | push r4 | ||
| 1110 | %assign push_num 2 | ||
| 1111 | LOAD_3_PARA | ||
| 1112 | %ifndef X86_32 | ||
| 1113 | movsx r2, r2d | ||
| 1114 | %endif | ||
| 1115 | sub r1, r2 | ||
| 1116 | movq mm0, [r1] | ||
| 1117 | |||
| 1118 | movzx r3, byte [r1+r2-0x01] ; l1 | ||
| 1119 | lea r1, [r1+2*r2] | ||
| 1120 | movzx r4, byte [r1-0x01] ; l2 | ||
| 1121 | add r3, r4 | ||
| 1122 | movzx r4, byte [r1+r2-0x01] ; l3 | ||
| 1123 | add r3, r4 | ||
| 1124 | lea r1, [r1+2*r2] | ||
| 1125 | movzx r4, byte [r1-0x01] ; l4 | ||
| 1126 | add r3, r4 | ||
| 1127 | movd mm1, r3d ; mm1 = l1+l2+l3+l4 | ||
| 1128 | |||
| 1129 | movzx r3, byte [r1+r2-0x01] ; l5 | ||
| 1130 | lea r1, [r1+2*r2] | ||
| 1131 | movzx r4, byte [r1-0x01] ; l6 | ||
| 1132 | add r3, r4 | ||
| 1133 | movzx r4, byte [r1+r2-0x01] ; l7 | ||
| 1134 | add r3, r4 | ||
| 1135 | lea r1, [r1+2*r2] | ||
| 1136 | movzx r4, byte [r1-0x01] ; l8 | ||
| 1137 | add r3, r4 | ||
| 1138 | movd mm2, r3d ; mm2 = l5+l6+l7+l8 | ||
| 1139 | |||
| 1140 | movq mm3, mm0 | ||
| 1141 | psrlq mm0, 0x20 | ||
| 1142 | psllq mm3, 0x20 | ||
| 1143 | psrlq mm3, 0x20 | ||
| 1144 | pxor mm4, mm4 | ||
| 1145 | psadbw mm0, mm4 | ||
| 1146 | psadbw mm3, mm4 ; sum1 = mm3+mm1, sum2 = mm0, sum3 = mm2 | ||
| 1147 | |||
| 1148 | paddq mm3, mm1 | ||
| 1149 | movq mm1, mm2 | ||
| 1150 | paddq mm1, mm0; ; sum1 = mm3, sum2 = mm0, sum3 = mm2, sum4 = mm1 | ||
| 1151 | |||
| 1152 | movq mm4, [mmx_0x02] | ||
| 1153 | |||
| 1154 | paddq mm0, mm4 | ||
| 1155 | psrlq mm0, 0x02 | ||
| 1156 | |||
| 1157 | paddq mm2, mm4 | ||
| 1158 | psrlq mm2, 0x02 | ||
| 1159 | |||
| 1160 | paddq mm3, mm4 | ||
| 1161 | paddq mm3, mm4 | ||
| 1162 | psrlq mm3, 0x03 | ||
| 1163 | |||
| 1164 | paddq mm1, mm4 | ||
| 1165 | paddq mm1, mm4 | ||
| 1166 | psrlq mm1, 0x03 | ||
| 1167 | |||
| 1168 | pmuludq mm0, [mmx_01bytes] | ||
| 1169 | pmuludq mm3, [mmx_01bytes] | ||
| 1170 | psllq mm0, 0x20 | ||
| 1171 | pxor mm0, mm3 ; mm0 = m_up | ||
| 1172 | |||
| 1173 | pmuludq mm2, [mmx_01bytes] | ||
| 1174 | pmuludq mm1, [mmx_01bytes] | ||
| 1175 | psllq mm1, 0x20 | ||
| 1176 | pxor mm1, mm2 ; mm2 = m_down | ||
| 1177 | |||
| 1178 | movq [r0], mm0 | ||
| 1179 | movq [r0+0x08], mm0 | ||
| 1180 | movq [r0+0x10], mm0 | ||
| 1181 | movq [r0+0x18], mm0 | ||
| 1182 | |||
| 1183 | movq [r0+0x20], mm1 | ||
| 1184 | movq [r0+0x28], mm1 | ||
| 1185 | movq [r0+0x30], mm1 | ||
| 1186 | movq [r0+0x38], mm1 | ||
| 1187 | |||
| 1188 | pop r4 | ||
| 1189 | pop r3 | ||
| 1190 | WELSEMMS | ||
| 1191 | ret | ||
| 1192 | |||
| 1193 | |||
| 1194 | |||
| 1195 | ALIGN 16 | ||
| 1196 | ;*********************************************************************** | ||
| 1197 | ; | ||
| 1198 | ; void WelsI16x16LumaPredDc_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride) | ||
| 1199 | ;*********************************************************************** | ||
| 1200 | WELS_EXTERN WelsI16x16LumaPredDc_sse2 | ||
| 1201 | WelsI16x16LumaPredDc_sse2: | ||
| 1202 | push r3 | ||
| 1203 | push r4 | ||
| 1204 | %assign push_num 2 | ||
| 1205 | LOAD_3_PARA | ||
| 1206 | %ifndef X86_32 | ||
| 1207 | movsx r2, r2d | ||
| 1208 | %endif | ||
| 1209 | sub r1, r2 | ||
| 1210 | movdqa xmm0, [r1] ; read one row | ||
| 1211 | pxor xmm1, xmm1 | ||
| 1212 | psadbw xmm0, xmm1 | ||
| 1213 | movdqa xmm1, xmm0 | ||
| 1214 | psrldq xmm1, 0x08 | ||
| 1215 | pslldq xmm0, 0x08 | ||
| 1216 | psrldq xmm0, 0x08 | ||
| 1217 | paddw xmm0, xmm1 | ||
| 1218 | |||
| 1219 | movzx r3, byte [r1+r2-0x01] | ||
| 1220 | movzx r4, byte [r1+2*r2-0x01] | ||
| 1221 | add r3, r4 | ||
| 1222 | lea r1, [r1+r2] | ||
| 1223 | LOAD_2_LEFT_AND_ADD | ||
| 1224 | LOAD_2_LEFT_AND_ADD | ||
| 1225 | LOAD_2_LEFT_AND_ADD | ||
| 1226 | LOAD_2_LEFT_AND_ADD | ||
| 1227 | LOAD_2_LEFT_AND_ADD | ||
| 1228 | LOAD_2_LEFT_AND_ADD | ||
| 1229 | LOAD_2_LEFT_AND_ADD | ||
| 1230 | add r3, 0x10 | ||
| 1231 | movd xmm1, r3d | ||
| 1232 | paddw xmm0, xmm1 | ||
| 1233 | psrld xmm0, 0x05 | ||
| 1234 | pmuludq xmm0, [mmx_01bytes] | ||
| 1235 | pshufd xmm0, xmm0, 0 | ||
| 1236 | |||
| 1237 | movdqa [r0], xmm0 | ||
| 1238 | movdqa [r0+0x10], xmm0 | ||
| 1239 | movdqa [r0+0x20], xmm0 | ||
| 1240 | movdqa [r0+0x30], xmm0 | ||
| 1241 | movdqa [r0+0x40], xmm0 | ||
| 1242 | movdqa [r0+0x50], xmm0 | ||
| 1243 | movdqa [r0+0x60], xmm0 | ||
| 1244 | movdqa [r0+0x70], xmm0 | ||
| 1245 | movdqa [r0+0x80], xmm0 | ||
| 1246 | movdqa [r0+0x90], xmm0 | ||
| 1247 | movdqa [r0+0xa0], xmm0 | ||
| 1248 | movdqa [r0+0xb0], xmm0 | ||
| 1249 | movdqa [r0+0xc0], xmm0 | ||
| 1250 | movdqa [r0+0xd0], xmm0 | ||
| 1251 | movdqa [r0+0xe0], xmm0 | ||
| 1252 | movdqa [r0+0xf0], xmm0 | ||
| 1253 | |||
| 1254 | pop r4 | ||
| 1255 | pop r3 | ||
| 1256 | ret | ||
| 1257 | |||
| 1258 | ;*********************************************************************** | ||
| 1259 | ; | ||
| 1260 | ;int32_t WelsSmpleSatdThree4x4_sse2( uint8_t *pDec, int32_t iLineSizeDec, uint8_t *pEnc, int32_t iLinesizeEnc, | ||
| 1261 | ; uint8_t* pRed, int32_t* pBestMode, int32_t, int32_t, int32_t); | ||
| 1262 | ; | ||
| 1263 | ;*********************************************************************** | ||
| 1264 | %ifdef X86_ASM | ||
| 1265 | WELS_EXTERN WelsSmpleSatdThree4x4_sse2 | ||
| 1266 | align 16 | ||
| 1267 | WelsSmpleSatdThree4x4_sse2: | ||
| 1268 | push ebx | ||
| 1269 | push esi | ||
| 1270 | push edi | ||
| 1271 | mov eax, [esp+24];p_enc | ||
| 1272 | mov ebx, [esp+28];linesize_enc | ||
| 1273 | |||
| 1274 | ; load source 4x4 samples and Hadamard transform | ||
| 1275 | movd xmm0, [eax] | ||
| 1276 | movd xmm1, [eax+ebx] | ||
| 1277 | lea eax , [eax+2*ebx] | ||
| 1278 | movd xmm2, [eax] | ||
| 1279 | movd xmm3, [eax+ebx] | ||
| 1280 | punpckldq xmm0, xmm2 | ||
| 1281 | punpckldq xmm1, xmm3 | ||
| 1282 | |||
| 1283 | pxor xmm6, xmm6 | ||
| 1284 | punpcklbw xmm0, xmm6 | ||
| 1285 | punpcklbw xmm1, xmm6 | ||
| 1286 | |||
| 1287 | movdqa xmm2, xmm0 | ||
| 1288 | paddw xmm0, xmm1 | ||
| 1289 | psubw xmm2, xmm1 | ||
| 1290 | SSE2_XSawp qdq, xmm0, xmm2, xmm3 | ||
| 1291 | |||
| 1292 | movdqa xmm4, xmm0 | ||
| 1293 | paddw xmm0, xmm3 | ||
| 1294 | psubw xmm4, xmm3 | ||
| 1295 | |||
| 1296 | movdqa xmm2, xmm0 | ||
| 1297 | punpcklwd xmm0, xmm4 | ||
| 1298 | punpckhwd xmm4, xmm2 | ||
| 1299 | |||
| 1300 | SSE2_XSawp dq, xmm0, xmm4, xmm3 | ||
| 1301 | SSE2_XSawp qdq, xmm0, xmm3, xmm5 | ||
| 1302 | |||
| 1303 | movdqa xmm7, xmm0 | ||
| 1304 | paddw xmm0, xmm5 | ||
| 1305 | psubw xmm7, xmm5 | ||
| 1306 | |||
| 1307 | SSE2_XSawp qdq, xmm0, xmm7, xmm1 | ||
| 1308 | |||
| 1309 | ; Hadamard transform results are saved in xmm0 and xmm2 | ||
| 1310 | movdqa xmm2, xmm0 | ||
| 1311 | paddw xmm0, xmm1 | ||
| 1312 | psubw xmm2, xmm1 | ||
| 1313 | |||
| 1314 | ; load top boundary samples: [a b c d] | ||
| 1315 | mov eax, [esp+16];p_dec | ||
| 1316 | sub eax, [esp+20];linesize_dec | ||
| 1317 | movzx ecx, byte [eax] | ||
| 1318 | movzx edx, byte [eax+1] | ||
| 1319 | movzx esi, byte [eax+2] | ||
| 1320 | movzx edi, byte [eax+3] | ||
| 1321 | |||
| 1322 | ; get the transform results of top boundary samples: [a b c d] | ||
| 1323 | add edx, ecx ; edx = a + b | ||
| 1324 | add edi, esi ; edi = c + d | ||
| 1325 | add ecx, ecx ; ecx = a + a | ||
| 1326 | add esi, esi ; esi = c + c | ||
| 1327 | sub ecx, edx ; ecx = a + a - a - b = a - b | ||
| 1328 | sub esi, edi ; esi = c + c - c - d = c - d | ||
| 1329 | add edi, edx ; edi = (a + b) + (c + d) | ||
| 1330 | add edx, edx | ||
| 1331 | sub edx, edi ; edx = (a + b) - (c + d) | ||
| 1332 | add esi, ecx ; esi = (a - b) + (c - d) | ||
| 1333 | add ecx, ecx | ||
| 1334 | sub ecx, esi ; ecx = (a - b) - (c - d) ; [edi edx ecx esi] | ||
| 1335 | |||
| 1336 | movdqa xmm6, xmm0 | ||
| 1337 | movdqa xmm7, xmm2 | ||
| 1338 | movd xmm5, edi ; store the edi for DC mode | ||
| 1339 | pxor xmm3, xmm3 | ||
| 1340 | pxor xmm4, xmm4 | ||
| 1341 | pinsrw xmm3, edi, 0 | ||
| 1342 | pinsrw xmm3, esi, 4 | ||
| 1343 | psllw xmm3, 2 | ||
| 1344 | pinsrw xmm4, edx, 0 | ||
| 1345 | pinsrw xmm4, ecx, 4 | ||
| 1346 | psllw xmm4, 2 | ||
| 1347 | |||
| 1348 | ; get the satd of H | ||
| 1349 | psubw xmm0, xmm3 | ||
| 1350 | psubw xmm2, xmm4 | ||
| 1351 | |||
| 1352 | WELS_AbsW xmm0, xmm1 | ||
| 1353 | WELS_AbsW xmm2, xmm1 | ||
| 1354 | paddusw xmm0, xmm2 | ||
| 1355 | SUMW_HORIZON1 xmm0, xmm1 ; satd of V is stored in xmm0 | ||
| 1356 | |||
| 1357 | ; load left boundary samples: [a b c d]' | ||
| 1358 | mov eax, [esp+16] | ||
| 1359 | mov ebx, [esp+20] | ||
| 1360 | movzx ecx, byte [eax-1] | ||
| 1361 | movzx edx, byte [eax+ebx-1] | ||
| 1362 | lea eax , [eax+2*ebx] | ||
| 1363 | movzx esi, byte [eax-1] | ||
| 1364 | movzx edi, byte [eax+ebx-1] | ||
| 1365 | |||
| 1366 | ; get the transform results of left boundary samples: [a b c d]' | ||
| 1367 | add edx, ecx ; edx = a + b | ||
| 1368 | add edi, esi ; edi = c + d | ||
| 1369 | add ecx, ecx ; ecx = a + a | ||
| 1370 | add esi, esi ; esi = c + c | ||
| 1371 | sub ecx, edx ; ecx = a + a - a - b = a - b | ||
| 1372 | sub esi, edi ; esi = c + c - c - d = c - d | ||
| 1373 | add edi, edx ; edi = (a + b) + (c + d) | ||
| 1374 | add edx, edx | ||
| 1375 | sub edx, edi ; edx = (a + b) - (c + d) | ||
| 1376 | add esi, ecx ; esi = (a - b) + (c - d) | ||
| 1377 | add ecx, ecx | ||
| 1378 | sub ecx, esi ; ecx = (a - b) - (c - d) ; [edi edx ecx esi]' | ||
| 1379 | |||
| 1380 | ; store the transform results in xmm3 | ||
| 1381 | movd xmm3, edi | ||
| 1382 | pinsrw xmm3, edx, 1 | ||
| 1383 | pinsrw xmm3, ecx, 2 | ||
| 1384 | pinsrw xmm3, esi, 3 | ||
| 1385 | psllw xmm3, 2 | ||
| 1386 | |||
| 1387 | ; get the satd of V | ||
| 1388 | movdqa xmm2, xmm6 | ||
| 1389 | movdqa xmm4, xmm7 | ||
| 1390 | psubw xmm2, xmm3 | ||
| 1391 | WELS_AbsW xmm2, xmm1 | ||
| 1392 | WELS_AbsW xmm4, xmm1 | ||
| 1393 | paddusw xmm2, xmm4 | ||
| 1394 | SUMW_HORIZON1 xmm2, xmm1 ; satd of H is stored in xmm2 | ||
| 1395 | |||
| 1396 | ; DC result is stored in xmm1 | ||
| 1397 | add edi, 4 | ||
| 1398 | movd xmm1, edi | ||
| 1399 | paddw xmm1, xmm5 | ||
| 1400 | psrlw xmm1, 3 | ||
| 1401 | movdqa xmm5, xmm1 | ||
| 1402 | psllw xmm1, 4 | ||
| 1403 | |||
| 1404 | ; get the satd of DC | ||
| 1405 | psubw xmm6, xmm1 | ||
| 1406 | WELS_AbsW xmm6, xmm1 | ||
| 1407 | WELS_AbsW xmm7, xmm1 | ||
| 1408 | paddusw xmm6, xmm7 | ||
| 1409 | SUMW_HORIZON1 xmm6, xmm1 ; satd of DC is stored in xmm6 | ||
| 1410 | |||
| 1411 | ; comparing order: DC H V | ||
| 1412 | mov edx, [esp+32] | ||
| 1413 | movd eax, xmm6 | ||
| 1414 | movd edi, xmm2 | ||
| 1415 | movd esi, xmm0 | ||
| 1416 | and eax, 0xffff | ||
| 1417 | shr eax, 1 | ||
| 1418 | and edi, 0xffff | ||
| 1419 | shr edi, 1 | ||
| 1420 | and esi, 0xffff | ||
| 1421 | shr esi, 1 | ||
| 1422 | add eax, [esp+40] | ||
| 1423 | add edi, [esp+44] | ||
| 1424 | add esi, [esp+48] | ||
| 1425 | cmp ax, di | ||
| 1426 | jg near not_dc | ||
| 1427 | cmp ax, si | ||
| 1428 | jg near not_dc_h | ||
| 1429 | |||
| 1430 | ; for DC mode | ||
| 1431 | movd ebx, xmm5 | ||
| 1432 | imul ebx, 0x01010101 | ||
| 1433 | movd xmm5, ebx | ||
| 1434 | pshufd xmm5, xmm5, 0 | ||
| 1435 | movdqa [edx], xmm5 | ||
| 1436 | mov ebx, [esp+36] | ||
| 1437 | mov dword [ebx], 0x02 | ||
| 1438 | pop edi | ||
| 1439 | pop esi | ||
| 1440 | pop ebx | ||
| 1441 | ret | ||
| 1442 | |||
| 1443 | not_dc: | ||
| 1444 | cmp di, si | ||
| 1445 | jg near not_dc_h | ||
| 1446 | |||
| 1447 | ; for H mode | ||
| 1448 | SSE_DB_1_2REG xmm6, xmm7 | ||
| 1449 | mov eax, [esp+16] | ||
| 1450 | mov ebx, [esp+20] | ||
| 1451 | movzx ecx, byte [eax-1] | ||
| 1452 | movd xmm0, ecx | ||
| 1453 | pmuludq xmm0, xmm6 | ||
| 1454 | |||
| 1455 | movzx ecx, byte [eax+ebx-1] | ||
| 1456 | movd xmm1, ecx | ||
| 1457 | pmuludq xmm1, xmm6 | ||
| 1458 | %if 1 | ||
| 1459 | punpckldq xmm0, xmm1 | ||
| 1460 | %else | ||
| 1461 | unpcklps xmm0, xmm1 | ||
| 1462 | %endif | ||
| 1463 | lea eax, [eax+ebx*2] | ||
| 1464 | movzx ecx, byte [eax-1] | ||
| 1465 | movd xmm2, ecx | ||
| 1466 | pmuludq xmm2, xmm6 | ||
| 1467 | |||
| 1468 | movzx ecx, byte [eax+ebx-1] | ||
| 1469 | movd xmm3, ecx | ||
| 1470 | pmuludq xmm3, xmm6 | ||
| 1471 | %if 1 | ||
| 1472 | punpckldq xmm2, xmm3 | ||
| 1473 | punpcklqdq xmm0, xmm2 | ||
| 1474 | %else | ||
| 1475 | unpcklps xmm2, xmm3 | ||
| 1476 | unpcklpd xmm0, xmm2 | ||
| 1477 | %endif | ||
| 1478 | movdqa [edx],xmm0 | ||
| 1479 | |||
| 1480 | mov eax, edi | ||
| 1481 | mov ebx, [esp+36] | ||
| 1482 | mov dword [ebx], 0x01 | ||
| 1483 | |||
| 1484 | pop edi | ||
| 1485 | pop esi | ||
| 1486 | pop ebx | ||
| 1487 | ret | ||
| 1488 | not_dc_h: | ||
| 1489 | ; for V mode | ||
| 1490 | mov eax, [esp+16] | ||
| 1491 | sub eax, [esp+20] | ||
| 1492 | movd xmm0, [eax] | ||
| 1493 | pshufd xmm0, xmm0, 0 | ||
| 1494 | movdqa [edx],xmm0 | ||
| 1495 | |||
| 1496 | mov eax, esi | ||
| 1497 | mov ebx, [esp+36] | ||
| 1498 | mov dword [ebx], 0x00 | ||
| 1499 | |||
| 1500 | pop edi | ||
| 1501 | pop esi | ||
| 1502 | pop ebx | ||
| 1503 | ret | ||
| 1504 | %endif | ||
| 1505 | |||
| @@ -0,0 +1,220 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | ;* sad.asm | ||
| 33 | ;* | ||
| 34 | ;* Abstract | ||
| 35 | ;* WelsSampleSad8x8_sse21 | ||
| 36 | ;* | ||
| 37 | ;* History | ||
| 38 | ;* 8/5/2009 Created | ||
| 39 | ;* | ||
| 40 | ;* | ||
| 41 | ;*************************************************************************/ | ||
| 42 | |||
| 43 | %include "asm_inc.asm" | ||
| 44 | |||
| 45 | ;*********************************************************************** | ||
| 46 | ; Macros and other preprocessor constants | ||
| 47 | ;*********************************************************************** | ||
| 48 | %macro CACHE_SPLIT_CHECK 3 ; address, width, cacheline | ||
| 49 | and %1, 0x1f|(%3>>1) | ||
| 50 | cmp %1, (32-%2)|(%3>>1) | ||
| 51 | %endmacro | ||
| 52 | |||
| 53 | %macro SSE2_GetSad8x4 0 | ||
| 54 | movq xmm0, [r0] | ||
| 55 | movq xmm1, [r0+r1] | ||
| 56 | lea r0, [r0+2*r1] | ||
| 57 | movhps xmm0, [r0] | ||
| 58 | movhps xmm1, [r0+r1] | ||
| 59 | |||
| 60 | movq xmm2, [r2] | ||
| 61 | movq xmm3, [r2+r3] | ||
| 62 | lea r2, [r2+2*r3] | ||
| 63 | movhps xmm2, [r2] | ||
| 64 | movhps xmm3, [r2+r3] | ||
| 65 | psadbw xmm0, xmm2 | ||
| 66 | psadbw xmm1, xmm3 | ||
| 67 | paddw xmm6, xmm0 | ||
| 68 | paddw xmm6, xmm1 | ||
| 69 | %endmacro | ||
| 70 | |||
| 71 | |||
| 72 | ;*********************************************************************** | ||
| 73 | ; Code | ||
| 74 | ;*********************************************************************** | ||
| 75 | SECTION .text | ||
| 76 | |||
| 77 | WELS_EXTERN WelsSampleSad8x8_sse21 | ||
| 78 | WelsSampleSad8x8_sse21: | ||
| 79 | ;mov ecx, [esp+12] | ||
| 80 | ;mov edx, ecx | ||
| 81 | ;CACHE_SPLIT_CHECK edx, 8, 64 | ||
| 82 | ;jle near .pixel_sad_8x8_nsplit | ||
| 83 | ;push ebx | ||
| 84 | ;push edi | ||
| 85 | ;mov eax, [esp+12] | ||
| 86 | ;mov ebx, [esp+16] | ||
| 87 | |||
| 88 | %assign push_num 0 | ||
| 89 | mov r2, arg3 | ||
| 90 | push r2 | ||
| 91 | CACHE_SPLIT_CHECK r2, 8, 64 | ||
| 92 | jle near .pixel_sad_8x8_nsplit | ||
| 93 | pop r2 | ||
| 94 | %ifdef X86_32 | ||
| 95 | push r3 | ||
| 96 | push r4 | ||
| 97 | push r5 | ||
| 98 | %endif | ||
| 99 | %assign push_num 3 | ||
| 100 | mov r0, arg1 | ||
| 101 | mov r1, arg2 | ||
| 102 | SIGN_EXTENTION r1, r1d | ||
| 103 | pxor xmm7, xmm7 | ||
| 104 | |||
| 105 | ;ecx r2, edx r4, edi r5 | ||
| 106 | |||
| 107 | mov r5, r2 | ||
| 108 | and r5, 0x07 | ||
| 109 | sub r2, r5 | ||
| 110 | mov r4, 8 | ||
| 111 | sub r4, r5 | ||
| 112 | |||
| 113 | shl r5, 3 | ||
| 114 | shl r4, 3 | ||
| 115 | movd xmm5, r5d | ||
| 116 | movd xmm6, r4d | ||
| 117 | mov r5, 8 | ||
| 118 | add r5, r2 | ||
| 119 | mov r3, arg4 | ||
| 120 | SIGN_EXTENTION r3, r3d | ||
| 121 | movq xmm0, [r0] | ||
| 122 | movhps xmm0, [r0+r1] | ||
| 123 | |||
| 124 | movq xmm1, [r2] | ||
| 125 | movq xmm2, [r5] | ||
| 126 | movhps xmm1, [r2+r3] | ||
| 127 | movhps xmm2, [r5+r3] | ||
| 128 | psrlq xmm1, xmm5 | ||
| 129 | psllq xmm2, xmm6 | ||
| 130 | por xmm1, xmm2 | ||
| 131 | |||
| 132 | psadbw xmm0, xmm1 | ||
| 133 | paddw xmm7, xmm0 | ||
| 134 | |||
| 135 | lea r0, [r0+2*r1] | ||
| 136 | lea r2, [r2+2*r3] | ||
| 137 | lea r5, [r5+2*r3] | ||
| 138 | |||
| 139 | movq xmm0, [r0] | ||
| 140 | movhps xmm0, [r0+r1] | ||
| 141 | |||
| 142 | movq xmm1, [r2] | ||
| 143 | movq xmm2, [r5] | ||
| 144 | movhps xmm1, [r2+r3] | ||
| 145 | movhps xmm2, [r5+r3] | ||
| 146 | psrlq xmm1, xmm5 | ||
| 147 | psllq xmm2, xmm6 | ||
| 148 | por xmm1, xmm2 | ||
| 149 | |||
| 150 | psadbw xmm0, xmm1 | ||
| 151 | paddw xmm7, xmm0 | ||
| 152 | |||
| 153 | lea r0, [r0+2*r1] | ||
| 154 | lea r2, [r2+2*r3] | ||
| 155 | lea r5, [r5+2*r3] | ||
| 156 | |||
| 157 | movq xmm0, [r0] | ||
| 158 | movhps xmm0, [r0+r1] | ||
| 159 | |||
| 160 | movq xmm1, [r2] | ||
| 161 | movq xmm2, [r5] | ||
| 162 | movhps xmm1, [r2+r3] | ||
| 163 | movhps xmm2, [r5+r3] | ||
| 164 | psrlq xmm1, xmm5 | ||
| 165 | psllq xmm2, xmm6 | ||
| 166 | por xmm1, xmm2 | ||
| 167 | |||
| 168 | psadbw xmm0, xmm1 | ||
| 169 | paddw xmm7, xmm0 | ||
| 170 | |||
| 171 | lea r0, [r0+2*r1] | ||
| 172 | lea r2, [r2+2*r3] | ||
| 173 | lea r5, [r5+2*r3] | ||
| 174 | |||
| 175 | movq xmm0, [r0] | ||
| 176 | movhps xmm0, [r0+r1] | ||
| 177 | |||
| 178 | movq xmm1, [r2] | ||
| 179 | movq xmm2, [r5] | ||
| 180 | movhps xmm1, [r2+r3] | ||
| 181 | movhps xmm2, [r5+r3] | ||
| 182 | psrlq xmm1, xmm5 | ||
| 183 | psllq xmm2, xmm6 | ||
| 184 | por xmm1, xmm2 | ||
| 185 | |||
| 186 | psadbw xmm0, xmm1 | ||
| 187 | paddw xmm7, xmm0 | ||
| 188 | |||
| 189 | movhlps xmm0, xmm7 | ||
| 190 | paddw xmm0, xmm7 | ||
| 191 | movd retrd, xmm0 | ||
| 192 | %ifdef X86_32 | ||
| 193 | pop r5 | ||
| 194 | pop r4 | ||
| 195 | pop r3 | ||
| 196 | %endif | ||
| 197 | jmp .return | ||
| 198 | |||
| 199 | .pixel_sad_8x8_nsplit: | ||
| 200 | ;push ebx | ||
| 201 | ;mov eax, [esp+8] | ||
| 202 | ;mov ebx, [esp+12] | ||
| 203 | ;mov edx, [esp+20] | ||
| 204 | |||
| 205 | pop r2 | ||
| 206 | %assign push_num 0 | ||
| 207 | LOAD_4_PARA | ||
| 208 | SIGN_EXTENTION r1, r1d | ||
| 209 | SIGN_EXTENTION r3, r3d | ||
| 210 | pxor xmm6, xmm6 | ||
| 211 | SSE2_GetSad8x4 | ||
| 212 | lea r0, [r0+2*r1] | ||
| 213 | lea r2, [r2+2*r3] | ||
| 214 | SSE2_GetSad8x4 | ||
| 215 | movhlps xmm0, xmm6 | ||
| 216 | paddw xmm0, xmm6 | ||
| 217 | movd retrd, xmm0 | ||
| 218 | LOAD_4_PARA_POP | ||
| 219 | .return: | ||
| 220 | ret | ||
| @@ -0,0 +1,1414 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2010-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | ;* vaa.asm | ||
| 33 | ;* | ||
| 34 | ;* Abstract | ||
| 35 | ;* sse2 for pVaa routines | ||
| 36 | ;* | ||
| 37 | ;* History | ||
| 38 | ;* 04/14/2010 Created | ||
| 39 | ;* | ||
| 40 | ;*************************************************************************/ | ||
| 41 | %include "asm_inc.asm" | ||
| 42 | %ifdef X86_32 | ||
| 43 | ;*********************************************************************** | ||
| 44 | ; Macros and other preprocessor constants | ||
| 45 | ;*********************************************************************** | ||
| 46 | |||
| 47 | ;%macro SUM_SSE2 4 ; dst, pSrc, zero, pack1_8x2 | ||
| 48 | ; movdqa %1, %2 | ||
| 49 | ; punpcklbw %1, %3 | ||
| 50 | ; punpckhbw %2, %3 | ||
| 51 | ; paddw %1, %2 | ||
| 52 | ; pmaddwd %1, %4 | ||
| 53 | ; pshufd %2, %1, 04Eh ; 01001110 B | ||
| 54 | ; paddd %1, %2 | ||
| 55 | ; pshufd %2, %1, 0B1h ; 10110001 B | ||
| 56 | ; paddd %1, %2 | ||
| 57 | ;%endmacro ; END OF SUM_SSE2 | ||
| 58 | |||
| 59 | ; by comparing it outperforms than phaddw(SSSE3) sets | ||
| 60 | %macro SUM_WORD_8x2_SSE2 2 ; dst(pSrc), tmp | ||
| 61 | ; @sum_8x2 begin | ||
| 62 | pshufd %2, %1, 04Eh ; 01001110 B | ||
| 63 | paddw %1, %2 | ||
| 64 | pshuflw %2, %1, 04Eh ; 01001110 B | ||
| 65 | paddw %1, %2 | ||
| 66 | pshuflw %2, %1, 0B1h ; 10110001 B | ||
| 67 | paddw %1, %2 | ||
| 68 | ; end of @sum_8x2 | ||
| 69 | %endmacro ; END of SUM_WORD_8x2_SSE2 | ||
| 70 | |||
| 71 | %macro SUM_SQR_SSE2 3 ; dst, pSrc, zero | ||
| 72 | movdqa %1, %2 | ||
| 73 | punpcklbw %1, %3 | ||
| 74 | punpckhbw %2, %3 | ||
| 75 | pmaddwd %1, %1 | ||
| 76 | pmaddwd %2, %2 | ||
| 77 | paddd %1, %2 | ||
| 78 | pshufd %2, %1, 04Eh ; 01001110 B | ||
| 79 | paddd %1, %2 | ||
| 80 | pshufd %2, %1, 0B1h ; 10110001 B | ||
| 81 | paddd %1, %2 | ||
| 82 | %endmacro ; END OF SUM_SQR_SSE2 | ||
| 83 | |||
| 84 | %macro VAA_AVG_BLOCK_SSE2 6 ; dst, t0, t1, t2, t3, t4 | ||
| 85 | movdqa %1, [esi ] ; line 0 | ||
| 86 | movdqa %2, [esi+ecx] ; line 1 | ||
| 87 | movdqa %3, %1 | ||
| 88 | punpcklbw %1, xmm7 | ||
| 89 | punpckhbw %3, xmm7 | ||
| 90 | movdqa %4, %2 | ||
| 91 | punpcklbw %4, xmm7 | ||
| 92 | punpckhbw %2, xmm7 | ||
| 93 | paddw %1, %4 | ||
| 94 | paddw %2, %3 | ||
| 95 | movdqa %3, [esi+ebx] ; line 2 | ||
| 96 | movdqa %4, [esi+edx] ; line 3 | ||
| 97 | movdqa %5, %3 | ||
| 98 | punpcklbw %3, xmm7 | ||
| 99 | punpckhbw %5, xmm7 | ||
| 100 | movdqa %6, %4 | ||
| 101 | punpcklbw %6, xmm7 | ||
| 102 | punpckhbw %4, xmm7 | ||
| 103 | paddw %3, %6 | ||
| 104 | paddw %4, %5 | ||
| 105 | paddw %1, %3 ; block 0, 1 | ||
| 106 | paddw %2, %4 ; block 2, 3 | ||
| 107 | pshufd %3, %1, 0B1h | ||
| 108 | pshufd %4, %2, 0B1h | ||
| 109 | paddw %1, %3 | ||
| 110 | paddw %2, %4 | ||
| 111 | movdqa %3, %1 | ||
| 112 | movdqa %4, %2 | ||
| 113 | pshuflw %5, %1, 0B1h | ||
| 114 | pshufhw %6, %3, 0B1h | ||
| 115 | paddw %1, %5 | ||
| 116 | paddw %3, %6 | ||
| 117 | pshuflw %5, %2, 0B1h | ||
| 118 | pshufhw %6, %4, 0B1h | ||
| 119 | paddw %2, %5 | ||
| 120 | paddw %4, %6 | ||
| 121 | punpcklwd %1, %2 | ||
| 122 | punpckhwd %3, %4 | ||
| 123 | punpcklwd %1, %3 | ||
| 124 | psraw %1, $4 | ||
| 125 | %endmacro | ||
| 126 | |||
| 127 | %macro VAA_AVG_BLOCK_SSSE3 6 ; dst, t0, t1, t2, t3, t4 | ||
| 128 | movdqa %1, [esi ] ; line 0 | ||
| 129 | movdqa %2, [esi+ecx] ; line 1 | ||
| 130 | movdqa %3, %1 | ||
| 131 | punpcklbw %1, xmm7 | ||
| 132 | punpckhbw %3, xmm7 | ||
| 133 | movdqa %4, %2 | ||
| 134 | punpcklbw %4, xmm7 | ||
| 135 | punpckhbw %2, xmm7 | ||
| 136 | paddw %1, %4 | ||
| 137 | paddw %2, %3 | ||
| 138 | movdqa %3, [esi+ebx] ; line 2 | ||
| 139 | movdqa %4, [esi+edx] ; line 3 | ||
| 140 | movdqa %5, %3 | ||
| 141 | punpcklbw %3, xmm7 | ||
| 142 | punpckhbw %5, xmm7 | ||
| 143 | movdqa %6, %4 | ||
| 144 | punpcklbw %6, xmm7 | ||
| 145 | punpckhbw %4, xmm7 | ||
| 146 | paddw %3, %6 | ||
| 147 | paddw %4, %5 | ||
| 148 | paddw %1, %3 ; block 0, 1 | ||
| 149 | paddw %2, %4 ; block 2, 3 | ||
| 150 | phaddw %1, %2 ; block[0]: 0-15, 16-31; block[1]: 32-47, 48-63; .. | ||
| 151 | phaddw %1, xmm7 ; block[0]: 0-15; block[1]: 16-31; block[2]: 32-47; block[3]: 48-63; .... | ||
| 152 | psraw %1, $4 | ||
| 153 | %endmacro | ||
| 154 | |||
| 155 | %macro WELS_SAD_16x2_SSE2 0 | ||
| 156 | movdqa xmm1, [esi] | ||
| 157 | movdqa xmm2, [edi] | ||
| 158 | movdqa xmm3, [esi+ebx] | ||
| 159 | movdqa xmm4, [edi+ebx] | ||
| 160 | psadbw xmm1, xmm2 | ||
| 161 | psadbw xmm3, xmm4 | ||
| 162 | paddd xmm6, xmm1 | ||
| 163 | paddd xmm6, xmm3 | ||
| 164 | lea esi, [esi+ebx*2] | ||
| 165 | lea edi, [edi+ebx*2] | ||
| 166 | %endmacro | ||
| 167 | |||
| 168 | %macro WELS_SAD_SUM_SQSUM_16x1_SSE2 0 | ||
| 169 | movdqa xmm1, [esi] | ||
| 170 | movdqa xmm2, [edi] | ||
| 171 | movdqa xmm3, xmm1 | ||
| 172 | psadbw xmm3, xmm2 | ||
| 173 | paddd xmm6, xmm3 | ||
| 174 | |||
| 175 | movdqa xmm3, xmm1 | ||
| 176 | psadbw xmm3, xmm0 | ||
| 177 | paddd xmm5, xmm3 | ||
| 178 | |||
| 179 | movdqa xmm2, xmm1 | ||
| 180 | punpcklbw xmm1, xmm0 | ||
| 181 | punpckhbw xmm2, xmm0 | ||
| 182 | pmaddwd xmm1, xmm1 | ||
| 183 | pmaddwd xmm2, xmm2 | ||
| 184 | paddd xmm4, xmm1 | ||
| 185 | paddd xmm4, xmm2 | ||
| 186 | |||
| 187 | add esi, ebx | ||
| 188 | add edi, ebx | ||
| 189 | %endmacro | ||
| 190 | |||
| 191 | %macro WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 0 | ||
| 192 | movdqa xmm1, [esi] | ||
| 193 | movdqa xmm2, [edi] | ||
| 194 | movdqa xmm3, xmm1 | ||
| 195 | psadbw xmm3, xmm2 | ||
| 196 | paddd xmm7, xmm3 ; sad | ||
| 197 | |||
| 198 | movdqa xmm3, xmm1 | ||
| 199 | pmaxub xmm3, xmm2 | ||
| 200 | pminub xmm2, xmm1 | ||
| 201 | psubb xmm3, xmm2 ; diff | ||
| 202 | |||
| 203 | movdqa xmm2, xmm1 | ||
| 204 | psadbw xmm2, xmm0 | ||
| 205 | paddd xmm6, xmm2 ; sum | ||
| 206 | |||
| 207 | movdqa xmm2, xmm1 | ||
| 208 | punpcklbw xmm1, xmm0 | ||
| 209 | punpckhbw xmm2, xmm0 | ||
| 210 | pmaddwd xmm1, xmm1 | ||
| 211 | pmaddwd xmm2, xmm2 | ||
| 212 | paddd xmm5, xmm1 | ||
| 213 | paddd xmm5, xmm2 ; sqsum | ||
| 214 | |||
| 215 | movdqa xmm1, xmm3 | ||
| 216 | punpcklbw xmm1, xmm0 | ||
| 217 | punpckhbw xmm3, xmm0 | ||
| 218 | pmaddwd xmm1, xmm1 | ||
| 219 | pmaddwd xmm3, xmm3 | ||
| 220 | paddd xmm4, xmm1 | ||
| 221 | paddd xmm4, xmm3 ; sqdiff | ||
| 222 | |||
| 223 | add esi, ebx | ||
| 224 | add edi, ebx | ||
| 225 | %endmacro | ||
| 226 | |||
| 227 | %macro WELS_SAD_SD_MAD_16x1_SSE2 4 | ||
| 228 | %define sad_reg %1 | ||
| 229 | %define sum_cur_reg %2 | ||
| 230 | %define sum_ref_reg %3 | ||
| 231 | %define mad_reg %4 | ||
| 232 | movdqa xmm1, [esi] | ||
| 233 | movdqa xmm2, [edi] | ||
| 234 | movdqa xmm3, xmm1 | ||
| 235 | psadbw xmm3, xmm0 | ||
| 236 | paddd sum_cur_reg, xmm3 ; sum_cur | ||
| 237 | movdqa xmm3, xmm2 | ||
| 238 | psadbw xmm3, xmm0 | ||
| 239 | paddd sum_ref_reg, xmm3 ; sum_ref | ||
| 240 | |||
| 241 | movdqa xmm3, xmm1 | ||
| 242 | pmaxub xmm3, xmm2 | ||
| 243 | pminub xmm2, xmm1 | ||
| 244 | psubb xmm3, xmm2 ; abs diff | ||
| 245 | pmaxub mad_reg, xmm3 ; max abs diff | ||
| 246 | |||
| 247 | psadbw xmm3, xmm0 | ||
| 248 | paddd sad_reg, xmm3 ; sad | ||
| 249 | |||
| 250 | add esi, ebx | ||
| 251 | add edi, ebx | ||
| 252 | %endmacro | ||
| 253 | |||
| 254 | |||
| 255 | %macro WELS_MAX_REG_SSE2 1 ; xmm1, xmm2, xmm3 can be used | ||
| 256 | %define max_reg %1 | ||
| 257 | movdqa xmm1, max_reg | ||
| 258 | psrldq xmm1, 4 | ||
| 259 | pmaxub max_reg, xmm1 | ||
| 260 | movdqa xmm1, max_reg | ||
| 261 | psrldq xmm1, 2 | ||
| 262 | pmaxub max_reg, xmm1 | ||
| 263 | movdqa xmm1, max_reg | ||
| 264 | psrldq xmm1, 1 | ||
| 265 | pmaxub max_reg, xmm1 | ||
| 266 | %endmacro | ||
| 267 | |||
| 268 | %macro WELS_SAD_BGD_SQDIFF_16x1_SSE2 4 | ||
| 269 | %define sad_reg %1 | ||
| 270 | %define sum_reg %2 | ||
| 271 | %define mad_reg %3 | ||
| 272 | %define sqdiff_reg %4 | ||
| 273 | movdqa xmm1, [esi] | ||
| 274 | movdqa xmm2, xmm1 | ||
| 275 | movdqa xmm3, xmm1 | ||
| 276 | punpcklbw xmm2, xmm0 | ||
| 277 | punpckhbw xmm3, xmm0 | ||
| 278 | pmaddwd xmm2, xmm2 | ||
| 279 | pmaddwd xmm3, xmm3 | ||
| 280 | paddd xmm2, xmm3 | ||
| 281 | movdqa xmm3, xmm2 | ||
| 282 | psllq xmm2, 32 | ||
| 283 | psrlq xmm3, 32 | ||
| 284 | psllq xmm3, 32 | ||
| 285 | paddd xmm2, xmm3 | ||
| 286 | paddd sad_reg, xmm2 ; sqsum | ||
| 287 | |||
| 288 | movdqa xmm2, [edi] | ||
| 289 | movdqa xmm3, xmm1 | ||
| 290 | psadbw xmm3, xmm0 | ||
| 291 | paddd sum_reg, xmm3 ; sum_cur | ||
| 292 | movdqa xmm3, xmm2 | ||
| 293 | psadbw xmm3, xmm0 | ||
| 294 | pslldq xmm3, 4 | ||
| 295 | paddd sum_reg, xmm3 ; sum_ref | ||
| 296 | |||
| 297 | movdqa xmm3, xmm1 | ||
| 298 | pmaxub xmm3, xmm2 | ||
| 299 | pminub xmm2, xmm1 | ||
| 300 | psubb xmm3, xmm2 ; abs diff | ||
| 301 | pmaxub mad_reg, xmm3 ; max abs diff | ||
| 302 | |||
| 303 | movdqa xmm1, xmm3 | ||
| 304 | psadbw xmm3, xmm0 | ||
| 305 | paddd sad_reg, xmm3 ; sad | ||
| 306 | |||
| 307 | movdqa xmm3, xmm1 | ||
| 308 | punpcklbw xmm1, xmm0 | ||
| 309 | punpckhbw xmm3, xmm0 | ||
| 310 | pmaddwd xmm1, xmm1 | ||
| 311 | pmaddwd xmm3, xmm3 | ||
| 312 | paddd sqdiff_reg, xmm1 | ||
| 313 | paddd sqdiff_reg, xmm3 ; sqdiff | ||
| 314 | |||
| 315 | add esi, ebx | ||
| 316 | add edi, ebx | ||
| 317 | %endmacro | ||
| 318 | |||
| 319 | |||
| 320 | ;*********************************************************************** | ||
| 321 | ; Local Data (Read Only) | ||
| 322 | ;*********************************************************************** | ||
| 323 | |||
| 324 | ;SECTION .rodata align=16 | ||
| 325 | |||
| 326 | ;ALIGN 16 | ||
| 327 | ;pack1_8x2: | ||
| 328 | ; dw 1, 1, 1, 1, 1, 1, 1, 1 | ||
| 329 | |||
| 330 | ;*********************************************************************** | ||
| 331 | ; Code | ||
| 332 | ;*********************************************************************** | ||
| 333 | |||
| 334 | SECTION .text | ||
| 335 | |||
| 336 | WELS_EXTERN rc_sad_frame_sse2 | ||
| 337 | ;*********************************************************************** | ||
| 338 | ; uint32_t rc_sad_frame_sse2( uint8_t *ref_orig, uint8_t *cur_orig, const int mb_width, const int iPicHeight, const int iPicStride ); | ||
| 339 | ;*********************************************************************** | ||
| 340 | ALIGN 16 | ||
| 341 | rc_sad_frame_sse2: | ||
| 342 | push esi | ||
| 343 | push edi | ||
| 344 | push ebp | ||
| 345 | push ebx | ||
| 346 | push edx | ||
| 347 | |||
| 348 | mov esi, [esp+24] | ||
| 349 | mov edi, [esp+28] | ||
| 350 | mov ebx, [esp+32] | ||
| 351 | mov ecx, [esp+36] | ||
| 352 | mov edx, [esp+40] | ||
| 353 | pxor xmm0, xmm0 | ||
| 354 | .hloop: | ||
| 355 | mov eax, ebx | ||
| 356 | mov ebp, $0 | ||
| 357 | .wloop: | ||
| 358 | movdqa xmm1, [esi+ebp] | ||
| 359 | movdqa xmm2, [edi+ebp] | ||
| 360 | psadbw xmm1, xmm2 | ||
| 361 | pshufd xmm2, xmm1, 0f6h ; 11110110 B ; movhlps for float | ||
| 362 | paddd xmm1, xmm2 | ||
| 363 | paddd xmm0, xmm1 | ||
| 364 | add ebp, 010h | ||
| 365 | dec eax | ||
| 366 | jnz near .wloop | ||
| 367 | lea esi, [esi+edx] | ||
| 368 | lea edi, [edi+edx] | ||
| 369 | dec ecx | ||
| 370 | jnz near .hloop | ||
| 371 | |||
| 372 | movd eax, xmm0 | ||
| 373 | pop edx | ||
| 374 | pop ebx | ||
| 375 | pop ebp | ||
| 376 | pop edi | ||
| 377 | pop esi | ||
| 378 | ret | ||
| 379 | |||
| 380 | |||
| 381 | WELS_EXTERN SampleVariance16x16_sse2 | ||
| 382 | ;*********************************************************************** | ||
| 383 | ; void SampleVariance16x16_sse2( uint8_t * y_ref, int32_t y_ref_stride, uint8_t * y_src, int32_t y_src_stride,SMotionTextureUnit* pMotionTexture ); | ||
| 384 | ;*********************************************************************** | ||
| 385 | ALIGN 16 | ||
| 386 | SampleVariance16x16_sse2: | ||
| 387 | push esi | ||
| 388 | push edi | ||
| 389 | push ebx | ||
| 390 | |||
| 391 | sub esp, 16 | ||
| 392 | %define SUM [esp] | ||
| 393 | %define SUM_CUR [esp+4] | ||
| 394 | %define SQR [esp+8] | ||
| 395 | %define SQR_CUR [esp+12] | ||
| 396 | %define PUSH_SIZE 28 ; 12 + 16 | ||
| 397 | |||
| 398 | mov edi, [esp+PUSH_SIZE+4] ; y_ref | ||
| 399 | mov edx, [esp+PUSH_SIZE+8] ; y_ref_stride | ||
| 400 | mov esi, [esp+PUSH_SIZE+12] ; y_src | ||
| 401 | mov eax, [esp+PUSH_SIZE+16] ; y_src_stride | ||
| 402 | mov ecx, 010h ; height = 16 | ||
| 403 | |||
| 404 | pxor xmm7, xmm7 | ||
| 405 | movdqu SUM, xmm7 | ||
| 406 | |||
| 407 | .hloops: | ||
| 408 | movdqa xmm0, [edi] ; y_ref | ||
| 409 | movdqa xmm1, [esi] ; y_src | ||
| 410 | movdqa xmm2, xmm0 ; store first for future process | ||
| 411 | movdqa xmm3, xmm1 | ||
| 412 | ; sum += diff; | ||
| 413 | movdqa xmm4, xmm0 | ||
| 414 | psadbw xmm4, xmm1 ; 2 parts, [0,..,15], [64,..,79] | ||
| 415 | ; to be continued for sum | ||
| 416 | pshufd xmm5, xmm4, 0C6h ; 11000110 B | ||
| 417 | paddw xmm4, xmm5 | ||
| 418 | movd ebx, xmm4 | ||
| 419 | add SUM, ebx | ||
| 420 | |||
| 421 | ; sqr += diff * diff; | ||
| 422 | pmaxub xmm0, xmm1 | ||
| 423 | pminub xmm1, xmm2 | ||
| 424 | psubb xmm0, xmm1 ; diff | ||
| 425 | SUM_SQR_SSE2 xmm1, xmm0, xmm7 ; dst, pSrc, zero | ||
| 426 | movd ebx, xmm1 | ||
| 427 | add SQR, ebx | ||
| 428 | |||
| 429 | ; sum_cur += y_src[x]; | ||
| 430 | movdqa xmm0, xmm3 ; cur_orig | ||
| 431 | movdqa xmm1, xmm0 | ||
| 432 | punpcklbw xmm0, xmm7 | ||
| 433 | punpckhbw xmm1, xmm7 | ||
| 434 | paddw xmm0, xmm1 ; 8x2 | ||
| 435 | SUM_WORD_8x2_SSE2 xmm0, xmm1 | ||
| 436 | movd ebx, xmm0 | ||
| 437 | and ebx, 0ffffh | ||
| 438 | add SUM_CUR, ebx | ||
| 439 | |||
| 440 | ; sqr_cur += y_src[x] * y_src[x]; | ||
| 441 | SUM_SQR_SSE2 xmm0, xmm3, xmm7 ; dst, pSrc, zero | ||
| 442 | movd ebx, xmm0 | ||
| 443 | add SQR_CUR, ebx | ||
| 444 | |||
| 445 | lea edi, [edi+edx] | ||
| 446 | lea esi, [esi+eax] | ||
| 447 | dec ecx | ||
| 448 | jnz near .hloops | ||
| 449 | |||
| 450 | mov ebx, 0 | ||
| 451 | mov bx, word SUM | ||
| 452 | sar ebx, 8 | ||
| 453 | imul ebx, ebx | ||
| 454 | mov ecx, SQR | ||
| 455 | sar ecx, 8 | ||
| 456 | sub ecx, ebx | ||
| 457 | mov edi, [esp+PUSH_SIZE+20] ; pMotionTexture | ||
| 458 | mov [edi], cx ; to store uiMotionIndex | ||
| 459 | mov ebx, 0 | ||
| 460 | mov bx, word SUM_CUR | ||
| 461 | sar ebx, 8 | ||
| 462 | imul ebx, ebx | ||
| 463 | mov ecx, SQR_CUR | ||
| 464 | sar ecx, 8 | ||
| 465 | sub ecx, ebx | ||
| 466 | mov [edi+2], cx ; to store uiTextureIndex | ||
| 467 | |||
| 468 | %undef SUM | ||
| 469 | %undef SUM_CUR | ||
| 470 | %undef SQR | ||
| 471 | %undef SQR_CUR | ||
| 472 | %undef PUSH_SIZE | ||
| 473 | |||
| 474 | add esp, 16 | ||
| 475 | pop ebx | ||
| 476 | pop edi | ||
| 477 | pop esi | ||
| 478 | |||
| 479 | ret | ||
| 480 | |||
| 481 | ; , 6/7/2010 | ||
| 482 | |||
| 483 | |||
| 484 | WELS_EXTERN abs_difference_mbrow_sse2 | ||
| 485 | ;************************************************************************************************************* | ||
| 486 | ;void abs_difference_mbrow_sse2( uint8_t *ref_orig, uint8_t *cur_orig, int32_t iPicStride, | ||
| 487 | ; int32_t gom_pixel_num, int32_t *pSum) | ||
| 488 | ;************************************************************************************************************* | ||
| 489 | ALIGN 16 | ||
| 490 | abs_difference_mbrow_sse2: | ||
| 491 | %define ref_orig esp + pushsize + 4 | ||
| 492 | %define cur_orig esp + pushsize + 8 | ||
| 493 | %define iPicStride esp + pushsize + 12 | ||
| 494 | %define gom_pixel_num esp + pushsize + 16 | ||
| 495 | %define pSum esp + pushsize + 20 | ||
| 496 | %define pushsize 12 | ||
| 497 | push esi | ||
| 498 | push edi | ||
| 499 | push ebx | ||
| 500 | mov esi, [ref_orig] | ||
| 501 | mov edi, [cur_orig] | ||
| 502 | mov ebx, [iPicStride] | ||
| 503 | mov eax, [gom_pixel_num] | ||
| 504 | mov ecx, 16 ;MB_WIDTH_LUMA | ||
| 505 | pxor xmm0, xmm0 | ||
| 506 | mb_width_loop_p: | ||
| 507 | mov edx, esi | ||
| 508 | add edx, eax ; end address | ||
| 509 | gom_row_loop_p: | ||
| 510 | movdqa xmm1, [esi] | ||
| 511 | movdqa xmm2, [edi] | ||
| 512 | psadbw xmm1, xmm2 | ||
| 513 | paddd xmm0, xmm1 | ||
| 514 | add esi, 16 | ||
| 515 | add edi, 16 | ||
| 516 | cmp esi, edx | ||
| 517 | jl gom_row_loop_p | ||
| 518 | |||
| 519 | sub esi, eax | ||
| 520 | sub edi, eax | ||
| 521 | add esi, ebx | ||
| 522 | add edi, ebx | ||
| 523 | loop mb_width_loop_p | ||
| 524 | |||
| 525 | movdqa xmm1, xmm0 | ||
| 526 | psrldq xmm1, 8 | ||
| 527 | paddd xmm1, xmm0 | ||
| 528 | movd eax, xmm1 | ||
| 529 | mov edx, [pSum] ; pSum | ||
| 530 | add [edx], eax | ||
| 531 | |||
| 532 | %undef ref_orig | ||
| 533 | %undef cur_orig | ||
| 534 | %undef iPicStride | ||
| 535 | %undef gom_pixel_num | ||
| 536 | %undef pSum | ||
| 537 | %undef pushsize | ||
| 538 | pop ebx | ||
| 539 | pop edi | ||
| 540 | pop esi | ||
| 541 | ret | ||
| 542 | |||
| 543 | |||
| 544 | |||
| 545 | |||
| 546 | WELS_EXTERN sum_sqrsum_mbrow_sse2 | ||
| 547 | ;************************************************************************************************************* | ||
| 548 | ;void sum_sqrsum_mbrow_sse2( uint8_t *cur_orig, int32_t iPicStride, | ||
| 549 | ; int32_t gom_pixel_num, int32_t *pSum, int32_t *pSqrSum) | ||
| 550 | ;************************************************************************************************************* | ||
| 551 | ALIGN 16 | ||
| 552 | sum_sqrsum_mbrow_sse2: | ||
| 553 | %define cur_orig esp + pushsize + 4 | ||
| 554 | %define iPicStride esp + pushsize + 8 | ||
| 555 | %define gom_pixel_num esp + pushsize + 12 | ||
| 556 | %define pSum esp + pushsize + 16 | ||
| 557 | %define pSqrSum esp + pushsize + 20 | ||
| 558 | %define pushsize 8 | ||
| 559 | push esi | ||
| 560 | push ebx | ||
| 561 | mov esi, [cur_orig] | ||
| 562 | mov eax, [gom_pixel_num] | ||
| 563 | mov ebx, [iPicStride] | ||
| 564 | mov ecx, 16 ;MB_WIDTH_LUMA | ||
| 565 | pxor xmm0, xmm0 ; zero | ||
| 566 | pxor xmm1, xmm1 ; sum | ||
| 567 | pxor xmm2, xmm2 ; sqr sum | ||
| 568 | mb_width_loop_i: | ||
| 569 | mov edx, esi | ||
| 570 | add edx, eax ; end address | ||
| 571 | gom_row_loop_i: | ||
| 572 | movdqa xmm3, [esi] | ||
| 573 | movdqa xmm4, xmm3 | ||
| 574 | psadbw xmm4, xmm0 | ||
| 575 | paddd xmm1, xmm4 | ||
| 576 | movdqa xmm4, xmm3 | ||
| 577 | punpcklbw xmm4, xmm0 | ||
| 578 | punpckhbw xmm3, xmm0 | ||
| 579 | pmaddwd xmm4, xmm4 | ||
| 580 | pmaddwd xmm3, xmm3 | ||
| 581 | paddd xmm2, xmm3 | ||
| 582 | paddd xmm2, xmm4 | ||
| 583 | add esi, 16 | ||
| 584 | cmp esi, edx | ||
| 585 | jl gom_row_loop_i | ||
| 586 | |||
| 587 | sub esi, eax | ||
| 588 | add esi, ebx | ||
| 589 | loop mb_width_loop_i | ||
| 590 | |||
| 591 | movdqa xmm3, xmm1 | ||
| 592 | psrldq xmm3, 8 | ||
| 593 | paddd xmm1, xmm3 | ||
| 594 | movd eax, xmm1 | ||
| 595 | mov edx, [pSum] | ||
| 596 | add [edx], eax | ||
| 597 | |||
| 598 | movdqa xmm3, xmm2 | ||
| 599 | psrldq xmm3, 8 | ||
| 600 | paddd xmm2, xmm3 | ||
| 601 | movdqa xmm3, xmm2 | ||
| 602 | psrldq xmm3, 4 | ||
| 603 | paddd xmm2, xmm3 | ||
| 604 | movd eax, xmm2 | ||
| 605 | mov edx, [pSqrSum] | ||
| 606 | add [edx], eax | ||
| 607 | |||
| 608 | |||
| 609 | %undef cur_orig | ||
| 610 | %undef iPicStride | ||
| 611 | %undef gom_pixel_num | ||
| 612 | %undef pSum | ||
| 613 | %undef pSqrSum | ||
| 614 | %undef pushsize | ||
| 615 | pop ebx | ||
| 616 | pop esi | ||
| 617 | ret | ||
| 618 | |||
| 619 | |||
| 620 | |||
| 621 | WELS_EXTERN VAACalcSad_sse2 | ||
| 622 | ;************************************************************************************************************* | ||
| 623 | ;void VAACalcSad_sse2( uint8_t *cur_data, uint8_t *ref_data, int32_t iPicWidth, int32_t iPicHeight | ||
| 624 | ; int32_t iPicStride, int32_t *psadframe, int32_t *psad8x8) | ||
| 625 | ;************************************************************************************************************* | ||
| 626 | |||
| 627 | |||
| 628 | ALIGN 16 | ||
| 629 | VAACalcSad_sse2: | ||
| 630 | %define cur_data esp + pushsize + 4 | ||
| 631 | %define ref_data esp + pushsize + 8 | ||
| 632 | %define iPicWidth esp + pushsize + 12 | ||
| 633 | %define iPicHeight esp + pushsize + 16 | ||
| 634 | %define iPicStride esp + pushsize + 20 | ||
| 635 | %define psadframe esp + pushsize + 24 | ||
| 636 | %define psad8x8 esp + pushsize + 28 | ||
| 637 | %define pushsize 12 | ||
| 638 | push esi | ||
| 639 | push edi | ||
| 640 | push ebx | ||
| 641 | mov esi, [cur_data] | ||
| 642 | mov edi, [ref_data] | ||
| 643 | mov ebx, [iPicStride] | ||
| 644 | mov edx, [psad8x8] | ||
| 645 | mov eax, ebx | ||
| 646 | |||
| 647 | shr dword [iPicWidth], 4 ; iPicWidth/16 | ||
| 648 | shr dword [iPicHeight], 4 ; iPicHeight/16 | ||
| 649 | shl eax, 4 ; iPicStride*16 | ||
| 650 | pxor xmm0, xmm0 | ||
| 651 | pxor xmm7, xmm7 ; iFrameSad | ||
| 652 | height_loop: | ||
| 653 | mov ecx, dword [iPicWidth] | ||
| 654 | push esi | ||
| 655 | push edi | ||
| 656 | width_loop: | ||
| 657 | pxor xmm6, xmm6 ; | ||
| 658 | WELS_SAD_16x2_SSE2 | ||
| 659 | WELS_SAD_16x2_SSE2 | ||
| 660 | WELS_SAD_16x2_SSE2 | ||
| 661 | WELS_SAD_16x2_SSE2 | ||
| 662 | paddd xmm7, xmm6 | ||
| 663 | movd [edx], xmm6 | ||
| 664 | psrldq xmm6, 8 | ||
| 665 | movd [edx+4], xmm6 | ||
| 666 | |||
| 667 | pxor xmm6, xmm6 | ||
| 668 | WELS_SAD_16x2_SSE2 | ||
| 669 | WELS_SAD_16x2_SSE2 | ||
| 670 | WELS_SAD_16x2_SSE2 | ||
| 671 | WELS_SAD_16x2_SSE2 | ||
| 672 | paddd xmm7, xmm6 | ||
| 673 | movd [edx+8], xmm6 | ||
| 674 | psrldq xmm6, 8 | ||
| 675 | movd [edx+12], xmm6 | ||
| 676 | |||
| 677 | add edx, 16 | ||
| 678 | sub esi, eax | ||
| 679 | sub edi, eax | ||
| 680 | add esi, 16 | ||
| 681 | add edi, 16 | ||
| 682 | |||
| 683 | dec ecx | ||
| 684 | jnz width_loop | ||
| 685 | |||
| 686 | pop edi | ||
| 687 | pop esi | ||
| 688 | add esi, eax | ||
| 689 | add edi, eax | ||
| 690 | |||
| 691 | dec dword [iPicHeight] | ||
| 692 | jnz height_loop | ||
| 693 | |||
| 694 | mov edx, [psadframe] | ||
| 695 | movdqa xmm5, xmm7 | ||
| 696 | psrldq xmm7, 8 | ||
| 697 | paddd xmm7, xmm5 | ||
| 698 | movd [edx], xmm7 | ||
| 699 | |||
| 700 | %undef cur_data | ||
| 701 | %undef ref_data | ||
| 702 | %undef iPicWidth | ||
| 703 | %undef iPicHeight | ||
| 704 | %undef iPicStride | ||
| 705 | %undef psadframe | ||
| 706 | %undef psad8x8 | ||
| 707 | %undef pushsize | ||
| 708 | pop ebx | ||
| 709 | pop edi | ||
| 710 | pop esi | ||
| 711 | ret | ||
| 712 | |||
| 713 | |||
| 714 | WELS_EXTERN VAACalcSadVar_sse2 | ||
| 715 | ;************************************************************************************************************* | ||
| 716 | ;void VAACalcSadVar_sse2( uint8_t *cur_data, uint8_t *ref_data, int32_t iPicWidth, int32_t iPicHeight | ||
| 717 | ; int32_t iPicStride, int32_t *psadframe, int32_t *psad8x8, int32_t *psum16x16, int32_t *psqsum16x16) | ||
| 718 | ;************************************************************************************************************* | ||
| 719 | |||
| 720 | |||
| 721 | ALIGN 16 | ||
| 722 | VAACalcSadVar_sse2: | ||
| 723 | %define localsize 8 | ||
| 724 | %define cur_data esp + pushsize + localsize + 4 | ||
| 725 | %define ref_data esp + pushsize + localsize + 8 | ||
| 726 | %define iPicWidth esp + pushsize + localsize + 12 | ||
| 727 | %define iPicHeight esp + pushsize + localsize + 16 | ||
| 728 | %define iPicStride esp + pushsize + localsize + 20 | ||
| 729 | %define psadframe esp + pushsize + localsize + 24 | ||
| 730 | %define psad8x8 esp + pushsize + localsize + 28 | ||
| 731 | %define psum16x16 esp + pushsize + localsize + 32 | ||
| 732 | %define psqsum16x16 esp + pushsize + localsize + 36 | ||
| 733 | %define tmp_esi esp + 0 | ||
| 734 | %define tmp_edi esp + 4 | ||
| 735 | %define pushsize 16 | ||
| 736 | push ebp | ||
| 737 | push esi | ||
| 738 | push edi | ||
| 739 | push ebx | ||
| 740 | sub esp, localsize | ||
| 741 | mov esi, [cur_data] | ||
| 742 | mov edi, [ref_data] | ||
| 743 | mov ebx, [iPicStride] | ||
| 744 | mov edx, [psad8x8] | ||
| 745 | mov eax, ebx | ||
| 746 | |||
| 747 | shr dword [iPicWidth], 4 ; iPicWidth/16 | ||
| 748 | shr dword [iPicHeight], 4 ; iPicHeight/16 | ||
| 749 | shl eax, 4 ; iPicStride*16 | ||
| 750 | pxor xmm0, xmm0 | ||
| 751 | pxor xmm7, xmm7 ; iFrameSad | ||
| 752 | var_height_loop: | ||
| 753 | mov ecx, dword [iPicWidth] | ||
| 754 | mov [tmp_esi], esi | ||
| 755 | mov [tmp_edi], edi | ||
| 756 | var_width_loop: | ||
| 757 | pxor xmm6, xmm6 ; hiQuad_loQuad pSad8x8 | ||
| 758 | pxor xmm5, xmm5 ; pSum16x16 | ||
| 759 | pxor xmm4, xmm4 ; sqsum_16x16 | ||
| 760 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 761 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 762 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 763 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 764 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 765 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 766 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 767 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 768 | paddd xmm7, xmm6 | ||
| 769 | movd [edx], xmm6 | ||
| 770 | psrldq xmm6, 8 | ||
| 771 | movd [edx+4], xmm6 | ||
| 772 | |||
| 773 | pxor xmm6, xmm6 | ||
| 774 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 775 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 776 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 777 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 778 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 779 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 780 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 781 | WELS_SAD_SUM_SQSUM_16x1_SSE2 | ||
| 782 | paddd xmm7, xmm6 | ||
| 783 | movd [edx+8], xmm6 | ||
| 784 | psrldq xmm6, 8 | ||
| 785 | movd [edx+12], xmm6 | ||
| 786 | |||
| 787 | mov ebp, [psum16x16] | ||
| 788 | movdqa xmm1, xmm5 | ||
| 789 | psrldq xmm1, 8 | ||
| 790 | paddd xmm5, xmm1 | ||
| 791 | movd [ebp], xmm5 | ||
| 792 | add dword [psum16x16], 4 | ||
| 793 | |||
| 794 | movdqa xmm5, xmm4 | ||
| 795 | psrldq xmm5, 8 | ||
| 796 | paddd xmm4, xmm5 | ||
| 797 | movdqa xmm3, xmm4 | ||
| 798 | psrldq xmm3, 4 | ||
| 799 | paddd xmm4, xmm3 | ||
| 800 | |||
| 801 | mov ebp, [psqsum16x16] | ||
| 802 | movd [ebp], xmm4 | ||
| 803 | add dword [psqsum16x16], 4 | ||
| 804 | |||
| 805 | add edx, 16 | ||
| 806 | sub esi, eax | ||
| 807 | sub edi, eax | ||
| 808 | add esi, 16 | ||
| 809 | add edi, 16 | ||
| 810 | |||
| 811 | dec ecx | ||
| 812 | jnz var_width_loop | ||
| 813 | |||
| 814 | mov esi, [tmp_esi] | ||
| 815 | mov edi, [tmp_edi] | ||
| 816 | add esi, eax | ||
| 817 | add edi, eax | ||
| 818 | |||
| 819 | dec dword [iPicHeight] | ||
| 820 | jnz var_height_loop | ||
| 821 | |||
| 822 | mov edx, [psadframe] | ||
| 823 | movdqa xmm5, xmm7 | ||
| 824 | psrldq xmm7, 8 | ||
| 825 | paddd xmm7, xmm5 | ||
| 826 | movd [edx], xmm7 | ||
| 827 | |||
| 828 | add esp, localsize | ||
| 829 | pop ebx | ||
| 830 | pop edi | ||
| 831 | pop esi | ||
| 832 | pop ebp | ||
| 833 | %undef cur_data | ||
| 834 | %undef ref_data | ||
| 835 | %undef iPicWidth | ||
| 836 | %undef iPicHeight | ||
| 837 | %undef iPicStride | ||
| 838 | %undef psadframe | ||
| 839 | %undef psad8x8 | ||
| 840 | %undef psum16x16 | ||
| 841 | %undef psqsum16x16 | ||
| 842 | %undef tmp_esi | ||
| 843 | %undef tmp_edi | ||
| 844 | %undef pushsize | ||
| 845 | %undef localsize | ||
| 846 | ret | ||
| 847 | |||
| 848 | |||
| 849 | |||
| 850 | WELS_EXTERN VAACalcSadSsd_sse2 | ||
| 851 | ;************************************************************************************************************* | ||
| 852 | ;void VAACalcSadSsd_sse2(uint8_t *cur_data, uint8_t *ref_data, int32_t iPicWidth, int32_t iPicHeight, | ||
| 853 | ; int32_t iPicStride,int32_t *psadframe, int32_t *psad8x8, int32_t *psum16x16, int32_t *psqsum16x16, int32_t *psqdiff16x16) | ||
| 854 | ;************************************************************************************************************* | ||
| 855 | |||
| 856 | |||
| 857 | ALIGN 16 | ||
| 858 | VAACalcSadSsd_sse2: | ||
| 859 | %define localsize 12 | ||
| 860 | %define cur_data esp + pushsize + localsize + 4 | ||
| 861 | %define ref_data esp + pushsize + localsize + 8 | ||
| 862 | %define iPicWidth esp + pushsize + localsize + 12 | ||
| 863 | %define iPicHeight esp + pushsize + localsize + 16 | ||
| 864 | %define iPicStride esp + pushsize + localsize + 20 | ||
| 865 | %define psadframe esp + pushsize + localsize + 24 | ||
| 866 | %define psad8x8 esp + pushsize + localsize + 28 | ||
| 867 | %define psum16x16 esp + pushsize + localsize + 32 | ||
| 868 | %define psqsum16x16 esp + pushsize + localsize + 36 | ||
| 869 | %define psqdiff16x16 esp + pushsize + localsize + 40 | ||
| 870 | %define tmp_esi esp + 0 | ||
| 871 | %define tmp_edi esp + 4 | ||
| 872 | %define tmp_sadframe esp + 8 | ||
| 873 | %define pushsize 16 | ||
| 874 | push ebp | ||
| 875 | push esi | ||
| 876 | push edi | ||
| 877 | push ebx | ||
| 878 | sub esp, localsize | ||
| 879 | mov ecx, [iPicWidth] | ||
| 880 | mov ecx, [iPicHeight] | ||
| 881 | mov esi, [cur_data] | ||
| 882 | mov edi, [ref_data] | ||
| 883 | mov ebx, [iPicStride] | ||
| 884 | mov edx, [psad8x8] | ||
| 885 | mov eax, ebx | ||
| 886 | |||
| 887 | shr dword [iPicWidth], 4 ; iPicWidth/16 | ||
| 888 | shr dword [iPicHeight], 4 ; iPicHeight/16 | ||
| 889 | shl eax, 4 ; iPicStride*16 | ||
| 890 | mov ecx, [iPicWidth] | ||
| 891 | mov ecx, [iPicHeight] | ||
| 892 | pxor xmm0, xmm0 | ||
| 893 | movd [tmp_sadframe], xmm0 | ||
| 894 | sqdiff_height_loop: | ||
| 895 | mov ecx, dword [iPicWidth] | ||
| 896 | mov [tmp_esi], esi | ||
| 897 | mov [tmp_edi], edi | ||
| 898 | sqdiff_width_loop: | ||
| 899 | pxor xmm7, xmm7 ; hiQuad_loQuad pSad8x8 | ||
| 900 | pxor xmm6, xmm6 ; pSum16x16 | ||
| 901 | pxor xmm5, xmm5 ; sqsum_16x16 four dword | ||
| 902 | pxor xmm4, xmm4 ; sqdiff_16x16 four Dword | ||
| 903 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 904 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 905 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 906 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 907 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 908 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 909 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 910 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 911 | movdqa xmm1, xmm7 | ||
| 912 | movd [edx], xmm7 | ||
| 913 | psrldq xmm7, 8 | ||
| 914 | paddd xmm1, xmm7 | ||
| 915 | movd [edx+4], xmm7 | ||
| 916 | movd ebp, xmm1 | ||
| 917 | add [tmp_sadframe], ebp | ||
| 918 | |||
| 919 | pxor xmm7, xmm7 | ||
| 920 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 921 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 922 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 923 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 924 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 925 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 926 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 927 | WELS_SAD_SUM_SQSUM_SQDIFF_16x1_SSE2 | ||
| 928 | movdqa xmm1, xmm7 | ||
| 929 | movd [edx+8], xmm7 | ||
| 930 | psrldq xmm7, 8 | ||
| 931 | paddd xmm1, xmm7 | ||
| 932 | movd [edx+12], xmm7 | ||
| 933 | movd ebp, xmm1 | ||
| 934 | add [tmp_sadframe], ebp | ||
| 935 | |||
| 936 | mov ebp, [psum16x16] | ||
| 937 | movdqa xmm1, xmm6 | ||
| 938 | psrldq xmm1, 8 | ||
| 939 | paddd xmm6, xmm1 | ||
| 940 | movd [ebp], xmm6 | ||
| 941 | add dword [psum16x16], 4 | ||
| 942 | |||
| 943 | mov ebp, [psqsum16x16] | ||
| 944 | pshufd xmm6, xmm5, 14 ;00001110 | ||
| 945 | paddd xmm6, xmm5 | ||
| 946 | pshufd xmm5, xmm6, 1 ;00000001 | ||
| 947 | paddd xmm5, xmm6 | ||
| 948 | movd [ebp], xmm5 | ||
| 949 | add dword [psqsum16x16], 4 | ||
| 950 | |||
| 951 | mov ebp, [psqdiff16x16] | ||
| 952 | pshufd xmm5, xmm4, 14 ; 00001110 | ||
| 953 | paddd xmm5, xmm4 | ||
| 954 | pshufd xmm4, xmm5, 1 ; 00000001 | ||
| 955 | paddd xmm4, xmm5 | ||
| 956 | movd [ebp], xmm4 | ||
| 957 | add dword [psqdiff16x16], 4 | ||
| 958 | |||
| 959 | add edx, 16 | ||
| 960 | sub esi, eax | ||
| 961 | sub edi, eax | ||
| 962 | add esi, 16 | ||
| 963 | add edi, 16 | ||
| 964 | |||
| 965 | dec ecx | ||
| 966 | jnz sqdiff_width_loop | ||
| 967 | |||
| 968 | mov esi, [tmp_esi] | ||
| 969 | mov edi, [tmp_edi] | ||
| 970 | add esi, eax | ||
| 971 | add edi, eax | ||
| 972 | |||
| 973 | dec dword [iPicHeight] | ||
| 974 | jnz sqdiff_height_loop | ||
| 975 | |||
| 976 | mov ebx, [tmp_sadframe] | ||
| 977 | mov eax, [psadframe] | ||
| 978 | mov [eax], ebx | ||
| 979 | |||
| 980 | add esp, localsize | ||
| 981 | pop ebx | ||
| 982 | pop edi | ||
| 983 | pop esi | ||
| 984 | pop ebp | ||
| 985 | %undef cur_data | ||
| 986 | %undef ref_data | ||
| 987 | %undef iPicWidth | ||
| 988 | %undef iPicHeight | ||
| 989 | %undef iPicStride | ||
| 990 | %undef psadframe | ||
| 991 | %undef psad8x8 | ||
| 992 | %undef psum16x16 | ||
| 993 | %undef psqsum16x16 | ||
| 994 | %undef psqdiff16x16 | ||
| 995 | %undef tmp_esi | ||
| 996 | %undef tmp_edi | ||
| 997 | %undef tmp_sadframe | ||
| 998 | %undef pushsize | ||
| 999 | %undef localsize | ||
| 1000 | ret | ||
| 1001 | |||
| 1002 | |||
| 1003 | |||
| 1004 | |||
| 1005 | |||
| 1006 | WELS_EXTERN VAACalcSadBgd_sse2 | ||
| 1007 | ;************************************************************************************************************* | ||
| 1008 | ;void VAACalcSadBgd_sse2(uint8_t *cur_data, uint8_t *ref_data, int32_t iPicWidth, int32_t iPicHeight, | ||
| 1009 | ; int32_t iPicStride, int32_t *psadframe, int32_t *psad8x8, int32_t *p_sd8x8, uint8_t *p_mad8x8) | ||
| 1010 | ;************************************************************************************************************* | ||
| 1011 | |||
| 1012 | |||
| 1013 | ALIGN 16 | ||
| 1014 | VAACalcSadBgd_sse2: | ||
| 1015 | %define localsize 12 | ||
| 1016 | %define cur_data esp + pushsize + localsize + 4 | ||
| 1017 | %define ref_data esp + pushsize + localsize + 8 | ||
| 1018 | %define iPicWidth esp + pushsize + localsize + 12 | ||
| 1019 | %define iPicHeight esp + pushsize + localsize + 16 | ||
| 1020 | %define iPicStride esp + pushsize + localsize + 20 | ||
| 1021 | %define psadframe esp + pushsize + localsize + 24 | ||
| 1022 | %define psad8x8 esp + pushsize + localsize + 28 | ||
| 1023 | %define p_sd8x8 esp + pushsize + localsize + 32 | ||
| 1024 | %define p_mad8x8 esp + pushsize + localsize + 36 | ||
| 1025 | %define tmp_esi esp + 0 | ||
| 1026 | %define tmp_edi esp + 4 | ||
| 1027 | %define tmp_ecx esp + 8 | ||
| 1028 | %define pushsize 16 | ||
| 1029 | push ebp | ||
| 1030 | push esi | ||
| 1031 | push edi | ||
| 1032 | push ebx | ||
| 1033 | sub esp, localsize | ||
| 1034 | mov esi, [cur_data] | ||
| 1035 | mov edi, [ref_data] | ||
| 1036 | mov ebx, [iPicStride] | ||
| 1037 | mov eax, ebx | ||
| 1038 | |||
| 1039 | shr dword [iPicWidth], 4 ; iPicWidth/16 | ||
| 1040 | shr dword [iPicHeight], 4 ; iPicHeight/16 | ||
| 1041 | shl eax, 4 ; iPicStride*16 | ||
| 1042 | xor ebp, ebp | ||
| 1043 | pxor xmm0, xmm0 | ||
| 1044 | bgd_height_loop: | ||
| 1045 | mov ecx, dword [iPicWidth] | ||
| 1046 | mov [tmp_esi], esi | ||
| 1047 | mov [tmp_edi], edi | ||
| 1048 | bgd_width_loop: | ||
| 1049 | pxor xmm7, xmm7 ; pSad8x8 | ||
| 1050 | pxor xmm6, xmm6 ; sum_cur_8x8 | ||
| 1051 | pxor xmm5, xmm5 ; sum_ref_8x8 | ||
| 1052 | pxor xmm4, xmm4 ; pMad8x8 | ||
| 1053 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1054 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1055 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1056 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1057 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1058 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1059 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1060 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1061 | |||
| 1062 | |||
| 1063 | mov edx, [p_mad8x8] | ||
| 1064 | WELS_MAX_REG_SSE2 xmm4 | ||
| 1065 | |||
| 1066 | ;movdqa xmm1, xmm4 | ||
| 1067 | ;punpcklbw xmm1, xmm0 | ||
| 1068 | ;punpcklwd xmm1, xmm0 | ||
| 1069 | ;movd [edx], xmm1 | ||
| 1070 | ;punpckhbw xmm4, xmm0 | ||
| 1071 | ;punpcklwd xmm4, xmm0 | ||
| 1072 | ;movd [edx+4], xmm4 | ||
| 1073 | ;add edx, 8 | ||
| 1074 | ;mov [p_mad8x8], edx | ||
| 1075 | mov [tmp_ecx], ecx | ||
| 1076 | movhlps xmm1, xmm4 | ||
| 1077 | movd ecx, xmm4 | ||
| 1078 | mov [edx], cl | ||
| 1079 | movd ecx, xmm1 | ||
| 1080 | mov [edx+1],cl | ||
| 1081 | add edx, 2 | ||
| 1082 | mov [p_mad8x8], edx | ||
| 1083 | |||
| 1084 | |||
| 1085 | pslldq xmm7, 4 | ||
| 1086 | pslldq xmm6, 4 | ||
| 1087 | pslldq xmm5, 4 | ||
| 1088 | |||
| 1089 | |||
| 1090 | pxor xmm4, xmm4 ; pMad8x8 | ||
| 1091 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1092 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1093 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1094 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1095 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1096 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1097 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1098 | WELS_SAD_SD_MAD_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1099 | |||
| 1100 | mov edx, [p_mad8x8] | ||
| 1101 | WELS_MAX_REG_SSE2 xmm4 | ||
| 1102 | |||
| 1103 | ;movdqa xmm1, xmm4 | ||
| 1104 | ;punpcklbw xmm1, xmm0 | ||
| 1105 | ;punpcklwd xmm1, xmm0 | ||
| 1106 | ;movd [edx], xmm1 | ||
| 1107 | ;punpckhbw xmm4, xmm0 | ||
| 1108 | ;punpcklwd xmm4, xmm0 | ||
| 1109 | ;movd [edx+4], xmm4 | ||
| 1110 | ;add edx, 8 | ||
| 1111 | ;mov [p_mad8x8], edx | ||
| 1112 | movhlps xmm1, xmm4 | ||
| 1113 | movd ecx, xmm4 | ||
| 1114 | mov [edx], cl | ||
| 1115 | movd ecx, xmm1 | ||
| 1116 | mov [edx+1],cl | ||
| 1117 | add edx, 2 | ||
| 1118 | mov [p_mad8x8], edx | ||
| 1119 | |||
| 1120 | ; data in xmm7, xmm6, xmm5: D1 D3 D0 D2 | ||
| 1121 | |||
| 1122 | mov edx, [psad8x8] | ||
| 1123 | pshufd xmm1, xmm7, 10001101b ; D3 D2 D1 D0 | ||
| 1124 | movdqa [edx], xmm1 | ||
| 1125 | add edx, 16 | ||
| 1126 | mov [psad8x8], edx ; sad8x8 | ||
| 1127 | |||
| 1128 | paddd xmm1, xmm7 ; D1+3 D3+2 D0+1 D2+0 | ||
| 1129 | pshufd xmm2, xmm1, 00000011b | ||
| 1130 | paddd xmm1, xmm2 | ||
| 1131 | movd edx, xmm1 | ||
| 1132 | add ebp, edx ; sad frame | ||
| 1133 | |||
| 1134 | mov edx, [p_sd8x8] | ||
| 1135 | psubd xmm6, xmm5 | ||
| 1136 | pshufd xmm1, xmm6, 10001101b | ||
| 1137 | movdqa [edx], xmm1 | ||
| 1138 | add edx, 16 | ||
| 1139 | mov [p_sd8x8], edx | ||
| 1140 | |||
| 1141 | |||
| 1142 | add edx, 16 | ||
| 1143 | sub esi, eax | ||
| 1144 | sub edi, eax | ||
| 1145 | add esi, 16 | ||
| 1146 | add edi, 16 | ||
| 1147 | |||
| 1148 | mov ecx, [tmp_ecx] | ||
| 1149 | dec ecx | ||
| 1150 | jnz bgd_width_loop | ||
| 1151 | |||
| 1152 | mov esi, [tmp_esi] | ||
| 1153 | mov edi, [tmp_edi] | ||
| 1154 | add esi, eax | ||
| 1155 | add edi, eax | ||
| 1156 | |||
| 1157 | dec dword [iPicHeight] | ||
| 1158 | jnz bgd_height_loop | ||
| 1159 | |||
| 1160 | mov edx, [psadframe] | ||
| 1161 | mov [edx], ebp | ||
| 1162 | |||
| 1163 | add esp, localsize | ||
| 1164 | pop ebx | ||
| 1165 | pop edi | ||
| 1166 | pop esi | ||
| 1167 | pop ebp | ||
| 1168 | %undef cur_data | ||
| 1169 | %undef ref_data | ||
| 1170 | %undef iPicWidth | ||
| 1171 | %undef iPicHeight | ||
| 1172 | %undef iPicStride | ||
| 1173 | %undef psadframe | ||
| 1174 | %undef psad8x8 | ||
| 1175 | %undef p_sd8x8 | ||
| 1176 | %undef p_mad8x8 | ||
| 1177 | %undef tmp_esi | ||
| 1178 | %undef tmp_edi | ||
| 1179 | %undef pushsize | ||
| 1180 | %undef localsize | ||
| 1181 | ret | ||
| 1182 | |||
| 1183 | |||
| 1184 | |||
| 1185 | WELS_EXTERN VAACalcSadSsdBgd_sse2 | ||
| 1186 | ;************************************************************************************************************* | ||
| 1187 | ;void VAACalcSadSsdBgd_sse2(uint8_t *cur_data, uint8_t *ref_data, int32_t iPicWidth, int32_t iPicHeight, | ||
| 1188 | ; int32_t iPicStride, int32_t *psadframe, int32_t *psad8x8, int32_t *psum16x16, int32_t *psqsum16x16, | ||
| 1189 | ; int32_t *psqdiff16x16, int32_t *p_sd8x8, uint8_t *p_mad8x8) | ||
| 1190 | ;************************************************************************************************************* | ||
| 1191 | |||
| 1192 | |||
| 1193 | ALIGN 16 | ||
| 1194 | VAACalcSadSsdBgd_sse2: | ||
| 1195 | %define localsize 16 | ||
| 1196 | %define cur_data esp + pushsize + localsize + 4 | ||
| 1197 | %define ref_data esp + pushsize + localsize + 8 | ||
| 1198 | %define iPicWidth esp + pushsize + localsize + 12 | ||
| 1199 | %define iPicHeight esp + pushsize + localsize + 16 | ||
| 1200 | %define iPicStride esp + pushsize + localsize + 20 | ||
| 1201 | %define psadframe esp + pushsize + localsize + 24 | ||
| 1202 | %define psad8x8 esp + pushsize + localsize + 28 | ||
| 1203 | %define psum16x16 esp + pushsize + localsize + 32 | ||
| 1204 | %define psqsum16x16 esp + pushsize + localsize + 36 | ||
| 1205 | %define psqdiff16x16 esp + pushsize + localsize + 40 | ||
| 1206 | %define p_sd8x8 esp + pushsize + localsize + 44 | ||
| 1207 | %define p_mad8x8 esp + pushsize + localsize + 48 | ||
| 1208 | %define tmp_esi esp + 0 | ||
| 1209 | %define tmp_edi esp + 4 | ||
| 1210 | %define tmp_sadframe esp + 8 | ||
| 1211 | %define tmp_ecx esp + 12 | ||
| 1212 | %define pushsize 16 | ||
| 1213 | push ebp | ||
| 1214 | push esi | ||
| 1215 | push edi | ||
| 1216 | push ebx | ||
| 1217 | sub esp, localsize | ||
| 1218 | mov esi, [cur_data] | ||
| 1219 | mov edi, [ref_data] | ||
| 1220 | mov ebx, [iPicStride] | ||
| 1221 | mov eax, ebx | ||
| 1222 | |||
| 1223 | shr dword [iPicWidth], 4 ; iPicWidth/16 | ||
| 1224 | shr dword [iPicHeight], 4 ; iPicHeight/16 | ||
| 1225 | shl eax, 4 ; iPicStride*16 | ||
| 1226 | pxor xmm0, xmm0 | ||
| 1227 | movd [tmp_sadframe], xmm0 | ||
| 1228 | sqdiff_bgd_height_loop: | ||
| 1229 | mov ecx, dword [iPicWidth] | ||
| 1230 | mov [tmp_esi], esi | ||
| 1231 | mov [tmp_edi], edi | ||
| 1232 | sqdiff_bgd_width_loop: | ||
| 1233 | pxor xmm7, xmm7 ; pSad8x8 interleaves sqsum16x16: sqsum1 sad1 sqsum0 sad0 | ||
| 1234 | pxor xmm6, xmm6 ; sum_8x8 interleaves cur and pRef in Dword, Sref1 Scur1 Sref0 Scur0 | ||
| 1235 | pxor xmm5, xmm5 ; pMad8x8 | ||
| 1236 | pxor xmm4, xmm4 ; sqdiff_16x16 four Dword | ||
| 1237 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1238 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1239 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1240 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1241 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1242 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1243 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1244 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1245 | |||
| 1246 | mov edx, [psad8x8] | ||
| 1247 | movdqa xmm2, xmm7 | ||
| 1248 | pshufd xmm1, xmm2, 00001110b | ||
| 1249 | movd [edx], xmm2 | ||
| 1250 | movd [edx+4], xmm1 | ||
| 1251 | add edx, 8 | ||
| 1252 | mov [psad8x8], edx ; sad8x8 | ||
| 1253 | |||
| 1254 | paddd xmm1, xmm2 | ||
| 1255 | movd edx, xmm1 | ||
| 1256 | add [tmp_sadframe], edx ; iFrameSad | ||
| 1257 | |||
| 1258 | mov edx, [psum16x16] | ||
| 1259 | movdqa xmm1, xmm6 | ||
| 1260 | pshufd xmm2, xmm1, 00001110b | ||
| 1261 | paddd xmm1, xmm2 | ||
| 1262 | movd [edx], xmm1 ; sum | ||
| 1263 | |||
| 1264 | mov edx, [p_sd8x8] | ||
| 1265 | pshufd xmm1, xmm6, 11110101b ; Sref1 Sref1 Sref0 Sref0 | ||
| 1266 | psubd xmm6, xmm1 ; 00 diff1 00 diff0 | ||
| 1267 | pshufd xmm1, xmm6, 00001000b ; xx xx diff1 diff0 | ||
| 1268 | movq [edx], xmm1 | ||
| 1269 | add edx, 8 | ||
| 1270 | mov [p_sd8x8], edx | ||
| 1271 | |||
| 1272 | mov edx, [p_mad8x8] | ||
| 1273 | WELS_MAX_REG_SSE2 xmm5 | ||
| 1274 | ;movdqa xmm1, xmm5 | ||
| 1275 | ;punpcklbw xmm1, xmm0 | ||
| 1276 | ;punpcklwd xmm1, xmm0 | ||
| 1277 | ;movd [edx], xmm1 | ||
| 1278 | ;punpckhbw xmm5, xmm0 | ||
| 1279 | ;punpcklwd xmm5, xmm0 | ||
| 1280 | ;movd [edx+4], xmm5 | ||
| 1281 | ;add edx, 8 | ||
| 1282 | ;mov [p_mad8x8], edx | ||
| 1283 | mov [tmp_ecx], ecx | ||
| 1284 | movhlps xmm1, xmm5 | ||
| 1285 | movd ecx, xmm5 | ||
| 1286 | mov [edx], cl | ||
| 1287 | movd ecx, xmm1 | ||
| 1288 | mov [edx+1],cl | ||
| 1289 | add edx, 2 | ||
| 1290 | mov [p_mad8x8], edx | ||
| 1291 | |||
| 1292 | psrlq xmm7, 32 | ||
| 1293 | psllq xmm7, 32 ; clear sad | ||
| 1294 | pxor xmm6, xmm6 ; sum_8x8 interleaves cur and pRef in Dword, Sref1 Scur1 Sref0 Scur0 | ||
| 1295 | pxor xmm5, xmm5 ; pMad8x8 | ||
| 1296 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1297 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1298 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1299 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1300 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1301 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1302 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1303 | WELS_SAD_BGD_SQDIFF_16x1_SSE2 xmm7, xmm6, xmm5, xmm4 | ||
| 1304 | |||
| 1305 | mov edx, [psad8x8] | ||
| 1306 | movdqa xmm2, xmm7 | ||
| 1307 | pshufd xmm1, xmm2, 00001110b | ||
| 1308 | movd [edx], xmm2 | ||
| 1309 | movd [edx+4], xmm1 | ||
| 1310 | add edx, 8 | ||
| 1311 | mov [psad8x8], edx ; sad8x8 | ||
| 1312 | |||
| 1313 | paddd xmm1, xmm2 | ||
| 1314 | movd edx, xmm1 | ||
| 1315 | add [tmp_sadframe], edx ; iFrameSad | ||
| 1316 | |||
| 1317 | mov edx, [psum16x16] | ||
| 1318 | movdqa xmm1, xmm6 | ||
| 1319 | pshufd xmm2, xmm1, 00001110b | ||
| 1320 | paddd xmm1, xmm2 | ||
| 1321 | movd ebp, xmm1 ; sum | ||
| 1322 | add [edx], ebp | ||
| 1323 | add edx, 4 | ||
| 1324 | mov [psum16x16], edx | ||
| 1325 | |||
| 1326 | mov edx, [psqsum16x16] | ||
| 1327 | psrlq xmm7, 32 | ||
| 1328 | pshufd xmm2, xmm7, 00001110b | ||
| 1329 | paddd xmm2, xmm7 | ||
| 1330 | movd [edx], xmm2 ; sqsum | ||
| 1331 | add edx, 4 | ||
| 1332 | mov [psqsum16x16], edx | ||
| 1333 | |||
| 1334 | mov edx, [p_sd8x8] | ||
| 1335 | pshufd xmm1, xmm6, 11110101b ; Sref1 Sref1 Sref0 Sref0 | ||
| 1336 | psubd xmm6, xmm1 ; 00 diff1 00 diff0 | ||
| 1337 | pshufd xmm1, xmm6, 00001000b ; xx xx diff1 diff0 | ||
| 1338 | movq [edx], xmm1 | ||
| 1339 | add edx, 8 | ||
| 1340 | mov [p_sd8x8], edx | ||
| 1341 | |||
| 1342 | mov edx, [p_mad8x8] | ||
| 1343 | WELS_MAX_REG_SSE2 xmm5 | ||
| 1344 | ;movdqa xmm1, xmm5 | ||
| 1345 | ;punpcklbw xmm1, xmm0 | ||
| 1346 | ;punpcklwd xmm1, xmm0 | ||
| 1347 | ;movd [edx], xmm1 | ||
| 1348 | ;punpckhbw xmm5, xmm0 | ||
| 1349 | ;punpcklwd xmm5, xmm0 | ||
| 1350 | ;movd [edx+4], xmm5 | ||
| 1351 | ;add edx, 8 | ||
| 1352 | ;mov [p_mad8x8], edx | ||
| 1353 | movhlps xmm1, xmm5 | ||
| 1354 | movd ecx, xmm5 | ||
| 1355 | mov [edx], cl | ||
| 1356 | movd ecx, xmm1 | ||
| 1357 | mov [edx+1],cl | ||
| 1358 | add edx, 2 | ||
| 1359 | mov [p_mad8x8], edx | ||
| 1360 | |||
| 1361 | mov edx, [psqdiff16x16] | ||
| 1362 | pshufd xmm1, xmm4, 00001110b | ||
| 1363 | paddd xmm4, xmm1 | ||
| 1364 | pshufd xmm1, xmm4, 00000001b | ||
| 1365 | paddd xmm4, xmm1 | ||
| 1366 | movd [edx], xmm4 | ||
| 1367 | add edx, 4 | ||
| 1368 | mov [psqdiff16x16], edx | ||
| 1369 | |||
| 1370 | add edx, 16 | ||
| 1371 | sub esi, eax | ||
| 1372 | sub edi, eax | ||
| 1373 | add esi, 16 | ||
| 1374 | add edi, 16 | ||
| 1375 | |||
| 1376 | mov ecx, [tmp_ecx] | ||
| 1377 | dec ecx | ||
| 1378 | jnz sqdiff_bgd_width_loop | ||
| 1379 | |||
| 1380 | mov esi, [tmp_esi] | ||
| 1381 | mov edi, [tmp_edi] | ||
| 1382 | add esi, eax | ||
| 1383 | add edi, eax | ||
| 1384 | |||
| 1385 | dec dword [iPicHeight] | ||
| 1386 | jnz sqdiff_bgd_height_loop | ||
| 1387 | |||
| 1388 | mov edx, [psadframe] | ||
| 1389 | mov ebp, [tmp_sadframe] | ||
| 1390 | mov [edx], ebp | ||
| 1391 | |||
| 1392 | add esp, localsize | ||
| 1393 | pop ebx | ||
| 1394 | pop edi | ||
| 1395 | pop esi | ||
| 1396 | pop ebp | ||
| 1397 | %undef cur_data | ||
| 1398 | %undef ref_data | ||
| 1399 | %undef iPicWidth | ||
| 1400 | %undef iPicHeight | ||
| 1401 | %undef iPicStride | ||
| 1402 | %undef psadframe | ||
| 1403 | %undef psad8x8 | ||
| 1404 | %undef psum16x16 | ||
| 1405 | %undef psqsum16x16 | ||
| 1406 | %undef psqdiff16x16 | ||
| 1407 | %undef p_sd8x8 | ||
| 1408 | %undef p_mad8x8 | ||
| 1409 | %undef tmp_esi | ||
| 1410 | %undef tmp_edi | ||
| 1411 | %undef pushsize | ||
| 1412 | %undef localsize | ||
| 1413 | ret | ||
| 1414 | %endif | ||
| @@ -0,0 +1,389 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "BackgroundDetection.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | #define LOG2_BGD_OU_SIZE (4) | ||
| 39 | #define LOG2_BGD_OU_SIZE_UV (LOG2_BGD_OU_SIZE-1) | ||
| 40 | #define BGD_OU_SIZE (1<<LOG2_BGD_OU_SIZE) | ||
| 41 | #define BGD_OU_SIZE_UV (BGD_OU_SIZE>>1) | ||
| 42 | #define BGD_THD_SAD (2*BGD_OU_SIZE*BGD_OU_SIZE) | ||
| 43 | #define BGD_THD_ASD_UV (4*BGD_OU_SIZE_UV) | ||
| 44 | #define LOG2_MB_SIZE (4) | ||
| 45 | #define OU_SIZE_IN_MB (BGD_OU_SIZE >> 4) | ||
| 46 | #define Q_FACTOR (8) | ||
| 47 | #define BGD_DELTA_QP_THD (3) | ||
| 48 | |||
| 49 | #define OU_LEFT (0x01) | ||
| 50 | #define OU_RIGHT (0x02) | ||
| 51 | #define OU_TOP (0x04) | ||
| 52 | #define OU_BOTTOM (0x08) | ||
| 53 | |||
| 54 | CBackgroundDetection::CBackgroundDetection (int32_t iCpuFlag) { | ||
| 55 | m_eMethod = METHOD_BACKGROUND_DETECTION; | ||
| 56 | WelsMemset (&m_BgdParam, 0, sizeof (m_BgdParam)); | ||
| 57 | m_iLargestFrameSize = 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | CBackgroundDetection::~CBackgroundDetection() { | ||
| 61 | FreeOUArrayMemory(); | ||
| 62 | } | ||
| 63 | |||
| 64 | EResult CBackgroundDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 65 | EResult eReturn = RET_INVALIDPARAM; | ||
| 66 | |||
| 67 | if (pSrcPixMap == NULL || pRefPixMap == NULL) | ||
| 68 | return eReturn; | ||
| 69 | |||
| 70 | m_BgdParam.pCur[0] = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 71 | m_BgdParam.pCur[1] = (uint8_t*)pSrcPixMap->pPixel[1]; | ||
| 72 | m_BgdParam.pCur[2] = (uint8_t*)pSrcPixMap->pPixel[2]; | ||
| 73 | m_BgdParam.pRef[0] = (uint8_t*)pRefPixMap->pPixel[0]; | ||
| 74 | m_BgdParam.pRef[1] = (uint8_t*)pRefPixMap->pPixel[1]; | ||
| 75 | m_BgdParam.pRef[2] = (uint8_t*)pRefPixMap->pPixel[2]; | ||
| 76 | m_BgdParam.iBgdWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 77 | m_BgdParam.iBgdHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 78 | m_BgdParam.iStride[0] = pSrcPixMap->iStride[0]; | ||
| 79 | m_BgdParam.iStride[1] = pSrcPixMap->iStride[1]; | ||
| 80 | m_BgdParam.iStride[2] = pSrcPixMap->iStride[2]; | ||
| 81 | |||
| 82 | int32_t iCurFrameSize = m_BgdParam.iBgdWidth * m_BgdParam.iBgdHeight; | ||
| 83 | if (m_BgdParam.pOU_array == NULL || iCurFrameSize > m_iLargestFrameSize) { | ||
| 84 | FreeOUArrayMemory(); | ||
| 85 | m_BgdParam.pOU_array = AllocateOUArrayMemory (m_BgdParam.iBgdWidth, m_BgdParam.iBgdHeight); | ||
| 86 | m_iLargestFrameSize = iCurFrameSize; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (m_BgdParam.pOU_array == NULL) | ||
| 90 | return eReturn; | ||
| 91 | |||
| 92 | BackgroundDetection (&m_BgdParam); | ||
| 93 | |||
| 94 | return RET_SUCCESS; | ||
| 95 | } | ||
| 96 | |||
| 97 | EResult CBackgroundDetection::Set (int32_t iType, void* pParam) { | ||
| 98 | if (pParam == NULL) { | ||
| 99 | return RET_INVALIDPARAM; | ||
| 100 | } | ||
| 101 | |||
| 102 | SBGDInterface* pInterface = (SBGDInterface*)pParam; | ||
| 103 | |||
| 104 | m_BgdParam.pBackgroundMbFlag = (int8_t*)pInterface->pBackgroundMbFlag; | ||
| 105 | m_BgdParam.pCalcRes = pInterface->pCalcRes; | ||
| 106 | |||
| 107 | return RET_SUCCESS; | ||
| 108 | } | ||
| 109 | |||
| 110 | inline SBackgroundOU* CBackgroundDetection::AllocateOUArrayMemory (int32_t iWidth, int32_t iHeight) { | ||
| 111 | int32_t iMaxOUWidth = (BGD_OU_SIZE - 1 + iWidth) >> LOG2_BGD_OU_SIZE; | ||
| 112 | int32_t iMaxOUHeight = (BGD_OU_SIZE - 1 + iHeight) >> LOG2_BGD_OU_SIZE; | ||
| 113 | return (SBackgroundOU*)WelsMalloc (iMaxOUWidth * iMaxOUHeight * sizeof (SBackgroundOU)); | ||
| 114 | } | ||
| 115 | |||
| 116 | inline void CBackgroundDetection::FreeOUArrayMemory() { | ||
| 117 | _SafeFree (m_BgdParam.pOU_array); | ||
| 118 | } | ||
| 119 | |||
| 120 | void CBackgroundDetection::GetOUParameters (SVAACalcResult* sVaaCalcInfo, int32_t iMbIndex, int32_t iMbWidth, | ||
| 121 | SBackgroundOU* pBgdOU) { | ||
| 122 | int32_t iSubSD[4]; | ||
| 123 | uint8_t iSubMAD[4]; | ||
| 124 | int32_t iSubSAD[4]; | ||
| 125 | |||
| 126 | uint8_t (*pMad8x8)[4]; | ||
| 127 | int32_t (*pSad8x8)[4]; | ||
| 128 | int32_t (*pSd8x8)[4]; | ||
| 129 | |||
| 130 | pSad8x8 = sVaaCalcInfo->pSad8x8; | ||
| 131 | pMad8x8 = sVaaCalcInfo->pMad8x8; | ||
| 132 | pSd8x8 = sVaaCalcInfo->pSumOfDiff8x8; | ||
| 133 | |||
| 134 | iSubSAD[0] = pSad8x8[iMbIndex][0]; | ||
| 135 | iSubSAD[1] = pSad8x8[iMbIndex][1]; | ||
| 136 | iSubSAD[2] = pSad8x8[iMbIndex][2]; | ||
| 137 | iSubSAD[3] = pSad8x8[iMbIndex][3]; | ||
| 138 | |||
| 139 | iSubSD[0] = pSd8x8[iMbIndex][0]; | ||
| 140 | iSubSD[1] = pSd8x8[iMbIndex][1]; | ||
| 141 | iSubSD[2] = pSd8x8[iMbIndex][2]; | ||
| 142 | iSubSD[3] = pSd8x8[iMbIndex][3]; | ||
| 143 | |||
| 144 | iSubMAD[0] = pMad8x8[iMbIndex][0]; | ||
| 145 | iSubMAD[1] = pMad8x8[iMbIndex][1]; | ||
| 146 | iSubMAD[2] = pMad8x8[iMbIndex][2]; | ||
| 147 | iSubMAD[3] = pMad8x8[iMbIndex][3]; | ||
| 148 | |||
| 149 | pBgdOU->iSD = iSubSD[0] + iSubSD[1] + iSubSD[2] + iSubSD[3]; | ||
| 150 | pBgdOU->iSAD = iSubSAD[0] + iSubSAD[1] + iSubSAD[2] + iSubSAD[3]; | ||
| 151 | pBgdOU->iSD = WELS_ABS (pBgdOU->iSD); | ||
| 152 | |||
| 153 | // get the max absolute difference (MAD) of OU and min value of the MAD of sub-blocks of OU | ||
| 154 | pBgdOU->iMAD = WELS_MAX (WELS_MAX (iSubMAD[0], iSubMAD[1]), WELS_MAX (iSubMAD[2], iSubMAD[3])); | ||
| 155 | pBgdOU->iMinSubMad = WELS_MIN (WELS_MIN (iSubMAD[0], iSubMAD[1]), WELS_MIN (iSubMAD[2], iSubMAD[3])); | ||
| 156 | |||
| 157 | // get difference between the max and min SD of the SDs of sub-blocks of OU | ||
| 158 | pBgdOU->iMaxDiffSubSd = WELS_MAX (WELS_MAX (iSubSD[0], iSubSD[1]), WELS_MAX (iSubSD[2], iSubSD[3])) - | ||
| 159 | WELS_MIN (WELS_MIN (iSubSD[0], iSubSD[1]), WELS_MIN (iSubSD[2], iSubSD[3])); | ||
| 160 | } | ||
| 161 | |||
| 162 | void CBackgroundDetection::ForegroundBackgroundDivision (vBGDParam* pBgdParam) { | ||
| 163 | int32_t iPicWidthInOU = pBgdParam->iBgdWidth >> LOG2_BGD_OU_SIZE; | ||
| 164 | int32_t iPicHeightInOU = pBgdParam->iBgdHeight >> LOG2_BGD_OU_SIZE; | ||
| 165 | int32_t iPicWidthInMb = (15 + pBgdParam->iBgdWidth) >> 4; | ||
| 166 | |||
| 167 | SBackgroundOU* pBackgroundOU = pBgdParam->pOU_array; | ||
| 168 | |||
| 169 | for (int32_t j = 0; j < iPicHeightInOU; j ++) { | ||
| 170 | for (int32_t i = 0; i < iPicWidthInOU; i++) { | ||
| 171 | GetOUParameters (pBgdParam->pCalcRes, (j * iPicWidthInMb + i) << (LOG2_BGD_OU_SIZE - LOG2_MB_SIZE), iPicWidthInMb, | ||
| 172 | pBackgroundOU); | ||
| 173 | |||
| 174 | pBackgroundOU->iBackgroundFlag = 0; | ||
| 175 | if (pBackgroundOU->iMAD > 63) { | ||
| 176 | pBackgroundOU++; | ||
| 177 | continue; | ||
| 178 | } | ||
| 179 | if ((pBackgroundOU->iMaxDiffSubSd <= pBackgroundOU->iSAD >> 3 | ||
| 180 | || pBackgroundOU->iMaxDiffSubSd <= (BGD_OU_SIZE * Q_FACTOR)) | ||
| 181 | && pBackgroundOU->iSAD < (BGD_THD_SAD << 1)) { //BGD_OU_SIZE*BGD_OU_SIZE>>2 | ||
| 182 | if (pBackgroundOU->iSAD <= BGD_OU_SIZE * Q_FACTOR) { | ||
| 183 | pBackgroundOU->iBackgroundFlag = 1; | ||
| 184 | } else { | ||
| 185 | pBackgroundOU->iBackgroundFlag = pBackgroundOU->iSAD < BGD_THD_SAD ? | ||
| 186 | (pBackgroundOU->iSD < (pBackgroundOU->iSAD * 3) >> 2) : | ||
| 187 | (pBackgroundOU->iSD << 1 < pBackgroundOU->iSAD); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | pBackgroundOU++; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | } | ||
| 194 | inline int32_t CBackgroundDetection::CalculateAsdChromaEdge (uint8_t* pOriRef, uint8_t* pOriCur, int32_t iStride) { | ||
| 195 | int32_t ASD = 0; | ||
| 196 | int32_t idx; | ||
| 197 | for (idx = 0; idx < BGD_OU_SIZE_UV; idx++) { | ||
| 198 | ASD += *pOriCur - *pOriRef; | ||
| 199 | pOriRef += iStride; | ||
| 200 | pOriCur += iStride; | ||
| 201 | } | ||
| 202 | return WELS_ABS (ASD); | ||
| 203 | } | ||
| 204 | |||
| 205 | inline bool_t CBackgroundDetection::ForegroundDilation23Luma (SBackgroundOU* pBackgroundOU, | ||
| 206 | SBackgroundOU* pOUNeighbours[]) { | ||
| 207 | SBackgroundOU* pOU_L = pOUNeighbours[0]; | ||
| 208 | SBackgroundOU* pOU_R = pOUNeighbours[1]; | ||
| 209 | SBackgroundOU* pOU_U = pOUNeighbours[2]; | ||
| 210 | SBackgroundOU* pOU_D = pOUNeighbours[3]; | ||
| 211 | |||
| 212 | if (pBackgroundOU->iMAD > pBackgroundOU->iMinSubMad << 1) { | ||
| 213 | int32_t iMaxNbrForegroundMad; | ||
| 214 | int32_t iMaxNbrBackgroundMad; | ||
| 215 | int32_t aBackgroundMad[4]; | ||
| 216 | int32_t aForegroundMad[4]; | ||
| 217 | |||
| 218 | aForegroundMad[0] = (pOU_L->iBackgroundFlag - 1) & pOU_L->iMAD; | ||
| 219 | aForegroundMad[1] = (pOU_R->iBackgroundFlag - 1) & pOU_R->iMAD; | ||
| 220 | aForegroundMad[2] = (pOU_U->iBackgroundFlag - 1) & pOU_U->iMAD; | ||
| 221 | aForegroundMad[3] = (pOU_D->iBackgroundFlag - 1) & pOU_D->iMAD; | ||
| 222 | iMaxNbrForegroundMad = WELS_MAX (WELS_MAX (aForegroundMad[0], aForegroundMad[1]), WELS_MAX (aForegroundMad[2], | ||
| 223 | aForegroundMad[3])); | ||
| 224 | |||
| 225 | aBackgroundMad[0] = ((!pOU_L->iBackgroundFlag) - 1) & pOU_L->iMAD; | ||
| 226 | aBackgroundMad[1] = ((!pOU_R->iBackgroundFlag) - 1) & pOU_R->iMAD; | ||
| 227 | aBackgroundMad[2] = ((!pOU_U->iBackgroundFlag) - 1) & pOU_U->iMAD; | ||
| 228 | aBackgroundMad[3] = ((!pOU_D->iBackgroundFlag) - 1) & pOU_D->iMAD; | ||
| 229 | iMaxNbrBackgroundMad = WELS_MAX (WELS_MAX (aBackgroundMad[0], aBackgroundMad[1]), WELS_MAX (aBackgroundMad[2], | ||
| 230 | aBackgroundMad[3])); | ||
| 231 | |||
| 232 | return ((iMaxNbrForegroundMad > pBackgroundOU->iMinSubMad << 2) || (pBackgroundOU->iMAD > iMaxNbrBackgroundMad << 1 | ||
| 233 | && pBackgroundOU->iMAD <= (iMaxNbrForegroundMad * 3) >> 1)); | ||
| 234 | } | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | inline bool_t CBackgroundDetection::ForegroundDilation23Chroma (int8_t iNeighbourForegroundFlags, | ||
| 239 | int32_t iStartSamplePos, int32_t iPicStrideUV, vBGDParam* pBgdParam) { | ||
| 240 | static const int8_t kaOUPos[4] = {OU_LEFT, OU_RIGHT, OU_TOP, OU_BOTTOM}; | ||
| 241 | int32_t aEdgeOffset[4] = {0, BGD_OU_SIZE_UV - 1, 0, iPicStrideUV* (BGD_OU_SIZE_UV - 1)}; | ||
| 242 | int32_t iStride[4] = {iPicStrideUV, iPicStrideUV, 1, 1}; | ||
| 243 | |||
| 244 | // V component first, high probability because V stands for red color and human skin colors have more weight on this component | ||
| 245 | for (int32_t i = 0; i < 4; i++) { | ||
| 246 | if (iNeighbourForegroundFlags & kaOUPos[i]) { | ||
| 247 | uint8_t* pRefC = pBgdParam->pRef[2] + iStartSamplePos + aEdgeOffset[i]; | ||
| 248 | uint8_t* pCurC = pBgdParam->pCur[2] + iStartSamplePos + aEdgeOffset[i]; | ||
| 249 | if (CalculateAsdChromaEdge (pRefC, pCurC, iStride[i]) > BGD_THD_ASD_UV) { | ||
| 250 | return 1; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | } | ||
| 254 | // U component, which stands for blue color, low probability | ||
| 255 | for (int32_t i = 0; i < 4; i++) { | ||
| 256 | if (iNeighbourForegroundFlags & kaOUPos[i]) { | ||
| 257 | uint8_t* pRefC = pBgdParam->pRef[1] + iStartSamplePos + aEdgeOffset[i]; | ||
| 258 | uint8_t* pCurC = pBgdParam->pCur[1] + iStartSamplePos + aEdgeOffset[i]; | ||
| 259 | if (CalculateAsdChromaEdge (pRefC, pCurC, iStride[i]) > BGD_THD_ASD_UV) { | ||
| 260 | return 1; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 268 | inline void CBackgroundDetection::ForegroundDilation (SBackgroundOU* pBackgroundOU, SBackgroundOU* pOUNeighbours[], | ||
| 269 | vBGDParam* pBgdParam, int32_t iChromaSampleStartPos) { | ||
| 270 | int32_t iPicStrideUV = pBgdParam->iStride[1]; | ||
| 271 | int32_t iSumNeighBackgroundFlags = pOUNeighbours[0]->iBackgroundFlag + pOUNeighbours[1]->iBackgroundFlag + | ||
| 272 | pOUNeighbours[2]->iBackgroundFlag + pOUNeighbours[3]->iBackgroundFlag; | ||
| 273 | |||
| 274 | if (pBackgroundOU->iSAD > BGD_OU_SIZE * Q_FACTOR) { | ||
| 275 | switch (iSumNeighBackgroundFlags) { | ||
| 276 | case 0: | ||
| 277 | case 1: | ||
| 278 | pBackgroundOU->iBackgroundFlag = 0; | ||
| 279 | break; | ||
| 280 | case 2: | ||
| 281 | case 3: | ||
| 282 | pBackgroundOU->iBackgroundFlag = !ForegroundDilation23Luma (pBackgroundOU, pOUNeighbours); | ||
| 283 | |||
| 284 | // chroma component check | ||
| 285 | if (pBackgroundOU->iBackgroundFlag == 1) { | ||
| 286 | int8_t iNeighbourForegroundFlags = !pOUNeighbours[0]->iBackgroundFlag | ((!pOUNeighbours[1]->iBackgroundFlag) << 1) | ||
| 287 | | ((!pOUNeighbours[2]->iBackgroundFlag) << 2) | ((!pOUNeighbours[3]->iBackgroundFlag) << 3); | ||
| 288 | pBackgroundOU->iBackgroundFlag = !ForegroundDilation23Chroma (iNeighbourForegroundFlags, iChromaSampleStartPos, | ||
| 289 | iPicStrideUV, pBgdParam); | ||
| 290 | } | ||
| 291 | break; | ||
| 292 | default: | ||
| 293 | break; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | } | ||
| 297 | inline void CBackgroundDetection::BackgroundErosion (SBackgroundOU* pBackgroundOU, SBackgroundOU* pOUNeighbours[]) { | ||
| 298 | if (pBackgroundOU->iMaxDiffSubSd <= (BGD_OU_SIZE * Q_FACTOR)) { //BGD_OU_SIZE*BGD_OU_SIZE>>2 | ||
| 299 | int32_t iSumNeighBackgroundFlags = pOUNeighbours[0]->iBackgroundFlag + pOUNeighbours[1]->iBackgroundFlag + | ||
| 300 | pOUNeighbours[2]->iBackgroundFlag + pOUNeighbours[3]->iBackgroundFlag; | ||
| 301 | int32_t sumNbrBGsad = (pOUNeighbours[0]->iSAD & (-pOUNeighbours[0]->iBackgroundFlag)) + (pOUNeighbours[2]->iSAD & | ||
| 302 | (-pOUNeighbours[2]->iBackgroundFlag)) | ||
| 303 | + (pOUNeighbours[1]->iSAD & (-pOUNeighbours[1]->iBackgroundFlag)) + (pOUNeighbours[3]->iSAD & | ||
| 304 | (-pOUNeighbours[3]->iBackgroundFlag)); | ||
| 305 | if (pBackgroundOU->iSAD * iSumNeighBackgroundFlags <= (3 * sumNbrBGsad) >> 1) { | ||
| 306 | if (iSumNeighBackgroundFlags == 4) { | ||
| 307 | pBackgroundOU->iBackgroundFlag = 1; | ||
| 308 | } else { | ||
| 309 | if ((pOUNeighbours[0]->iBackgroundFlag & pOUNeighbours[1]->iBackgroundFlag) | ||
| 310 | || (pOUNeighbours[2]->iBackgroundFlag & pOUNeighbours[3]->iBackgroundFlag)) { | ||
| 311 | pBackgroundOU->iBackgroundFlag = !ForegroundDilation23Luma (pBackgroundOU, pOUNeighbours); | ||
| 312 | } | ||
| 313 | } | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | inline void CBackgroundDetection::SetBackgroundMbFlag (int8_t* pBackgroundMbFlag, int32_t iPicWidthInMb, | ||
| 319 | int32_t iBackgroundMbFlag) { | ||
| 320 | *pBackgroundMbFlag = iBackgroundMbFlag; | ||
| 321 | } | ||
| 322 | |||
| 323 | inline void CBackgroundDetection::UpperOUForegroundCheck (SBackgroundOU* pCurOU, int8_t* pBackgroundMbFlag, | ||
| 324 | int32_t iPicWidthInOU, int32_t iPicWidthInMb) { | ||
| 325 | if (pCurOU->iSAD > BGD_OU_SIZE * Q_FACTOR) { | ||
| 326 | SBackgroundOU* pOU_L = pCurOU - 1; | ||
| 327 | SBackgroundOU* pOU_R = pCurOU + 1; | ||
| 328 | SBackgroundOU* pOU_U = pCurOU - iPicWidthInOU; | ||
| 329 | SBackgroundOU* pOU_D = pCurOU + iPicWidthInOU; | ||
| 330 | if (pOU_L->iBackgroundFlag + pOU_R->iBackgroundFlag + pOU_U->iBackgroundFlag + pOU_D->iBackgroundFlag <= 1) { | ||
| 331 | SetBackgroundMbFlag (pBackgroundMbFlag, iPicWidthInMb, 0); | ||
| 332 | pCurOU->iBackgroundFlag = 0; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | void CBackgroundDetection::ForegroundDilationAndBackgroundErosion (vBGDParam* pBgdParam) { | ||
| 338 | int32_t iPicStrideUV = pBgdParam->iStride[1]; | ||
| 339 | int32_t iPicWidthInOU = pBgdParam->iBgdWidth >> LOG2_BGD_OU_SIZE; | ||
| 340 | int32_t iPicHeightInOU = pBgdParam->iBgdHeight >> LOG2_BGD_OU_SIZE; | ||
| 341 | int32_t iOUStrideUV = iPicStrideUV << (LOG2_BGD_OU_SIZE - 1); | ||
| 342 | int32_t iPicWidthInMb = (15 + pBgdParam->iBgdWidth) >> 4; | ||
| 343 | |||
| 344 | SBackgroundOU* pBackgroundOU = pBgdParam->pOU_array; | ||
| 345 | int8_t* pVaaBackgroundMbFlag = (int8_t*)pBgdParam->pBackgroundMbFlag; | ||
| 346 | SBackgroundOU* pOUNeighbours[4];//0: left; 1: right; 2: top; 3: bottom | ||
| 347 | |||
| 348 | pBackgroundOU = pBgdParam->pOU_array; | ||
| 349 | pOUNeighbours[2] = pBackgroundOU;//top OU | ||
| 350 | for (int32_t j = 0; j < iPicHeightInOU; j ++) { | ||
| 351 | int8_t* pRowSkipFlag = pVaaBackgroundMbFlag; | ||
| 352 | pOUNeighbours[0] = pBackgroundOU;//left OU | ||
| 353 | pOUNeighbours[3] = pBackgroundOU + (iPicWidthInOU & ((j == iPicHeightInOU - 1) - 1)); //bottom OU | ||
| 354 | for (int32_t i = 0; i < iPicWidthInOU; i++) { | ||
| 355 | pOUNeighbours[1] = pBackgroundOU + (i < iPicWidthInOU - 1); //right OU | ||
| 356 | |||
| 357 | if (pBackgroundOU->iBackgroundFlag) | ||
| 358 | ForegroundDilation (pBackgroundOU, pOUNeighbours, pBgdParam, j * iOUStrideUV + (i << LOG2_BGD_OU_SIZE_UV)); | ||
| 359 | else | ||
| 360 | BackgroundErosion (pBackgroundOU, pOUNeighbours); | ||
| 361 | |||
| 362 | // check the up OU | ||
| 363 | if (j > 1 && i > 0 && i < iPicWidthInOU - 1 && pOUNeighbours[2]->iBackgroundFlag == 1) { | ||
| 364 | UpperOUForegroundCheck (pOUNeighbours[2], pRowSkipFlag - OU_SIZE_IN_MB * iPicWidthInMb, iPicWidthInOU, iPicWidthInMb); | ||
| 365 | } | ||
| 366 | |||
| 367 | SetBackgroundMbFlag (pRowSkipFlag, iPicWidthInMb, pBackgroundOU->iBackgroundFlag); | ||
| 368 | |||
| 369 | // preparation for the next OU | ||
| 370 | pRowSkipFlag += OU_SIZE_IN_MB; | ||
| 371 | pOUNeighbours[0] = pBackgroundOU; | ||
| 372 | pOUNeighbours[2]++; | ||
| 373 | pOUNeighbours[3]++; | ||
| 374 | pBackgroundOU++; | ||
| 375 | } | ||
| 376 | pOUNeighbours[2] = pBackgroundOU - iPicWidthInOU; | ||
| 377 | pVaaBackgroundMbFlag += OU_SIZE_IN_MB * iPicWidthInMb; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | void CBackgroundDetection::BackgroundDetection (vBGDParam* pBgdParam) { | ||
| 382 | // 1st step: foreground/background coarse division | ||
| 383 | ForegroundBackgroundDivision (pBgdParam); | ||
| 384 | |||
| 385 | // 2nd step: foreground dilation and background erosion | ||
| 386 | ForegroundDilationAndBackgroundErosion (pBgdParam); | ||
| 387 | } | ||
| 388 | |||
| 389 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,106 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : BackgroundDetection.h | ||
| 32 | * | ||
| 33 | * \brief : background detection class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/17 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of background detection class | ||
| 38 | * | ||
| 39 | */ | ||
| 40 | |||
| 41 | #ifndef WELSVP_BACKGROUNDDETECTION_H | ||
| 42 | #define WELSVP_BACKGROUNDDETECTION_H | ||
| 43 | |||
| 44 | #include "../common/util.h" | ||
| 45 | #include "../common/memory.h" | ||
| 46 | #include "../common/WelsFrameWork.h" | ||
| 47 | #include "../../interface/IWelsVP.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | typedef struct { | ||
| 52 | int32_t iBackgroundFlag; | ||
| 53 | int32_t iSAD; | ||
| 54 | int32_t iSD; | ||
| 55 | int32_t iMAD; | ||
| 56 | int32_t iMinSubMad; | ||
| 57 | int32_t iMaxDiffSubSd; | ||
| 58 | } SBackgroundOU; | ||
| 59 | |||
| 60 | class CBackgroundDetection : public IStrategy { | ||
| 61 | public: | ||
| 62 | CBackgroundDetection (int32_t iCpuFlag); | ||
| 63 | ~CBackgroundDetection(); | ||
| 64 | |||
| 65 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef); | ||
| 66 | EResult Set (int32_t iType, void* pParam); | ||
| 67 | |||
| 68 | private: | ||
| 69 | struct vBGDParam { | ||
| 70 | uint8_t* pCur[3]; | ||
| 71 | uint8_t* pRef[3]; | ||
| 72 | int32_t iBgdWidth; | ||
| 73 | int32_t iBgdHeight; | ||
| 74 | int32_t iStride[3]; | ||
| 75 | SBackgroundOU* pOU_array; | ||
| 76 | int8_t* pBackgroundMbFlag; | ||
| 77 | SVAACalcResult* pCalcRes; | ||
| 78 | } m_BgdParam; | ||
| 79 | |||
| 80 | int32_t m_iLargestFrameSize; | ||
| 81 | |||
| 82 | private: | ||
| 83 | inline SBackgroundOU* AllocateOUArrayMemory (int32_t iWidth, int32_t iHeight); | ||
| 84 | inline void FreeOUArrayMemory(); | ||
| 85 | inline int32_t CalculateAsdChromaEdge (uint8_t* pOriRef, uint8_t* pOriCur, int32_t iStride); | ||
| 86 | inline bool_t ForegroundDilation23Luma (SBackgroundOU* pBackgroundOU, | ||
| 87 | SBackgroundOU* pOUNeighbours[]); //Foreground_Dilation_2_3_Luma | ||
| 88 | inline bool_t ForegroundDilation23Chroma (int8_t iNeighbourForegroundFlags, int32_t iStartSamplePos, | ||
| 89 | int32_t iPicStrideUV, vBGDParam* pBgdParam);//Foreground_Dilation_2_3_Chroma | ||
| 90 | inline void ForegroundDilation (SBackgroundOU* pBackgroundOU, SBackgroundOU* pOUNeighbours[], vBGDParam* pBgdParam, | ||
| 91 | int32_t iChromaSampleStartPos); | ||
| 92 | inline void BackgroundErosion (SBackgroundOU* pBackgroundOU, SBackgroundOU* pOUNeighbours[]); | ||
| 93 | inline void SetBackgroundMbFlag (int8_t* pBackgroundMbFlag, int32_t iPicWidthInMb, int32_t iBackgroundMbFlag); | ||
| 94 | inline void UpperOUForegroundCheck (SBackgroundOU* pCurOU, int8_t* pBackgroundMbFlag, int32_t iPicWidthInOU, | ||
| 95 | int32_t iPicWidthInMb); | ||
| 96 | |||
| 97 | void GetOUParameters (SVAACalcResult* sVaaCalcInfo, int32_t iMbIndex, int32_t iMbWidth, | ||
| 98 | SBackgroundOU* pBackgroundOU); | ||
| 99 | void ForegroundBackgroundDivision (vBGDParam* pBgdParam); | ||
| 100 | void ForegroundDilationAndBackgroundErosion (vBGDParam* pBgdParam); | ||
| 101 | void BackgroundDetection (vBGDParam* pBgdParam); | ||
| 102 | }; | ||
| 103 | |||
| 104 | WELSVP_NAMESPACE_END | ||
| 105 | |||
| 106 | #endif | ||
| @@ -0,0 +1,301 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "WelsFrameWork.h" | ||
| 34 | #include "cpu.h" | ||
| 35 | #include "../denoise/denoise.h" | ||
| 36 | #include "../downsample/downsample.h" | ||
| 37 | #include "../scenechangedetection/SceneChangeDetection.h" | ||
| 38 | #include "../vaacalc/vaacalculation.h" | ||
| 39 | #include "../backgounddetection/BackgroundDetection.h" | ||
| 40 | #include "../adaptivequantization/AdaptiveQuantization.h" | ||
| 41 | #include "../complexityanalysis/ComplexityAnalysis.h" | ||
| 42 | #include "../imagerotate/imagerotate.h" | ||
| 43 | |||
| 44 | |||
| 45 | /* interface API implement */ | ||
| 46 | |||
| 47 | EResult WELSAPI CreateVpInterface (void** ppCtx, int iVersion) { | ||
| 48 | if (iVersion & 0x8000) | ||
| 49 | return nsWelsVP::CreateSpecificVpInterface ((IWelsVP**)ppCtx); | ||
| 50 | else if (iVersion & 0x7fff) | ||
| 51 | return nsWelsVP::CreateSpecificVpInterface ((IWelsVPc**)ppCtx); | ||
| 52 | else | ||
| 53 | return RET_INVALIDPARAM; | ||
| 54 | } | ||
| 55 | |||
| 56 | EResult WELSAPI DestroyVpInterface (void* pCtx, int iVersion) { | ||
| 57 | if (iVersion & 0x8000) | ||
| 58 | return nsWelsVP::DestroySpecificVpInterface ((IWelsVP*)pCtx); | ||
| 59 | else if (iVersion & 0x7fff) | ||
| 60 | return nsWelsVP::DestroySpecificVpInterface ((IWelsVPc*)pCtx); | ||
| 61 | else | ||
| 62 | return RET_INVALIDPARAM; | ||
| 63 | } | ||
| 64 | |||
| 65 | WELSVP_NAMESPACE_BEGIN | ||
| 66 | |||
| 67 | /////////////////////////////////////////////////////////////////////// | ||
| 68 | |||
| 69 | EResult CreateSpecificVpInterface (IWelsVP** ppCtx) { | ||
| 70 | EResult eReturn = RET_FAILED; | ||
| 71 | |||
| 72 | CVpFrameWork* pFr = new CVpFrameWork (1, eReturn); | ||
| 73 | if (pFr) { | ||
| 74 | *ppCtx = (IWelsVP*)pFr; | ||
| 75 | eReturn = RET_SUCCESS; | ||
| 76 | } | ||
| 77 | |||
| 78 | return eReturn; | ||
| 79 | } | ||
| 80 | |||
| 81 | EResult DestroySpecificVpInterface (IWelsVP* pCtx) { | ||
| 82 | _SafeDelete (pCtx); | ||
| 83 | |||
| 84 | return RET_SUCCESS; | ||
| 85 | } | ||
| 86 | |||
| 87 | /////////////////////////////////////////////////////////////////////////////// | ||
| 88 | |||
| 89 | CVpFrameWork::CVpFrameWork (uint32_t uiThreadsNum, EResult& eReturn) { | ||
| 90 | int32_t iCoreNum = 1; | ||
| 91 | #ifndef X86_ASM | ||
| 92 | uint32_t uiCPUFlag = 0; | ||
| 93 | #else | ||
| 94 | uint32_t uiCPUFlag = WelsCPUFeatureDetect (&iCoreNum); | ||
| 95 | #endif | ||
| 96 | |||
| 97 | for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) { | ||
| 98 | IStrategy* pStrategy = m_pStgChain[i]; | ||
| 99 | pStrategy = CreateStrategy (WelsStaticCast (EMethods, i + 1), uiCPUFlag); | ||
| 100 | m_pStgChain[i] = pStrategy; | ||
| 101 | } | ||
| 102 | |||
| 103 | WelsMutexInit (&m_mutes); | ||
| 104 | |||
| 105 | eReturn = RET_SUCCESS; | ||
| 106 | } | ||
| 107 | |||
| 108 | CVpFrameWork::~CVpFrameWork() { | ||
| 109 | for (int32_t i = 0; i < MAX_STRATEGY_NUM; i++) { | ||
| 110 | if (m_pStgChain[i]) { | ||
| 111 | Uninit (m_pStgChain[i]->m_eMethod); | ||
| 112 | _SafeDelete (m_pStgChain[i]); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | WelsMutexDestroy (&m_mutes); | ||
| 117 | } | ||
| 118 | |||
| 119 | EResult CVpFrameWork::Init (int32_t iType, void* pCfg) { | ||
| 120 | EResult eReturn = RET_SUCCESS; | ||
| 121 | int32_t iCurIdx = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1; | ||
| 122 | |||
| 123 | Uninit (iType); | ||
| 124 | |||
| 125 | WelsMutexLock (&m_mutes); | ||
| 126 | |||
| 127 | IStrategy* pStrategy = m_pStgChain[iCurIdx]; | ||
| 128 | if (pStrategy) | ||
| 129 | eReturn = pStrategy->Init (0, pCfg); | ||
| 130 | |||
| 131 | WelsMutexUnlock (&m_mutes); | ||
| 132 | |||
| 133 | return eReturn; | ||
| 134 | } | ||
| 135 | |||
| 136 | EResult CVpFrameWork::Uninit (int32_t iType) { | ||
| 137 | EResult eReturn = RET_SUCCESS; | ||
| 138 | int32_t iCurIdx = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1; | ||
| 139 | |||
| 140 | WelsMutexLock (&m_mutes); | ||
| 141 | |||
| 142 | IStrategy* pStrategy = m_pStgChain[iCurIdx]; | ||
| 143 | if (pStrategy) | ||
| 144 | eReturn = pStrategy->Uninit (0); | ||
| 145 | |||
| 146 | WelsMutexUnlock (&m_mutes); | ||
| 147 | |||
| 148 | return eReturn; | ||
| 149 | } | ||
| 150 | |||
| 151 | EResult CVpFrameWork::Flush (int32_t iType) { | ||
| 152 | EResult eReturn = RET_SUCCESS; | ||
| 153 | |||
| 154 | return eReturn; | ||
| 155 | } | ||
| 156 | |||
| 157 | EResult CVpFrameWork::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDstPixMap) { | ||
| 158 | EResult eReturn = RET_NOTSUPPORTED; | ||
| 159 | EMethods eMethod = WelsVpGetValidMethod (iType); | ||
| 160 | int32_t iCurIdx = WelsStaticCast (int32_t, eMethod) - 1; | ||
| 161 | SPixMap sSrcPic; | ||
| 162 | SPixMap sDstPic; | ||
| 163 | memset (&sSrcPic, 0, sizeof (sSrcPic)); // confirmed_safe_unsafe_usage | ||
| 164 | memset (&sDstPic, 0, sizeof (sDstPic)); // confirmed_safe_unsafe_usage | ||
| 165 | |||
| 166 | if (pSrcPixMap) sSrcPic = *pSrcPixMap; | ||
| 167 | if (pDstPixMap) sDstPic = *pDstPixMap; | ||
| 168 | if (!CheckValid (eMethod, sSrcPic, sDstPic)) | ||
| 169 | return RET_INVALIDPARAM; | ||
| 170 | |||
| 171 | WelsMutexLock (&m_mutes); | ||
| 172 | |||
| 173 | IStrategy* pStrategy = m_pStgChain[iCurIdx]; | ||
| 174 | if (pStrategy) | ||
| 175 | eReturn = pStrategy->Process (0, &sSrcPic, &sDstPic); | ||
| 176 | |||
| 177 | WelsMutexUnlock (&m_mutes); | ||
| 178 | |||
| 179 | return eReturn; | ||
| 180 | } | ||
| 181 | |||
| 182 | EResult CVpFrameWork::Get (int32_t iType, void* pParam) { | ||
| 183 | EResult eReturn = RET_SUCCESS; | ||
| 184 | int32_t iCurIdx = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1; | ||
| 185 | |||
| 186 | if (!pParam) | ||
| 187 | return RET_INVALIDPARAM; | ||
| 188 | |||
| 189 | WelsMutexLock (&m_mutes); | ||
| 190 | |||
| 191 | IStrategy* pStrategy = m_pStgChain[iCurIdx]; | ||
| 192 | if (pStrategy) | ||
| 193 | eReturn = pStrategy->Get (0, pParam); | ||
| 194 | |||
| 195 | WelsMutexUnlock (&m_mutes); | ||
| 196 | |||
| 197 | return eReturn; | ||
| 198 | } | ||
| 199 | |||
| 200 | EResult CVpFrameWork::Set (int32_t iType, void* pParam) { | ||
| 201 | EResult eReturn = RET_SUCCESS; | ||
| 202 | int32_t iCurIdx = WelsStaticCast (int32_t, WelsVpGetValidMethod (iType)) - 1; | ||
| 203 | |||
| 204 | if (!pParam) | ||
| 205 | return RET_INVALIDPARAM; | ||
| 206 | |||
| 207 | WelsMutexLock (&m_mutes); | ||
| 208 | |||
| 209 | IStrategy* pStrategy = m_pStgChain[iCurIdx]; | ||
| 210 | if (pStrategy) | ||
| 211 | eReturn = pStrategy->Set (0, pParam); | ||
| 212 | |||
| 213 | WelsMutexUnlock (&m_mutes); | ||
| 214 | |||
| 215 | return eReturn; | ||
| 216 | } | ||
| 217 | |||
| 218 | EResult CVpFrameWork::SpecialFeature (int32_t iType, void* pIn, void* pOut) { | ||
| 219 | EResult eReturn = RET_SUCCESS; | ||
| 220 | |||
| 221 | return eReturn; | ||
| 222 | } | ||
| 223 | |||
| 224 | bool_t CVpFrameWork::CheckValid (EMethods eMethod, SPixMap& pSrcPixMap, SPixMap& pDstPixMap) { | ||
| 225 | bool_t eReturn = FALSE; | ||
| 226 | |||
| 227 | if (eMethod == METHOD_NULL) | ||
| 228 | goto exit; | ||
| 229 | |||
| 230 | if (eMethod != METHOD_COLORSPACE_CONVERT) { | ||
| 231 | if (pSrcPixMap.pPixel[0]) { | ||
| 232 | if (pSrcPixMap.eFormat != VIDEO_FORMAT_I420 && pSrcPixMap.eFormat != VIDEO_FORMAT_YV12) | ||
| 233 | goto exit; | ||
| 234 | } | ||
| 235 | if (pSrcPixMap.pPixel[0] && pDstPixMap.pPixel[0]) { | ||
| 236 | if (pDstPixMap.eFormat != pSrcPixMap.eFormat) | ||
| 237 | goto exit; | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | if (pSrcPixMap.pPixel[0]) { | ||
| 242 | if (pSrcPixMap.sRect.iRectWidth <= 0 || pSrcPixMap.sRect.iRectWidth > MAX_WIDTH || pSrcPixMap.sRect.iRectHeight <= 0 | ||
| 243 | || pSrcPixMap.sRect.iRectHeight > MAX_HEIGHT) | ||
| 244 | goto exit; | ||
| 245 | if (pSrcPixMap.sRect.iRectTop >= pSrcPixMap.sRect.iRectHeight | ||
| 246 | || pSrcPixMap.sRect.iRectLeft >= pSrcPixMap.sRect.iRectWidth || pSrcPixMap.sRect.iRectWidth > pSrcPixMap.iStride[0]) | ||
| 247 | goto exit; | ||
| 248 | } | ||
| 249 | if (pDstPixMap.pPixel[0]) { | ||
| 250 | if (pDstPixMap.sRect.iRectWidth <= 0 || pDstPixMap.sRect.iRectWidth > MAX_WIDTH || pDstPixMap.sRect.iRectHeight <= 0 | ||
| 251 | || pDstPixMap.sRect.iRectHeight > MAX_HEIGHT) | ||
| 252 | goto exit; | ||
| 253 | if (pDstPixMap.sRect.iRectTop >= pDstPixMap.sRect.iRectHeight | ||
| 254 | || pDstPixMap.sRect.iRectLeft >= pDstPixMap.sRect.iRectWidth || pDstPixMap.sRect.iRectWidth > pDstPixMap.iStride[0]) | ||
| 255 | goto exit; | ||
| 256 | } | ||
| 257 | eReturn = TRUE; | ||
| 258 | |||
| 259 | exit: | ||
| 260 | return eReturn; | ||
| 261 | } | ||
| 262 | |||
| 263 | IStrategy* CVpFrameWork::CreateStrategy (EMethods m_eMethod, int32_t iCpuFlag) { | ||
| 264 | IStrategy* pStrategy = NULL; | ||
| 265 | |||
| 266 | switch (m_eMethod) { | ||
| 267 | case METHOD_COLORSPACE_CONVERT: | ||
| 268 | //not support yet | ||
| 269 | break; | ||
| 270 | case METHOD_DENOISE: | ||
| 271 | pStrategy = WelsDynamicCast (IStrategy*, new CDenoiser (iCpuFlag)); | ||
| 272 | break; | ||
| 273 | case METHOD_SCENE_CHANGE_DETECTION: | ||
| 274 | pStrategy = WelsDynamicCast (IStrategy*, new CSceneChangeDetection (iCpuFlag)); | ||
| 275 | break; | ||
| 276 | case METHOD_DOWNSAMPLE: | ||
| 277 | pStrategy = WelsDynamicCast (IStrategy*, new CDownsampling (iCpuFlag)); | ||
| 278 | break; | ||
| 279 | case METHOD_VAA_STATISTICS: | ||
| 280 | pStrategy = WelsDynamicCast (IStrategy*, new CVAACalculation (iCpuFlag)); | ||
| 281 | break; | ||
| 282 | case METHOD_BACKGROUND_DETECTION: | ||
| 283 | pStrategy = WelsDynamicCast (IStrategy*, new CBackgroundDetection (iCpuFlag)); | ||
| 284 | break; | ||
| 285 | case METHOD_ADAPTIVE_QUANT: | ||
| 286 | pStrategy = WelsDynamicCast (IStrategy*, new CAdaptiveQuantization (iCpuFlag)); | ||
| 287 | break; | ||
| 288 | case METHOD_COMPLEXITY_ANALYSIS: | ||
| 289 | pStrategy = WelsDynamicCast (IStrategy*, new CComplexityAnalysis (iCpuFlag)); | ||
| 290 | break; | ||
| 291 | case METHOD_IMAGE_ROTATE: | ||
| 292 | pStrategy = WelsDynamicCast (IStrategy*, new CImageRotating (iCpuFlag)); | ||
| 293 | break; | ||
| 294 | default: | ||
| 295 | break; | ||
| 296 | } | ||
| 297 | |||
| 298 | return pStrategy; | ||
| 299 | } | ||
| 300 | |||
| 301 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,130 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : WelsFrameWork.h | ||
| 32 | * | ||
| 33 | * \brief : framework of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/01/04 | ||
| 36 | * | ||
| 37 | * \description : | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_WELSFRAMEWORK_H | ||
| 43 | #define WELSVP_WELSFRAMEWORK_H | ||
| 44 | |||
| 45 | #include "../../interface/IWelsVP.h" | ||
| 46 | #include "util.h" | ||
| 47 | #include "thread.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | EResult CreateSpecificVpInterface (IWelsVP** ppCtx); | ||
| 52 | EResult DestroySpecificVpInterface (IWelsVP* pCtx); | ||
| 53 | |||
| 54 | EResult CreateSpecificVpInterface (IWelsVPc** ppCtx); | ||
| 55 | EResult DestroySpecificVpInterface (IWelsVPc* pCtx); | ||
| 56 | |||
| 57 | #define MAX_STRATEGY_NUM (METHOD_MASK - 1) | ||
| 58 | |||
| 59 | class IStrategy : public IWelsVP { | ||
| 60 | public: | ||
| 61 | IStrategy() { | ||
| 62 | m_eMethod = METHOD_NULL; | ||
| 63 | m_eFormat = VIDEO_FORMAT_I420; | ||
| 64 | m_iIndex = 0; | ||
| 65 | m_bInit = FALSE; | ||
| 66 | }; | ||
| 67 | |||
| 68 | virtual ~IStrategy() {} | ||
| 69 | |||
| 70 | public: | ||
| 71 | virtual EResult Init (int32_t iType, void* pCfg) { | ||
| 72 | return RET_SUCCESS; | ||
| 73 | } | ||
| 74 | virtual EResult Uninit (int32_t iType) { | ||
| 75 | return RET_SUCCESS; | ||
| 76 | } | ||
| 77 | virtual EResult Flush (int32_t iType) { | ||
| 78 | return RET_SUCCESS; | ||
| 79 | } | ||
| 80 | virtual EResult Get (int32_t iType, void* pParam) { | ||
| 81 | return RET_SUCCESS; | ||
| 82 | } | ||
| 83 | virtual EResult Set (int32_t iType, void* pParam) { | ||
| 84 | return RET_SUCCESS; | ||
| 85 | } | ||
| 86 | virtual EResult SpecialFeature (int32_t iType, void* pIn, void* pOut) { | ||
| 87 | return RET_SUCCESS; | ||
| 88 | } | ||
| 89 | virtual EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pDst) = 0; | ||
| 90 | |||
| 91 | public: | ||
| 92 | EMethods m_eMethod; | ||
| 93 | EVideoFormat m_eFormat; | ||
| 94 | int32_t m_iIndex; | ||
| 95 | bool_t m_bInit; | ||
| 96 | }; | ||
| 97 | |||
| 98 | class CVpFrameWork : public IWelsVP { | ||
| 99 | public: | ||
| 100 | CVpFrameWork (uint32_t uiThreadsNum, EResult& ret); | ||
| 101 | ~CVpFrameWork(); | ||
| 102 | |||
| 103 | public: | ||
| 104 | EResult Init (int32_t iType, void* pCfg); | ||
| 105 | |||
| 106 | EResult Uninit (int32_t iType); | ||
| 107 | |||
| 108 | EResult Flush (int32_t iType); | ||
| 109 | |||
| 110 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pDst); | ||
| 111 | |||
| 112 | EResult Get (int32_t iType, void* pParam); | ||
| 113 | |||
| 114 | EResult Set (int32_t iType, void* pParam); | ||
| 115 | |||
| 116 | EResult SpecialFeature (int32_t iType, void* pIn, void* pOut); | ||
| 117 | |||
| 118 | private: | ||
| 119 | bool_t CheckValid (EMethods eMethod, SPixMap& sSrc, SPixMap& sDst); | ||
| 120 | IStrategy* CreateStrategy (EMethods eMethod, int32_t iCpuFlag); | ||
| 121 | |||
| 122 | private: | ||
| 123 | IStrategy* m_pStgChain[MAX_STRATEGY_NUM]; | ||
| 124 | |||
| 125 | WELS_MUTEX m_mutes; | ||
| 126 | }; | ||
| 127 | |||
| 128 | WELSVP_NAMESPACE_END | ||
| 129 | |||
| 130 | #endif | ||
| @@ -0,0 +1,96 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "WelsFrameWork.h" | ||
| 34 | |||
| 35 | /////////////////////////////////////////////////////////////////////// | ||
| 36 | |||
| 37 | WELSVP_NAMESPACE_BEGIN | ||
| 38 | |||
| 39 | EResult Init (void* pCtx, int32_t iType, void* pCfg) { | ||
| 40 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Init (iType, pCfg) : RET_INVALIDPARAM; | ||
| 41 | } | ||
| 42 | EResult Uninit (void* pCtx, int32_t iType) { | ||
| 43 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Uninit (iType) : RET_INVALIDPARAM; | ||
| 44 | } | ||
| 45 | EResult Flush (void* pCtx, int32_t iType) { | ||
| 46 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Flush (iType) : RET_INVALIDPARAM; | ||
| 47 | } | ||
| 48 | EResult Process (void* pCtx, int32_t iType, SPixMap* pSrc, SPixMap* dst) { | ||
| 49 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Process (iType, pSrc, dst) : RET_INVALIDPARAM; | ||
| 50 | } | ||
| 51 | EResult Get (void* pCtx, int32_t iType, void* pParam) { | ||
| 52 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Get (iType, pParam) : RET_INVALIDPARAM; | ||
| 53 | } | ||
| 54 | EResult Set (void* pCtx, int32_t iType, void* pParam) { | ||
| 55 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Set (iType, pParam) : RET_INVALIDPARAM; | ||
| 56 | } | ||
| 57 | EResult SpecialFeature (void* pCtx, int32_t iType, void* pIn, void* pOut) { | ||
| 58 | return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->SpecialFeature (iType, pIn, pOut) : RET_INVALIDPARAM; | ||
| 59 | } | ||
| 60 | |||
| 61 | /////////////////////////////////////////////////////////////////////////////// | ||
| 62 | |||
| 63 | EResult CreateSpecificVpInterface (IWelsVPc** pCtx) { | ||
| 64 | EResult ret = RET_FAILED; | ||
| 65 | IWelsVP* pWelsVP = NULL; | ||
| 66 | |||
| 67 | ret = CreateSpecificVpInterface (&pWelsVP); | ||
| 68 | if (ret == RET_SUCCESS) { | ||
| 69 | IWelsVPc* pVPc = new IWelsVPc; | ||
| 70 | if (pVPc) { | ||
| 71 | pVPc->Init = Init; | ||
| 72 | pVPc->Uninit = Uninit; | ||
| 73 | pVPc->Flush = Flush; | ||
| 74 | pVPc->Process = Process; | ||
| 75 | pVPc->Get = Get; | ||
| 76 | pVPc->Set = Set; | ||
| 77 | pVPc->SpecialFeature = SpecialFeature; | ||
| 78 | pVPc->pCtx = WelsStaticCast (void*, pWelsVP); | ||
| 79 | *pCtx = pVPc; | ||
| 80 | } else | ||
| 81 | ret = RET_OUTOFMEMORY; | ||
| 82 | } | ||
| 83 | |||
| 84 | return ret; | ||
| 85 | } | ||
| 86 | |||
| 87 | EResult DestroySpecificVpInterface (IWelsVPc* pCtx) { | ||
| 88 | if (pCtx) { | ||
| 89 | DestroySpecificVpInterface (WelsStaticCast (IWelsVP*, pCtx->pCtx)); | ||
| 90 | _SafeDelete (pCtx); | ||
| 91 | } | ||
| 92 | |||
| 93 | return RET_SUCCESS; | ||
| 94 | } | ||
| 95 | |||
| 96 | WELSVP_NAMESPACE_END | ||
Binary file not shown.
| @@ -0,0 +1,36 @@ | |||
| 1 | ;*! | ||
| 2 | ;* \copy | ||
| 3 | ;* Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | ;* All rights reserved. | ||
| 5 | ;* | ||
| 6 | ;* Redistribution and use in source and binary forms, with or without | ||
| 7 | ;* modification, are permitted provided that the following conditions | ||
| 8 | ;* are met: | ||
| 9 | ;* | ||
| 10 | ;* * Redistributions of source code must retain the above copyright | ||
| 11 | ;* notice, this list of conditions and the following disclaimer. | ||
| 12 | ;* | ||
| 13 | ;* * Redistributions in binary form must reproduce the above copyright | ||
| 14 | ;* notice, this list of conditions and the following disclaimer in | ||
| 15 | ;* the documentation and/or other materials provided with the | ||
| 16 | ;* distribution. | ||
| 17 | ;* | ||
| 18 | ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | ;* POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | ;* | ||
| 31 | ;* | ||
| 32 | |||
| 33 | LIBRARY welsvp.dll | ||
| 34 | EXPORTS | ||
| 35 | CreateVpInterface PRIVATE | ||
| 36 | DestroyVpInterface PRIVATE | ||
| @@ -0,0 +1,115 @@ | |||
| 1 | // Microsoft Visual C++ generated resource script. | ||
| 2 | // | ||
| 3 | #include "resource.h" | ||
| 4 | |||
| 5 | #define APSTUDIO_READONLY_SYMBOLS | ||
| 6 | ///////////////////////////////////////////////////////////////////////////// | ||
| 7 | // | ||
| 8 | // Generated from the TEXTINCLUDE 2 resource. | ||
| 9 | // | ||
| 10 | #include "windows.h" | ||
| 11 | |||
| 12 | ///////////////////////////////////////////////////////////////////////////// | ||
| 13 | #undef APSTUDIO_READONLY_SYMBOLS | ||
| 14 | |||
| 15 | ///////////////////////////////////////////////////////////////////////////// | ||
| 16 | // Chinese (P.R.C.) resources | ||
| 17 | |||
| 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) | ||
| 19 | #ifdef _WIN32 | ||
| 20 | LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED | ||
| 21 | #pragma code_page(936) | ||
| 22 | #endif //_WIN32 | ||
| 23 | |||
| 24 | #ifdef APSTUDIO_INVOKED | ||
| 25 | ///////////////////////////////////////////////////////////////////////////// | ||
| 26 | // | ||
| 27 | // TEXTINCLUDE | ||
| 28 | // | ||
| 29 | |||
| 30 | 1 TEXTINCLUDE | ||
| 31 | BEGIN | ||
| 32 | "resource.h\0" | ||
| 33 | END | ||
| 34 | |||
| 35 | 2 TEXTINCLUDE | ||
| 36 | BEGIN | ||
| 37 | "#include ""windows.h""\r\n" | ||
| 38 | "\0" | ||
| 39 | END | ||
| 40 | |||
| 41 | 3 TEXTINCLUDE | ||
| 42 | BEGIN | ||
| 43 | "\r\n" | ||
| 44 | "\0" | ||
| 45 | END | ||
| 46 | |||
| 47 | #endif // APSTUDIO_INVOKED | ||
| 48 | |||
| 49 | #endif // Chinese (P.R.C.) resources | ||
| 50 | ///////////////////////////////////////////////////////////////////////////// | ||
| 51 | |||
| 52 | |||
| 53 | ///////////////////////////////////////////////////////////////////////////// | ||
| 54 | // English (U.S.) resources | ||
| 55 | |||
| 56 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) | ||
| 57 | #ifdef _WIN32 | ||
| 58 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US | ||
| 59 | #pragma code_page(1252) | ||
| 60 | #endif //_WIN32 | ||
| 61 | |||
| 62 | ///////////////////////////////////////////////////////////////////////////// | ||
| 63 | // | ||
| 64 | // Version | ||
| 65 | // | ||
| 66 | |||
| 67 | VS_VERSION_INFO VERSIONINFO | ||
| 68 | FILEVERSION 0,0,0,0 | ||
| 69 | PRODUCTVERSION 0,0,0,0 | ||
| 70 | FILEFLAGSMASK 0x3fL | ||
| 71 | #ifdef _DEBUG | ||
| 72 | FILEFLAGS 0x1L | ||
| 73 | #else | ||
| 74 | FILEFLAGS 0x0L | ||
| 75 | #endif | ||
| 76 | FILEOS 0x40004L | ||
| 77 | FILETYPE 0x2L | ||
| 78 | FILESUBTYPE 0x0L | ||
| 79 | BEGIN | ||
| 80 | BLOCK "StringFileInfo" | ||
| 81 | BEGIN | ||
| 82 | BLOCK "040904b0" | ||
| 83 | BEGIN | ||
| 84 | VALUE "Comments", "Cisco OpenH264 video preprocessing" | ||
| 85 | VALUE "CompanyName", "Cisco Systems" | ||
| 86 | VALUE "FileDescription", "Cisco OpenH264 video preprocessing" | ||
| 87 | VALUE "FileVersion", "0, 0, 0, 0" | ||
| 88 | VALUE "InternalName", "welsvp.dll" | ||
| 89 | VALUE "LegalCopyright", "� 2011-2015 Cisco and/or its affiliates. All rights reserved." | ||
| 90 | VALUE "OriginalFilename", "welsvp.dll" | ||
| 91 | VALUE "ProductName", "Cisco OpenH264 video preprocessing" | ||
| 92 | VALUE "ProductVersion", "0, 0, 0, 0" | ||
| 93 | END | ||
| 94 | END | ||
| 95 | BLOCK "VarFileInfo" | ||
| 96 | BEGIN | ||
| 97 | VALUE "Translation", 0x409, 1200 | ||
| 98 | END | ||
| 99 | END | ||
| 100 | |||
| 101 | #endif // English (U.S.) resources | ||
| 102 | ///////////////////////////////////////////////////////////////////////////// | ||
| 103 | |||
| 104 | |||
| 105 | |||
| 106 | #ifndef APSTUDIO_INVOKED | ||
| 107 | ///////////////////////////////////////////////////////////////////////////// | ||
| 108 | // | ||
| 109 | // Generated from the TEXTINCLUDE 3 resource. | ||
| 110 | // | ||
| 111 | |||
| 112 | |||
| 113 | ///////////////////////////////////////////////////////////////////////////// | ||
| 114 | #endif // not APSTUDIO_INVOKED | ||
| 115 | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file cpu.c | ||
| 32 | * | ||
| 33 | * \brief CPU compatibility detection | ||
| 34 | * | ||
| 35 | * \date 04/29/2009 Created | ||
| 36 | * | ||
| 37 | ************************************************************************************* | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include "util.h" | ||
| 41 | #include "cpu.h" | ||
| 42 | |||
| 43 | WELSVP_NAMESPACE_BEGIN | ||
| 44 | |||
| 45 | #define CPU_Vender_AMD "AuthenticAMD" | ||
| 46 | #define CPU_Vender_INTEL "GenuineIntel" | ||
| 47 | #define CPU_Vender_CYRIX "CyrixInstead" | ||
| 48 | |||
| 49 | |||
| 50 | #if defined(X86_ASM) | ||
| 51 | |||
| 52 | uint32_t WelsCPUFeatureDetect (int32_t* pNumberOfLogicProcessors) { | ||
| 53 | uint32_t uiCPU = 0; | ||
| 54 | uint32_t uiFeatureA = 0, uiFeatureB = 0, uiFeatureC = 0, uiFeatureD = 0; | ||
| 55 | int32_t CacheLineSize = 0; | ||
| 56 | int8_t chVenderName[16] = { 0 }; | ||
| 57 | |||
| 58 | if (!WelsCPUIdVerify()) { | ||
| 59 | /* cpuid is not supported in cpu */ | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | WelsCPUId (0, &uiFeatureA, (uint32_t*)&chVenderName[0], (uint32_t*)&chVenderName[8], (uint32_t*)&chVenderName[4]); | ||
| 64 | if (uiFeatureA == 0) { | ||
| 65 | /* maximum input value for basic cpuid information */ | ||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | ||
| 70 | if ((uiFeatureD & 0x00800000) == 0) { | ||
| 71 | /* Basic MMX technology is not support in cpu, mean nothing for us so return here */ | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | uiCPU = WELS_CPU_MMX; | ||
| 76 | if (uiFeatureD & 0x02000000) { | ||
| 77 | /* SSE technology is identical to AMD MMX extensions */ | ||
| 78 | uiCPU |= WELS_CPU_MMXEXT | WELS_CPU_SSE; | ||
| 79 | } | ||
| 80 | if (uiFeatureD & 0x04000000) { | ||
| 81 | /* SSE2 support here */ | ||
| 82 | uiCPU |= WELS_CPU_SSE2; | ||
| 83 | } | ||
| 84 | if (uiFeatureD & 0x00000001) { | ||
| 85 | /* x87 FPU on-chip checking */ | ||
| 86 | uiCPU |= WELS_CPU_FPU; | ||
| 87 | } | ||
| 88 | if (uiFeatureD & 0x00008000) { | ||
| 89 | /* CMOV instruction checking */ | ||
| 90 | uiCPU |= WELS_CPU_CMOV; | ||
| 91 | } | ||
| 92 | if (!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) { // confirmed_safe_unsafe_usage | ||
| 93 | if (uiFeatureD & 0x10000000) { | ||
| 94 | /* Multi-Threading checking: contains of multiple logic processors */ | ||
| 95 | uiCPU |= WELS_CPU_HTT; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | if (uiFeatureC & 0x00000001) { | ||
| 100 | /* SSE3 support here */ | ||
| 101 | uiCPU |= WELS_CPU_SSE3; | ||
| 102 | } | ||
| 103 | if (uiFeatureC & 0x00000200) { | ||
| 104 | /* SSSE3 support here */ | ||
| 105 | uiCPU |= WELS_CPU_SSSE3; | ||
| 106 | } | ||
| 107 | if (uiFeatureC & 0x00080000) { | ||
| 108 | /* SSE4.1 support here, 45nm Penryn processor */ | ||
| 109 | uiCPU |= WELS_CPU_SSE41; | ||
| 110 | } | ||
| 111 | if (uiFeatureC & 0x00100000) { | ||
| 112 | /* SSE4.2 support here, next generation Nehalem processor */ | ||
| 113 | uiCPU |= WELS_CPU_SSE42; | ||
| 114 | } | ||
| 115 | if (WelsCPUSupportAVX (uiFeatureA, uiFeatureC)) { // | ||
| 116 | /* AVX supported */ | ||
| 117 | uiCPU |= WELS_CPU_AVX; | ||
| 118 | } | ||
| 119 | if (WelsCPUSupportFMA (uiFeatureA, uiFeatureC)) { // | ||
| 120 | /* AVX FMA supported */ | ||
| 121 | uiCPU |= WELS_CPU_FMA; | ||
| 122 | } | ||
| 123 | if (uiFeatureC & 0x02000000) { | ||
| 124 | /* AES checking */ | ||
| 125 | uiCPU |= WELS_CPU_AES; | ||
| 126 | } | ||
| 127 | if (uiFeatureC & 0x00400000) { | ||
| 128 | /* MOVBE checking */ | ||
| 129 | uiCPU |= WELS_CPU_MOVBE; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (pNumberOfLogicProcessors != NULL) { | ||
| 133 | // HTT enabled on chip | ||
| 134 | *pNumberOfLogicProcessors = (uiFeatureB & 0x00ff0000) >> 16; // feature bits: 23-16 on returned EBX | ||
| 135 | } | ||
| 136 | |||
| 137 | WelsCPUId (0x80000000, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | ||
| 138 | |||
| 139 | if ((!strcmp ((const str_t*)chVenderName, CPU_Vender_AMD)) | ||
| 140 | && (uiFeatureA >= 0x80000001)) { // confirmed_safe_unsafe_usage | ||
| 141 | WelsCPUId (0x80000001, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | ||
| 142 | if (uiFeatureD & 0x00400000) { | ||
| 143 | uiCPU |= WELS_CPU_MMXEXT; | ||
| 144 | } | ||
| 145 | if (uiFeatureD & 0x80000000) { | ||
| 146 | uiCPU |= WELS_CPU_3DNOW; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | if (!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) { // confirmed_safe_unsafe_usage | ||
| 151 | int32_t family, model; | ||
| 152 | |||
| 153 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | ||
| 154 | family = ((uiFeatureA >> 8) & 0xf) + ((uiFeatureA >> 20) & 0xff); | ||
| 155 | model = ((uiFeatureA >> 4) & 0xf) + ((uiFeatureA >> 12) & 0xf0); | ||
| 156 | |||
| 157 | if ((family == 6) && (model == 9 || model == 13 || model == 14)) { | ||
| 158 | uiCPU &= ~ (WELS_CPU_SSE2 | WELS_CPU_SSE3); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | // get cache line size | ||
| 163 | if ((!strcmp ((const str_t*)chVenderName, CPU_Vender_INTEL)) | ||
| 164 | || ! (strcmp ((const str_t*)chVenderName, CPU_Vender_CYRIX))) { // confirmed_safe_unsafe_usage | ||
| 165 | WelsCPUId (1, &uiFeatureA, &uiFeatureB, &uiFeatureC, &uiFeatureD); | ||
| 166 | |||
| 167 | CacheLineSize = (uiFeatureB & 0xff00) >> | ||
| 168 | 5; // ((clflush_line_size >> 8) << 3), CLFLUSH_line_size * 8 = CacheLineSize_in_byte | ||
| 169 | |||
| 170 | if (CacheLineSize == 128) { | ||
| 171 | uiCPU |= WELS_CPU_CACHELINE_128; | ||
| 172 | } else if (CacheLineSize == 64) { | ||
| 173 | uiCPU |= WELS_CPU_CACHELINE_64; | ||
| 174 | } else if (CacheLineSize == 32) { | ||
| 175 | uiCPU |= WELS_CPU_CACHELINE_32; | ||
| 176 | } else if (CacheLineSize == 16) { | ||
| 177 | uiCPU |= WELS_CPU_CACHELINE_16; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | return uiCPU; | ||
| 182 | } | ||
| 183 | |||
| 184 | |||
| 185 | void WelsCPURestore (const uint32_t kuiCPU) { | ||
| 186 | if (kuiCPU & (WELS_CPU_MMX | WELS_CPU_MMXEXT | WELS_CPU_3DNOW | WELS_CPU_3DNOWEXT)) { | ||
| 187 | WelsEmms(); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | #endif | ||
| 192 | |||
| 193 | |||
| 194 | WELSVP_NAMESPACE_END | ||
| 195 | |||
| 196 | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file cpu.h | ||
| 32 | * | ||
| 33 | * \brief CPU feature compatibility detection | ||
| 34 | * | ||
| 35 | * \date 04/29/2009 Created | ||
| 36 | * | ||
| 37 | ************************************************************************************* | ||
| 38 | */ | ||
| 39 | |||
| 40 | #ifndef WELSVP_CPU_H | ||
| 41 | #define WELSVP_CPU_H | ||
| 42 | |||
| 43 | #include "typedef.h" | ||
| 44 | |||
| 45 | WELSVP_NAMESPACE_BEGIN | ||
| 46 | |||
| 47 | /* | ||
| 48 | * WELS CPU feature flags | ||
| 49 | */ | ||
| 50 | #define WELS_CPU_MMX 0x00000001 /* mmx */ | ||
| 51 | #define WELS_CPU_MMXEXT 0x00000002 /* mmx-ext*/ | ||
| 52 | #define WELS_CPU_SSE 0x00000004 /* sse */ | ||
| 53 | #define WELS_CPU_SSE2 0x00000008 /* sse 2 */ | ||
| 54 | #define WELS_CPU_SSE3 0x00000010 /* sse 3 */ | ||
| 55 | #define WELS_CPU_SSE41 0x00000020 /* sse 4.1 */ | ||
| 56 | #define WELS_CPU_3DNOW 0x00000040 /* 3dnow! */ | ||
| 57 | #define WELS_CPU_3DNOWEXT 0x00000080 /* 3dnow! ext */ | ||
| 58 | #define WELS_CPU_ALTIVEC 0x00000100 /* altivec */ | ||
| 59 | #define WELS_CPU_SSSE3 0x00000200 /* ssse3 */ | ||
| 60 | #define WELS_CPU_SSE42 0x00000400 /* sse 4.2 */ | ||
| 61 | |||
| 62 | /* CPU features application extensive */ | ||
| 63 | #define WELS_CPU_AVX 0x00000800 /* Advanced Vector eXtentions */ | ||
| 64 | #define WELS_CPU_FPU 0x00001000 /* x87-FPU on chip */ | ||
| 65 | #define WELS_CPU_HTT 0x00002000 /* Hyper-Threading Technology (HTT), Multi-threading enabled feature: | ||
| 66 | physical processor package is capable of supporting more than one logic processor | ||
| 67 | */ | ||
| 68 | #define WELS_CPU_CMOV 0x00004000 /* Conditional Move Instructions, | ||
| 69 | also if x87-FPU is present at indicated by the CPUID.FPU feature bit, then FCOMI and FCMOV are supported | ||
| 70 | */ | ||
| 71 | #define WELS_CPU_MOVBE 0x00008000 /* MOVBE instruction */ | ||
| 72 | #define WELS_CPU_AES 0x00010000 /* AES instruction extensions */ | ||
| 73 | #define WELS_CPU_FMA 0x00020000 /* AVX VEX FMA instruction sets */ | ||
| 74 | |||
| 75 | #define WELS_CPU_CACHELINE_16 0x10000000 /* CacheLine Size 16 */ | ||
| 76 | #define WELS_CPU_CACHELINE_32 0x20000000 /* CacheLine Size 32 */ | ||
| 77 | #define WELS_CPU_CACHELINE_64 0x40000000 /* CacheLine Size 64 */ | ||
| 78 | #define WELS_CPU_CACHELINE_128 0x80000000 /* CacheLine Size 128 */ | ||
| 79 | |||
| 80 | /* | ||
| 81 | * Interfaces for CPU core feature detection as below | ||
| 82 | */ | ||
| 83 | |||
| 84 | #ifdef X86_ASM | ||
| 85 | WELSVP_EXTERN_C_BEGIN | ||
| 86 | |||
| 87 | int32_t WelsCPUIdVerify(); | ||
| 88 | |||
| 89 | void WelsCPUId (uint32_t uiIndex, uint32_t* pFeatureA, uint32_t* pFeatureB, uint32_t* pFeatureC, uint32_t* pFeatureD); | ||
| 90 | int32_t WelsCPUSupportAVX (uint32_t eax, uint32_t ecx); | ||
| 91 | int32_t WelsCPUSupportFMA (uint32_t eax, uint32_t ecx); | ||
| 92 | |||
| 93 | void WelsEmms(); | ||
| 94 | |||
| 95 | WELSVP_EXTERN_C_END | ||
| 96 | #endif | ||
| 97 | |||
| 98 | uint32_t WelsCPUFeatureDetect (int32_t* pNumberOfLogicProcessors); | ||
| 99 | |||
| 100 | WELSVP_NAMESPACE_END | ||
| 101 | |||
| 102 | #endif | ||
| @@ -0,0 +1,117 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "memory.h" | ||
| 34 | |||
| 35 | WELSVP_NAMESPACE_BEGIN | ||
| 36 | ///////////////////////////////////////////////////////////////////////////////// | ||
| 37 | |||
| 38 | void* WelsMalloc (const uint32_t kuiSize, str_t* pTag) { | ||
| 39 | const int32_t kiSizeVoidPointer = sizeof (void**); | ||
| 40 | const int32_t kiSizeInt32 = sizeof (int32_t); | ||
| 41 | const int32_t kiAlignedBytes = ALIGNBYTES - 1; | ||
| 42 | |||
| 43 | uint8_t* pBuf = (uint8_t*) ::malloc (kuiSize + kiAlignedBytes + kiSizeVoidPointer + kiSizeInt32); | ||
| 44 | uint8_t* pAlignedBuf = NULL; | ||
| 45 | |||
| 46 | if (NULL == pBuf) | ||
| 47 | return NULL; | ||
| 48 | |||
| 49 | // to fill zero values | ||
| 50 | WelsMemset (pBuf, 0, kuiSize + kiAlignedBytes + kiSizeVoidPointer + kiSizeInt32); | ||
| 51 | |||
| 52 | pAlignedBuf = pBuf + kiAlignedBytes + kiSizeVoidPointer + kiSizeInt32; | ||
| 53 | pAlignedBuf -= WelsCastFromPointer (pAlignedBuf) & kiAlignedBytes; | ||
| 54 | * ((void**) (pAlignedBuf - kiSizeVoidPointer)) = pBuf; | ||
| 55 | * ((int32_t*) (pAlignedBuf - (kiSizeVoidPointer + kiSizeInt32))) = kuiSize; | ||
| 56 | |||
| 57 | return (pAlignedBuf); | ||
| 58 | } | ||
| 59 | |||
| 60 | ///////////////////////////////////////////////////////////////////////////// | ||
| 61 | |||
| 62 | void WelsFree (void* pPointer, str_t* pTag) { | ||
| 63 | if (pPointer) { | ||
| 64 | ::free (* (((void**) pPointer) - 1)); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | ///////////////////////////////////////////////////////////////////////////// | ||
| 69 | |||
| 70 | void* InternalReallocate (void* pPointer, const uint32_t kuiSize, str_t* pTag) { | ||
| 71 | uint32_t iOldSize = 0; | ||
| 72 | uint8_t* pNew = NULL; | ||
| 73 | if (pPointer != NULL) | ||
| 74 | iOldSize = * ((int32_t*) ((uint8_t*) pPointer - sizeof (void**) - sizeof (int32_t))); | ||
| 75 | else | ||
| 76 | return WelsMalloc (kuiSize, pTag); | ||
| 77 | |||
| 78 | pNew = (uint8_t*)WelsMalloc (kuiSize, pTag); | ||
| 79 | if (0 == pNew) { | ||
| 80 | if (iOldSize > 0 && kuiSize > 0 && iOldSize >= kuiSize) | ||
| 81 | return (pPointer); | ||
| 82 | return 0; | ||
| 83 | } else if (iOldSize > 0 && kuiSize > 0) | ||
| 84 | memcpy (pNew, pPointer, (iOldSize < kuiSize) ? iOldSize : kuiSize); | ||
| 85 | else | ||
| 86 | return 0; | ||
| 87 | |||
| 88 | WelsFree (pPointer, pTag); | ||
| 89 | return (pNew); | ||
| 90 | } | ||
| 91 | |||
| 92 | ///////////////////////////////////////////////////////////////////////////// | ||
| 93 | |||
| 94 | void* WelsRealloc (void* pPointer, uint32_t* pRealSize, const uint32_t kuiSize, str_t* pTag) { | ||
| 95 | const uint32_t kuiOldSize = *pRealSize; | ||
| 96 | uint32_t kuiNewSize = 0; | ||
| 97 | void* pLocalPointer = NULL; | ||
| 98 | if (kuiOldSize >= kuiSize) // large enough of original block, so do nothing | ||
| 99 | return (pPointer); | ||
| 100 | |||
| 101 | // new request | ||
| 102 | kuiNewSize = kuiSize + 15; | ||
| 103 | kuiNewSize -= (kuiNewSize & 15); | ||
| 104 | kuiNewSize += 32; | ||
| 105 | |||
| 106 | pLocalPointer = InternalReallocate (pPointer, kuiNewSize, pTag); | ||
| 107 | if (NULL != pLocalPointer) { | ||
| 108 | *pRealSize = kuiNewSize; | ||
| 109 | return (pLocalPointer); | ||
| 110 | } else { | ||
| 111 | return NULL; | ||
| 112 | } | ||
| 113 | |||
| 114 | return NULL; // something wrong | ||
| 115 | } | ||
| 116 | |||
| 117 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,110 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : memory.h | ||
| 32 | * | ||
| 33 | * \brief : memory definition for wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/02/22 | ||
| 36 | * | ||
| 37 | * \description : | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_MEMORY_H | ||
| 43 | #define WELSVP_MEMORY_H | ||
| 44 | |||
| 45 | #include "util.h" | ||
| 46 | #include "typedef.h" | ||
| 47 | |||
| 48 | WELSVP_NAMESPACE_BEGIN | ||
| 49 | |||
| 50 | inline_t void* WelsMemset (void* pPointer, int32_t iValue, uint32_t uiSize) { | ||
| 51 | return ::memset (pPointer, iValue, uiSize); | ||
| 52 | } | ||
| 53 | |||
| 54 | inline_t void* WelsMemcpy (void* pDst, const void* kpSrc, uint32_t uiSize) { | ||
| 55 | return ::memcpy (pDst, kpSrc, uiSize); | ||
| 56 | } | ||
| 57 | |||
| 58 | inline_t int32_t WelsMemcmp (const void* kpBuf1, const void* kpBuf2, uint32_t uiSize) { | ||
| 59 | return ::memcmp (kpBuf1, kpBuf2, uiSize); | ||
| 60 | } | ||
| 61 | |||
| 62 | /*! | ||
| 63 | ************************************************************************************* | ||
| 64 | * \brief malloc with zero filled utilization in Wels | ||
| 65 | * | ||
| 66 | * \param i_size uiSize of memory block required | ||
| 67 | * | ||
| 68 | * \return allocated memory pointer exactly, failed in case of NULL return | ||
| 69 | * | ||
| 70 | * \note N/A | ||
| 71 | ************************************************************************************* | ||
| 72 | */ | ||
| 73 | void* WelsMalloc (const uint32_t kuiSize, str_t* pTag = NULL); | ||
| 74 | |||
| 75 | /*! | ||
| 76 | ************************************************************************************* | ||
| 77 | * \brief free utilization in Wels | ||
| 78 | * | ||
| 79 | * \param p data pointer to be free. | ||
| 80 | * i.e, uint8_t *p = actual data to be free, argv = &p. | ||
| 81 | * | ||
| 82 | * \return NONE | ||
| 83 | * | ||
| 84 | * \note N/A | ||
| 85 | ************************************************************************************* | ||
| 86 | */ | ||
| 87 | void WelsFree (void* pPointer, str_t* pTag = NULL); | ||
| 88 | |||
| 89 | /*! | ||
| 90 | ************************************************************************************* | ||
| 91 | * \brief reallocation in Wels. Do nothing and continue using old block | ||
| 92 | * in case the block is large enough currently | ||
| 93 | * | ||
| 94 | * \param p memory block required in old time | ||
| 95 | * \param i_size new uiSize of memory block requested | ||
| 96 | * \param sz_real pointer to the old uiSize of memory block | ||
| 97 | * | ||
| 98 | * \return reallocated memory pointer exactly, failed in case of NULL return | ||
| 99 | * | ||
| 100 | * \note N/A | ||
| 101 | ************************************************************************************* | ||
| 102 | */ | ||
| 103 | void* WelsRealloc (void* pPointer, uint32_t* pRealSize, const uint32_t kuiSize, str_t* pTag = NULL); | ||
| 104 | |||
| 105 | ////////////////////////////////////////////////////////////////////////////////////// | ||
| 106 | WELSVP_NAMESPACE_END | ||
| 107 | |||
| 108 | #endif | ||
| 109 | |||
| 110 | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | //{{NO_DEPENDENCIES}} | ||
| 2 | // Microsoft Visual C++ generated include file. | ||
| 3 | // Used by WelsVP.rc | ||
| 4 | // | ||
| 5 | |||
| 6 | // Next default values for new objects | ||
| 7 | // | ||
| 8 | #ifdef APSTUDIO_INVOKED | ||
| 9 | #ifndef APSTUDIO_READONLY_SYMBOLS | ||
| 10 | #define _APS_NEXT_RESOURCE_VALUE 101 | ||
| 11 | #define _APS_NEXT_COMMAND_VALUE 40001 | ||
| 12 | #define _APS_NEXT_CONTROL_VALUE 1000 | ||
| 13 | #define _APS_NEXT_SYMED_VALUE 101 | ||
| 14 | #endif | ||
| 15 | #endif | ||
| @@ -0,0 +1,93 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file thread.cpp | ||
| 32 | * | ||
| 33 | * \brief Interfaces introduced in thread programming | ||
| 34 | * | ||
| 35 | * \date 11/17/2009 Created | ||
| 36 | * | ||
| 37 | ************************************************************************************* | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include "thread.h" | ||
| 41 | |||
| 42 | WELSVP_NAMESPACE_BEGIN | ||
| 43 | |||
| 44 | #if defined(_WIN32) | ||
| 45 | |||
| 46 | WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) { | ||
| 47 | InitializeCriticalSection (mutex); | ||
| 48 | |||
| 49 | return WELS_THREAD_ERROR_OK; | ||
| 50 | } | ||
| 51 | |||
| 52 | WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) { | ||
| 53 | EnterCriticalSection (mutex); | ||
| 54 | |||
| 55 | return WELS_THREAD_ERROR_OK; | ||
| 56 | } | ||
| 57 | |||
| 58 | WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) { | ||
| 59 | LeaveCriticalSection (mutex); | ||
| 60 | |||
| 61 | return WELS_THREAD_ERROR_OK; | ||
| 62 | } | ||
| 63 | |||
| 64 | WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) { | ||
| 65 | DeleteCriticalSection (mutex); | ||
| 66 | |||
| 67 | return WELS_THREAD_ERROR_OK; | ||
| 68 | } | ||
| 69 | |||
| 70 | #elif defined(__GNUC__) | ||
| 71 | |||
| 72 | WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) { | ||
| 73 | return pthread_mutex_init (mutex, NULL); | ||
| 74 | } | ||
| 75 | |||
| 76 | WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) { | ||
| 77 | return pthread_mutex_lock (mutex); | ||
| 78 | } | ||
| 79 | |||
| 80 | WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) { | ||
| 81 | return pthread_mutex_unlock (mutex); | ||
| 82 | } | ||
| 83 | |||
| 84 | WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) { | ||
| 85 | return pthread_mutex_destroy (mutex); | ||
| 86 | } | ||
| 87 | |||
| 88 | #endif | ||
| 89 | |||
| 90 | WELSVP_NAMESPACE_END | ||
| 91 | |||
| 92 | |||
| 93 | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2009-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file thread.h | ||
| 32 | * | ||
| 33 | * \brief Interfaces introduced in thread programming | ||
| 34 | * | ||
| 35 | * \date 11/17/2009 Created | ||
| 36 | * | ||
| 37 | ************************************************************************************* | ||
| 38 | */ | ||
| 39 | |||
| 40 | #ifndef WELSVP_THREAD_H | ||
| 41 | #define WELSVP_THREAD_H | ||
| 42 | |||
| 43 | #include "typedef.h" | ||
| 44 | |||
| 45 | #if defined(_WIN32) | ||
| 46 | |||
| 47 | #include <windows.h> | ||
| 48 | |||
| 49 | #elif defined(__GNUC__) | ||
| 50 | |||
| 51 | #include <stdlib.h> | ||
| 52 | #include <unistd.h> | ||
| 53 | #include <pthread.h> | ||
| 54 | #include <semaphore.h> | ||
| 55 | #include <signal.h> | ||
| 56 | #include <errno.h> | ||
| 57 | |||
| 58 | #endif//WIN32 | ||
| 59 | |||
| 60 | WELSVP_NAMESPACE_BEGIN | ||
| 61 | |||
| 62 | #if defined(_WIN32) | ||
| 63 | |||
| 64 | typedef HANDLE WELS_THREAD_HANDLE; | ||
| 65 | typedef CRITICAL_SECTION WELS_MUTEX; | ||
| 66 | |||
| 67 | #elif defined(__GNUC__) | ||
| 68 | |||
| 69 | typedef pthread_t WELS_THREAD_HANDLE; | ||
| 70 | typedef pthread_mutex_t WELS_MUTEX; | ||
| 71 | |||
| 72 | #endif | ||
| 73 | |||
| 74 | typedef long_t WELS_THREAD_ERROR_CODE; | ||
| 75 | |||
| 76 | #define WELS_THREAD_ERROR_OK 0 | ||
| 77 | #define WELS_THREAD_ERROR_GENERIAL ((unsigned long)(-1)) | ||
| 78 | #define WELS_THREAD_ERROR_WAIT_OBJECT_0 0 | ||
| 79 | #define WELS_THREAD_ERROR_WAIT_TIMEOUT ((unsigned long)0x00000102L) | ||
| 80 | #define WELS_THREAD_ERROR_WAIT_FAILED WELS_THREAD_ERROR_GENERIAL | ||
| 81 | |||
| 82 | WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex); | ||
| 83 | WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex); | ||
| 84 | WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex); | ||
| 85 | WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex); | ||
| 86 | |||
| 87 | WELSVP_NAMESPACE_END | ||
| 88 | |||
| 89 | #endif | ||
| @@ -0,0 +1,102 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : typedef.h | ||
| 32 | * | ||
| 33 | * \brief : basic type definition | ||
| 34 | * | ||
| 35 | * \date : 2011/01/04 | ||
| 36 | * | ||
| 37 | * \description : 1. Define basic type with platform-independent; | ||
| 38 | * 2. Define specific namespace to avoid name pollution; | ||
| 39 | * 3. C++ ONLY; | ||
| 40 | * | ||
| 41 | ************************************************************************************* | ||
| 42 | */ | ||
| 43 | |||
| 44 | #ifndef WELSVP_TYPEDEF_H | ||
| 45 | #define WELSVP_TYPEDEF_H | ||
| 46 | |||
| 47 | #define WELSVP_EXTERN_C_BEGIN extern "C" { | ||
| 48 | #define WELSVP_EXTERN_C_END } | ||
| 49 | |||
| 50 | #define WELSVP_NAMESPACE_BEGIN namespace nsWelsVP { | ||
| 51 | #define WELSVP_NAMESPACE_END } | ||
| 52 | |||
| 53 | WELSVP_NAMESPACE_BEGIN | ||
| 54 | |||
| 55 | #if ( defined(_WIN32) || defined(_WIN32) ) && defined(_MSC_VER) | ||
| 56 | |||
| 57 | typedef char int8_t ; | ||
| 58 | typedef unsigned char uint8_t ; | ||
| 59 | typedef short int16_t ; | ||
| 60 | typedef unsigned short uint16_t ; | ||
| 61 | typedef int int32_t ; | ||
| 62 | typedef unsigned int uint32_t ; | ||
| 63 | typedef __int64 int64_t ; | ||
| 64 | typedef unsigned __int64 uint64_t ; | ||
| 65 | #define inline_t _inline | ||
| 66 | |||
| 67 | #else // GCC | ||
| 68 | |||
| 69 | typedef signed char int8_t | ||
| 70 | ; // [comment]: some compilers may identify the type "char" as "unsigned char" as default, so declare it explicit | ||
| 71 | typedef unsigned char uint8_t ; | ||
| 72 | typedef signed short int16_t ; | ||
| 73 | typedef unsigned short uint16_t ; | ||
| 74 | typedef signed int int32_t ; | ||
| 75 | typedef unsigned int uint32_t ; | ||
| 76 | typedef long long int64_t ; | ||
| 77 | typedef unsigned long long uint64_t ; | ||
| 78 | #define inline_t inline | ||
| 79 | |||
| 80 | #endif | ||
| 81 | |||
| 82 | typedef char str_t ; // [comment]: specific use plain char only for character parameters | ||
| 83 | typedef long long_t ; | ||
| 84 | typedef int32_t bool_t ; | ||
| 85 | |||
| 86 | #if defined(_WIN32) || defined(_MACH_PLATFORM) || defined(__GNUC__) | ||
| 87 | typedef float float_t ; | ||
| 88 | typedef double double_t ; | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #ifndef NULL | ||
| 92 | #define NULL 0 | ||
| 93 | #endif | ||
| 94 | |||
| 95 | enum { | ||
| 96 | FALSE = 0, | ||
| 97 | TRUE = !FALSE | ||
| 98 | }; | ||
| 99 | |||
| 100 | WELSVP_NAMESPACE_END | ||
| 101 | |||
| 102 | #endif | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "util.h" | ||
| 34 | |||
| 35 | WELSVP_NAMESPACE_BEGIN | ||
| 36 | ///////////////////////////////////////////////////////////////////////////////// | ||
| 37 | |||
| 38 | |||
| 39 | int32_t WelsStrCmp (const str_t* kpStr1, const str_t* kpStr2) { | ||
| 40 | return ::strcmp (kpStr1, kpStr2); | ||
| 41 | } | ||
| 42 | |||
| 43 | |||
| 44 | ///////////////////////////////////////////////////////////////////////////////// | ||
| 45 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,107 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : util.h | ||
| 32 | * | ||
| 33 | * \brief : utils for wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/01/04 | ||
| 36 | * | ||
| 37 | * \description : | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_UTIL_H | ||
| 43 | #define WELSVP_UTIL_H | ||
| 44 | |||
| 45 | #include <stdio.h> | ||
| 46 | #include <stdlib.h> | ||
| 47 | #include <string.h> | ||
| 48 | #include <stdarg.h> | ||
| 49 | #include <assert.h> | ||
| 50 | |||
| 51 | #include "typedef.h" | ||
| 52 | #include "memory.h" | ||
| 53 | #include "../../interface/IWelsVP.h" | ||
| 54 | |||
| 55 | WELSVP_NAMESPACE_BEGIN | ||
| 56 | |||
| 57 | #define MAX_WIDTH (4096) | ||
| 58 | #define MAX_HEIGHT (2304)//MAX_FS_LEVEL51 (36864); MAX_FS_LEVEL51*256/4096 = 2304 | ||
| 59 | #define MB_WIDTH_LUMA (16) | ||
| 60 | #define PESN (1e-6) // desired float precision | ||
| 61 | |||
| 62 | #define MB_TYPE_INTRA4x4 0x00000001 | ||
| 63 | #define MB_TYPE_INTRA16x16 0x00000002 | ||
| 64 | #define MB_TYPE_INTRA_PCM 0x00000004 | ||
| 65 | #define MB_TYPE_INTRA (MB_TYPE_INTRA4x4 | MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM) | ||
| 66 | #define IS_INTRA(type) ((type)&MB_TYPE_INTRA) | ||
| 67 | |||
| 68 | #define WELS_MAX(x, y) ((x) > (y) ? (x) : (y)) | ||
| 69 | #define WELS_MIN(x, y) ((x) < (y) ? (x) : (y)) | ||
| 70 | #define WELS_SIGN(a) ((long_t)(a) >> 31) | ||
| 71 | #define WELS_ABS(a) ((WELS_SIGN(a) ^ (long_t)(a)) - WELS_SIGN(a)) | ||
| 72 | #define WELS_CLAMP(x, minv, maxv) WELS_MIN(WELS_MAX(x, minv), maxv) | ||
| 73 | |||
| 74 | #define ALIGNBYTES (16) /* Worst case is requiring alignment to an 16 byte boundary */ | ||
| 75 | #define WELS_ALIGN(iInput) ((iInput+(ALIGNMENT-1)) & ~(ALIGNMENT-1)) | ||
| 76 | #define WELS_ALIGN2(iInput) ((iInput+1) & ~1) | ||
| 77 | #define WELS_ALIGN4(iInput) ((iInput+3) & ~3) | ||
| 78 | #define WELS_ALIGN8(iInput) ((iInput+7) & ~7) | ||
| 79 | |||
| 80 | #define WelsCastFromPointer(p) (reinterpret_cast<long_t>(p)) | ||
| 81 | #define WelsStaticCast(type, p) (static_cast<type>(p)) | ||
| 82 | #define WelsDynamicCast(type, p) (dynamic_cast<type>(p)) | ||
| 83 | |||
| 84 | #define GET_METHOD(x) ((x) & 0xff) // mask method as the lowest 8bits | ||
| 85 | #define GET_SPECIAL(x) (((x) >> 8) & 0xff) // mask special flag as 8bits | ||
| 86 | |||
| 87 | inline_t EMethods WelsVpGetValidMethod (int32_t a) { | ||
| 88 | int32_t iMethod = GET_METHOD (a); | ||
| 89 | return WelsStaticCast (EMethods, WELS_CLAMP (iMethod, METHOD_NULL + 1, METHOD_MASK - 1)); | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 93 | #define _SafeFree(p) if (p) { WelsFree(p); (p) = NULL; } | ||
| 94 | #define _SafeDelete(p) if (p) { delete (p); (p) = NULL; } | ||
| 95 | |||
| 96 | |||
| 97 | ////////////////////////////////////////////////////////////////////////////////////// | ||
| 98 | |||
| 99 | int32_t WelsStrCmp (const str_t* kpStr1, const str_t* kpStr2); | ||
| 100 | |||
| 101 | |||
| 102 | ////////////////////////////////////////////////////////////////////////////////////// | ||
| 103 | WELSVP_NAMESPACE_END | ||
| 104 | |||
| 105 | #endif | ||
| 106 | |||
| 107 | |||
| @@ -0,0 +1,304 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "ComplexityAnalysis.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | |||
| 39 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | CComplexityAnalysis::CComplexityAnalysis (int32_t iCpuFlag) { | ||
| 42 | m_eMethod = METHOD_COMPLEXITY_ANALYSIS; | ||
| 43 | m_pfGomSad = NULL; | ||
| 44 | WelsMemset (&m_sComplexityAnalysisParam, 0, sizeof (m_sComplexityAnalysisParam)); | ||
| 45 | } | ||
| 46 | |||
| 47 | CComplexityAnalysis::~CComplexityAnalysis() { | ||
| 48 | } | ||
| 49 | |||
| 50 | EResult CComplexityAnalysis::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 51 | EResult eReturn = RET_SUCCESS; | ||
| 52 | |||
| 53 | switch (m_sComplexityAnalysisParam.iComplexityAnalysisMode) { | ||
| 54 | case FRAME_SAD: | ||
| 55 | AnalyzeFrameComplexityViaSad (pSrcPixMap, pRefPixMap); | ||
| 56 | break; | ||
| 57 | case GOM_SAD: | ||
| 58 | AnalyzeGomComplexityViaSad (pSrcPixMap, pRefPixMap); | ||
| 59 | break; | ||
| 60 | case GOM_VAR: | ||
| 61 | AnalyzeGomComplexityViaVar (pSrcPixMap, pRefPixMap); | ||
| 62 | break; | ||
| 63 | default: | ||
| 64 | eReturn = RET_INVALIDPARAM; | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | |||
| 68 | return eReturn; | ||
| 69 | } | ||
| 70 | |||
| 71 | |||
| 72 | EResult CComplexityAnalysis::Set (int32_t iType, void* pParam) { | ||
| 73 | if (pParam == NULL) { | ||
| 74 | return RET_INVALIDPARAM; | ||
| 75 | } | ||
| 76 | |||
| 77 | m_sComplexityAnalysisParam = * (SComplexityAnalysisParam*)pParam; | ||
| 78 | |||
| 79 | return RET_SUCCESS; | ||
| 80 | } | ||
| 81 | |||
| 82 | EResult CComplexityAnalysis::Get (int32_t iType, void* pParam) { | ||
| 83 | if (pParam == NULL) { | ||
| 84 | return RET_INVALIDPARAM; | ||
| 85 | } | ||
| 86 | |||
| 87 | SComplexityAnalysisParam* sComplexityAnalysisParam = (SComplexityAnalysisParam*)pParam; | ||
| 88 | |||
| 89 | sComplexityAnalysisParam->iFrameComplexity = m_sComplexityAnalysisParam.iFrameComplexity; | ||
| 90 | |||
| 91 | return RET_SUCCESS; | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | /////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 96 | void CComplexityAnalysis::AnalyzeFrameComplexityViaSad (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 97 | SVAACalcResult* pVaaCalcResults = NULL; | ||
| 98 | pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult; | ||
| 99 | |||
| 100 | m_sComplexityAnalysisParam.iFrameComplexity = pVaaCalcResults->iFrameSad; | ||
| 101 | |||
| 102 | if (m_sComplexityAnalysisParam.iCalcBgd) { //BGD control | ||
| 103 | m_sComplexityAnalysisParam.iFrameComplexity = (int32_t)GetFrameSadExcludeBackground (pSrcPixMap, pRefPixMap); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | int32_t CComplexityAnalysis::GetFrameSadExcludeBackground (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 108 | int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 109 | int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 110 | int32_t iMbWidth = iWidth >> 4; | ||
| 111 | int32_t iMbHeight = iHeight >> 4; | ||
| 112 | int32_t iMbNum = iMbWidth * iMbHeight; | ||
| 113 | |||
| 114 | int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom; | ||
| 115 | int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom; | ||
| 116 | int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0; | ||
| 117 | |||
| 118 | uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag; | ||
| 119 | uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType; | ||
| 120 | SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult; | ||
| 121 | int32_t* pGomForegroundBlockNum = m_sComplexityAnalysisParam.pGomForegroundBlockNum; | ||
| 122 | |||
| 123 | uint32_t uiFrameSad = 0; | ||
| 124 | for (int32_t j = 0; j < iGomMbNum; j ++) { | ||
| 125 | iGomMbStartIndex = j * iMbNumInGom; | ||
| 126 | iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum); | ||
| 127 | |||
| 128 | for (int32_t i = iGomMbStartIndex; i < iGomMbEndIndex; i ++) { | ||
| 129 | if (pBackgroundMbFlag[i] == 0 || IS_INTRA (uiRefMbType[i])) { | ||
| 130 | pGomForegroundBlockNum[j]++; | ||
| 131 | uiFrameSad += pVaaCalcResults->pSad8x8[i][0]; | ||
| 132 | uiFrameSad += pVaaCalcResults->pSad8x8[i][1]; | ||
| 133 | uiFrameSad += pVaaCalcResults->pSad8x8[i][2]; | ||
| 134 | uiFrameSad += pVaaCalcResults->pSad8x8[i][3]; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | return (uiFrameSad); | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 143 | void InitGomSadFunc (PGOMSadFunc& pfGomSad, uint8_t iCalcBgd) { | ||
| 144 | pfGomSad = GomSampleSad; | ||
| 145 | |||
| 146 | if (iCalcBgd) { | ||
| 147 | pfGomSad = GomSampleSadExceptBackground; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | void GomSampleSad (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8, uint8_t pBackgroundMbFlag) { | ||
| 152 | (*pGomForegroundBlockNum) ++; | ||
| 153 | *pGomSad += pSad8x8[0]; | ||
| 154 | *pGomSad += pSad8x8[1]; | ||
| 155 | *pGomSad += pSad8x8[2]; | ||
| 156 | *pGomSad += pSad8x8[3]; | ||
| 157 | } | ||
| 158 | |||
| 159 | void GomSampleSadExceptBackground (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8, | ||
| 160 | uint8_t pBackgroundMbFlag) { | ||
| 161 | if (pBackgroundMbFlag == 0) { | ||
| 162 | (*pGomForegroundBlockNum) ++; | ||
| 163 | *pGomSad += pSad8x8[0]; | ||
| 164 | *pGomSad += pSad8x8[1]; | ||
| 165 | *pGomSad += pSad8x8[2]; | ||
| 166 | *pGomSad += pSad8x8[3]; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | void CComplexityAnalysis::AnalyzeGomComplexityViaSad (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 171 | int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 172 | int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 173 | int32_t iMbWidth = iWidth >> 4; | ||
| 174 | int32_t iMbHeight = iHeight >> 4; | ||
| 175 | int32_t iMbNum = iMbWidth * iMbHeight; | ||
| 176 | |||
| 177 | int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom; | ||
| 178 | int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom; | ||
| 179 | |||
| 180 | int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0; | ||
| 181 | int32_t iMbStartIndex = 0, iMbEndIndex = 0; | ||
| 182 | int32_t iStartSampleIndex = 0; | ||
| 183 | |||
| 184 | uint8_t* pBackgroundMbFlag = (uint8_t*)m_sComplexityAnalysisParam.pBackgroundMbFlag; | ||
| 185 | uint32_t* uiRefMbType = (uint32_t*)m_sComplexityAnalysisParam.uiRefMbType; | ||
| 186 | SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult; | ||
| 187 | int32_t* pGomForegroundBlockNum = (int32_t*)m_sComplexityAnalysisParam.pGomForegroundBlockNum; | ||
| 188 | int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity; | ||
| 189 | |||
| 190 | uint8_t* pRefY = NULL, *pSrcY = NULL; | ||
| 191 | int32_t iRefStride = 0, iCurStride = 0; | ||
| 192 | |||
| 193 | uint8_t* pRefTmp = NULL, *pCurTmp = NULL; | ||
| 194 | uint32_t uiGomSad = 0, uiFrameSad = 0; | ||
| 195 | |||
| 196 | pRefY = (uint8_t*)pRefPixMap->pPixel[0]; | ||
| 197 | pSrcY = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 198 | |||
| 199 | iRefStride = pRefPixMap->iStride[0]; | ||
| 200 | iCurStride = pSrcPixMap->iStride[0]; | ||
| 201 | |||
| 202 | InitGomSadFunc (m_pfGomSad, m_sComplexityAnalysisParam.iCalcBgd); | ||
| 203 | |||
| 204 | for (int32_t j = 0; j < iGomMbNum; j ++) { | ||
| 205 | uiGomSad = 0; | ||
| 206 | |||
| 207 | iGomMbStartIndex = j * iMbNumInGom; | ||
| 208 | iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum); | ||
| 209 | iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth - iGomMbStartIndex / iMbWidth; | ||
| 210 | |||
| 211 | iMbStartIndex = iGomMbStartIndex; | ||
| 212 | iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex); | ||
| 213 | |||
| 214 | iStartSampleIndex = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iRefStride + (iMbStartIndex % iMbWidth) * | ||
| 215 | MB_WIDTH_LUMA; | ||
| 216 | |||
| 217 | do { | ||
| 218 | pRefTmp = pRefY + iStartSampleIndex; | ||
| 219 | pCurTmp = pSrcY + iStartSampleIndex; | ||
| 220 | |||
| 221 | for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) { | ||
| 222 | m_pfGomSad (&uiGomSad, pGomForegroundBlockNum + j, pVaaCalcResults->pSad8x8[i], pBackgroundMbFlag[i] | ||
| 223 | && !IS_INTRA (uiRefMbType[i])); | ||
| 224 | } | ||
| 225 | |||
| 226 | iMbStartIndex = iMbEndIndex; | ||
| 227 | iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth , iGomMbEndIndex); | ||
| 228 | |||
| 229 | iStartSampleIndex = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iRefStride + (iMbStartIndex % iMbWidth) * | ||
| 230 | MB_WIDTH_LUMA; | ||
| 231 | |||
| 232 | } while (--iGomMbRowNum); | ||
| 233 | |||
| 234 | pGomComplexity[j] = uiGomSad; | ||
| 235 | uiFrameSad += pGomComplexity[j]; | ||
| 236 | } | ||
| 237 | |||
| 238 | m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad; | ||
| 239 | } | ||
| 240 | |||
| 241 | |||
| 242 | void CComplexityAnalysis::AnalyzeGomComplexityViaVar (SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 243 | int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 244 | int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 245 | int32_t iMbWidth = iWidth >> 4; | ||
| 246 | int32_t iMbHeight = iHeight >> 4; | ||
| 247 | int32_t iMbNum = iMbWidth * iMbHeight; | ||
| 248 | |||
| 249 | int32_t iMbNumInGom = m_sComplexityAnalysisParam.iMbNumInGom; | ||
| 250 | int32_t iGomMbNum = (iMbNum + iMbNumInGom - 1) / iMbNumInGom; | ||
| 251 | int32_t iGomSampleNum = 0; | ||
| 252 | |||
| 253 | int32_t iGomMbStartIndex = 0, iGomMbEndIndex = 0, iGomMbRowNum = 0; | ||
| 254 | int32_t iMbStartIndex = 0, iMbEndIndex = 0; | ||
| 255 | int32_t iStartSampleIndex = 0; | ||
| 256 | |||
| 257 | SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult; | ||
| 258 | int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity; | ||
| 259 | |||
| 260 | uint8_t* pSrcY = NULL; | ||
| 261 | int32_t iCurStride = 0; | ||
| 262 | |||
| 263 | uint8_t* pCurTmp = NULL; | ||
| 264 | uint32_t uiSampleSum = 0, uiSquareSum = 0; | ||
| 265 | |||
| 266 | pSrcY = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 267 | iCurStride = pSrcPixMap->iStride[0]; | ||
| 268 | |||
| 269 | for (int32_t j = 0; j < iGomMbNum; j ++) { | ||
| 270 | uiSampleSum = 0; | ||
| 271 | uiSquareSum = 0; | ||
| 272 | |||
| 273 | iGomMbStartIndex = j * iMbNumInGom; | ||
| 274 | iGomMbEndIndex = WELS_MIN ((j + 1) * iMbNumInGom, iMbNum); | ||
| 275 | iGomMbRowNum = (iGomMbEndIndex + iMbWidth - 1) / iMbWidth - iGomMbStartIndex / iMbWidth; | ||
| 276 | |||
| 277 | iMbStartIndex = iGomMbStartIndex; | ||
| 278 | iMbEndIndex = WELS_MIN ((iMbStartIndex / iMbWidth + 1) * iMbWidth, iGomMbEndIndex); | ||
| 279 | |||
| 280 | iStartSampleIndex = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iCurStride + (iMbStartIndex % iMbWidth) * | ||
| 281 | MB_WIDTH_LUMA; | ||
| 282 | iGomSampleNum = (iMbEndIndex - iMbStartIndex) * MB_WIDTH_LUMA * MB_WIDTH_LUMA; | ||
| 283 | |||
| 284 | do { | ||
| 285 | pCurTmp = pSrcY + iStartSampleIndex; | ||
| 286 | |||
| 287 | for (int32_t i = iMbStartIndex; i < iMbEndIndex; i ++) { | ||
| 288 | uiSampleSum += pVaaCalcResults->pSum16x16[i]; | ||
| 289 | uiSquareSum += pVaaCalcResults->pSumOfSquare16x16[i]; | ||
| 290 | } | ||
| 291 | |||
| 292 | iMbStartIndex = iMbEndIndex; | ||
| 293 | iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth, iGomMbEndIndex); | ||
| 294 | |||
| 295 | iStartSampleIndex = (iMbStartIndex / iMbWidth) * MB_WIDTH_LUMA * iCurStride + (iMbStartIndex % iMbWidth) * | ||
| 296 | MB_WIDTH_LUMA; | ||
| 297 | } while (--iGomMbRowNum); | ||
| 298 | |||
| 299 | pGomComplexity[j] = uiSquareSum - (uiSampleSum * uiSampleSum / iGomSampleNum); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | |||
| 304 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,83 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : ComplexityAnalysis.h | ||
| 32 | * | ||
| 33 | * \brief : complexity analysis class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/28 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of complexity analysis class | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_COMPLEXITYANALYSIS_H | ||
| 43 | #define WELSVP_COMPLEXITYANALYSIS_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/memory.h" | ||
| 47 | #include "../common/WelsFrameWork.h" | ||
| 48 | #include "../../interface/IWelsVP.h" | ||
| 49 | |||
| 50 | WELSVP_NAMESPACE_BEGIN | ||
| 51 | |||
| 52 | typedef void (GOMSadFunc) (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8, | ||
| 53 | uint8_t pBackgroundMbFlag); | ||
| 54 | |||
| 55 | typedef GOMSadFunc* PGOMSadFunc; | ||
| 56 | |||
| 57 | GOMSadFunc GomSampleSad; | ||
| 58 | GOMSadFunc GomSampleSadExceptBackground; | ||
| 59 | |||
| 60 | class CComplexityAnalysis : public IStrategy { | ||
| 61 | public: | ||
| 62 | CComplexityAnalysis (int32_t iCpuFlag); | ||
| 63 | ~CComplexityAnalysis(); | ||
| 64 | |||
| 65 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef); | ||
| 66 | EResult Set (int32_t iType, void* pParam); | ||
| 67 | EResult Get (int32_t iType, void* pParam); | ||
| 68 | |||
| 69 | private: | ||
| 70 | void AnalyzeFrameComplexityViaSad (SPixMap* pSrc, SPixMap* pRef); | ||
| 71 | int32_t GetFrameSadExcludeBackground (SPixMap* pSrc, SPixMap* pRef); | ||
| 72 | |||
| 73 | void AnalyzeGomComplexityViaSad (SPixMap* pSrc, SPixMap* pRef); | ||
| 74 | void AnalyzeGomComplexityViaVar (SPixMap* pSrc, SPixMap* pRef); | ||
| 75 | |||
| 76 | private: | ||
| 77 | PGOMSadFunc m_pfGomSad; | ||
| 78 | SComplexityAnalysisParam m_sComplexityAnalysisParam; | ||
| 79 | }; | ||
| 80 | |||
| 81 | WELSVP_NAMESPACE_END | ||
| 82 | |||
| 83 | #endif | ||
| @@ -0,0 +1,124 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "denoise.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | #define CALC_BI_STRIDE(iWidth, iBitcount) ((((iWidth) * (iBitcount) + 31) & ~31) >> 3) | ||
| 39 | |||
| 40 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 41 | |||
| 42 | CDenoiser::CDenoiser (int32_t iCpuFlag) { | ||
| 43 | m_CPUFlag = iCpuFlag; | ||
| 44 | m_eMethod = METHOD_DENOISE; | ||
| 45 | WelsMemset (&m_pfDenoise, 0, sizeof (m_pfDenoise)); | ||
| 46 | |||
| 47 | m_uiSpaceRadius = DENOISE_GRAY_RADIUS; | ||
| 48 | m_fSigmaGrey = DENOISE_GRAY_SIGMA; | ||
| 49 | m_uiType = DENOISE_ALL_COMPONENT; | ||
| 50 | InitDenoiseFunc (m_pfDenoise, m_CPUFlag); | ||
| 51 | } | ||
| 52 | |||
| 53 | CDenoiser::~CDenoiser() { | ||
| 54 | } | ||
| 55 | |||
| 56 | void CDenoiser::InitDenoiseFunc (SDenoiseFuncs& denoiser, int32_t iCpuFlag) { | ||
| 57 | denoiser.pfBilateralLumaFilter8 = BilateralLumaFilter8_c; | ||
| 58 | denoiser.pfWaverageChromaFilter8 = WaverageChromaFilter8_c; | ||
| 59 | #if defined(X86_ASM) | ||
| 60 | if (iCpuFlag & WELS_CPU_SSE2) { | ||
| 61 | denoiser.pfBilateralLumaFilter8 = BilateralLumaFilter8_sse2; | ||
| 62 | denoiser.pfWaverageChromaFilter8 = WaverageChromaFilter8_sse2; | ||
| 63 | } | ||
| 64 | #endif | ||
| 65 | } | ||
| 66 | |||
| 67 | EResult CDenoiser::Process (int32_t iType, SPixMap* pSrc, SPixMap* dst) { | ||
| 68 | uint8_t* pSrcY = (uint8_t*)pSrc->pPixel[0]; | ||
| 69 | uint8_t* pSrcU = (uint8_t*)pSrc->pPixel[1]; | ||
| 70 | uint8_t* pSrcV = (uint8_t*)pSrc->pPixel[2]; | ||
| 71 | if (pSrcY == NULL || pSrcU == NULL || pSrcV == NULL) { | ||
| 72 | return RET_INVALIDPARAM; | ||
| 73 | } | ||
| 74 | |||
| 75 | int32_t iWidthY = pSrc->sRect.iRectWidth; | ||
| 76 | int32_t iHeightY = pSrc->sRect.iRectHeight; | ||
| 77 | int32_t iWidthUV = iWidthY >> 1; | ||
| 78 | int32_t iHeightUV = iHeightY >> 1; | ||
| 79 | |||
| 80 | if (m_uiType & DENOISE_Y_COMPONENT) | ||
| 81 | BilateralDenoiseLuma (pSrcY, iWidthY, iHeightY, pSrc->iStride[0]); | ||
| 82 | |||
| 83 | if (m_uiType & DENOISE_U_COMPONENT) | ||
| 84 | WaverageDenoiseChroma (pSrcU, iWidthUV, iHeightUV, pSrc->iStride[1]); | ||
| 85 | |||
| 86 | if (m_uiType & DENOISE_V_COMPONENT) | ||
| 87 | WaverageDenoiseChroma (pSrcV, iWidthUV, iHeightUV, pSrc->iStride[2]); | ||
| 88 | |||
| 89 | return RET_SUCCESS; | ||
| 90 | } | ||
| 91 | |||
| 92 | void CDenoiser::BilateralDenoiseLuma (uint8_t* pSrcY, int32_t iWidth, int32_t iHeight, int32_t iStride) { | ||
| 93 | int32_t w; | ||
| 94 | |||
| 95 | pSrcY = pSrcY + m_uiSpaceRadius * iStride; | ||
| 96 | for (int32_t h = m_uiSpaceRadius; h < iHeight - m_uiSpaceRadius; h++) { | ||
| 97 | for (w = m_uiSpaceRadius; w < iWidth - m_uiSpaceRadius - TAIL_OF_LINE8; w += 8) { | ||
| 98 | m_pfDenoise.pfBilateralLumaFilter8 (pSrcY + w, iStride); | ||
| 99 | } | ||
| 100 | for (w = w + TAIL_OF_LINE8; w < iWidth - m_uiSpaceRadius; w++) { | ||
| 101 | Gauss3x3Filter (pSrcY + w, iStride); | ||
| 102 | } | ||
| 103 | pSrcY += iStride; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | void CDenoiser::WaverageDenoiseChroma (uint8_t* pSrcUV, int32_t iWidth, int32_t iHeight, int32_t iStride) { | ||
| 108 | int32_t w; | ||
| 109 | |||
| 110 | pSrcUV = pSrcUV + UV_WINDOWS_RADIUS * iStride; | ||
| 111 | for (int32_t h = UV_WINDOWS_RADIUS; h < iHeight - UV_WINDOWS_RADIUS; h++) { | ||
| 112 | for (w = UV_WINDOWS_RADIUS; w < iWidth - UV_WINDOWS_RADIUS - TAIL_OF_LINE8; w += 8) { | ||
| 113 | m_pfDenoise.pfWaverageChromaFilter8 (pSrcUV + w, iStride); | ||
| 114 | } | ||
| 115 | |||
| 116 | for (w = w + TAIL_OF_LINE8; w < iWidth - UV_WINDOWS_RADIUS; w++) { | ||
| 117 | Gauss3x3Filter (pSrcUV + w, iStride); | ||
| 118 | } | ||
| 119 | pSrcUV += iStride; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | |||
| 124 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,111 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : denoise.h | ||
| 32 | * | ||
| 33 | * \brief : denoise class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/15 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of denoise class | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_DENOISE_H | ||
| 43 | #define WELSVP_DENOISE_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/memory.h" | ||
| 47 | #include "../common/WelsFrameWork.h" | ||
| 48 | #include "../../interface/IWelsVP.h" | ||
| 49 | |||
| 50 | |||
| 51 | #define DENOISE_GRAY_RADIUS (1) | ||
| 52 | #define DENOISE_GRAY_SIGMA (2) | ||
| 53 | |||
| 54 | #define UV_WINDOWS_RADIUS (2) | ||
| 55 | #define TAIL_OF_LINE8 (7) | ||
| 56 | |||
| 57 | #define DENOISE_Y_COMPONENT (1) | ||
| 58 | #define DENOISE_U_COMPONENT (2) | ||
| 59 | #define DENOISE_V_COMPONENT (4) | ||
| 60 | #define DENOISE_ALL_COMPONENT (7) | ||
| 61 | |||
| 62 | |||
| 63 | WELSVP_NAMESPACE_BEGIN | ||
| 64 | |||
| 65 | void Gauss3x3Filter (uint8_t* pixels, int32_t stride); | ||
| 66 | |||
| 67 | typedef void (DenoiseFilterFunc) (uint8_t* pixels, int32_t stride); | ||
| 68 | |||
| 69 | typedef DenoiseFilterFunc* DenoiseFilterFuncPtr; | ||
| 70 | |||
| 71 | DenoiseFilterFunc BilateralLumaFilter8_c; | ||
| 72 | DenoiseFilterFunc WaverageChromaFilter8_c; | ||
| 73 | |||
| 74 | #ifdef X86_ASM | ||
| 75 | WELSVP_EXTERN_C_BEGIN | ||
| 76 | DenoiseFilterFunc BilateralLumaFilter8_sse2 ; | ||
| 77 | DenoiseFilterFunc WaverageChromaFilter8_sse2 ; | ||
| 78 | WELSVP_EXTERN_C_END | ||
| 79 | #endif | ||
| 80 | |||
| 81 | typedef struct TagDenoiseFuncs { | ||
| 82 | DenoiseFilterFuncPtr pfBilateralLumaFilter8;//on 8 samples | ||
| 83 | DenoiseFilterFuncPtr pfWaverageChromaFilter8;//on 8 samples | ||
| 84 | } SDenoiseFuncs; | ||
| 85 | |||
| 86 | class CDenoiser : public IStrategy { | ||
| 87 | public: | ||
| 88 | CDenoiser (int32_t iCpuFlag); | ||
| 89 | ~CDenoiser(); | ||
| 90 | |||
| 91 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* dst); | ||
| 92 | |||
| 93 | private: | ||
| 94 | void InitDenoiseFunc (SDenoiseFuncs& pf, int32_t cpu); | ||
| 95 | void BilateralDenoiseLuma (uint8_t* p_y_data, int32_t width, int32_t height, int32_t stride); | ||
| 96 | void WaverageDenoiseChroma (uint8_t* pSrcUV, int32_t width, int32_t height, int32_t stride); | ||
| 97 | |||
| 98 | private: | ||
| 99 | float_t m_fSigmaGrey; //sigma for grey scale similarity, suggestion 2.5-3 | ||
| 100 | uint32_t m_uiFilterWindow; //filter window diameter | ||
| 101 | uint16_t m_uiSpaceRadius; //filter windows radius: 1-3x3, 2-5x5,3-7x7. Larger size, slower speed | ||
| 102 | uint16_t m_uiType; //do denoising on which component 1-Y, 2-U, 4-V; 7-YUV, 3-YU, 5-YV, 6-UV | ||
| 103 | uint32_t* m_pGreyWeightTable; //weight table for grey scale | ||
| 104 | |||
| 105 | SDenoiseFuncs m_pfDenoise; | ||
| 106 | int32_t m_CPUFlag; | ||
| 107 | }; | ||
| 108 | |||
| 109 | WELSVP_NAMESPACE_END | ||
| 110 | |||
| 111 | #endif | ||
| @@ -0,0 +1,127 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2010-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file svc_preprocess.h | ||
| 32 | * | ||
| 33 | * \brief svc denoising | ||
| 34 | * | ||
| 35 | * \date 4/1/2010 Created | ||
| 36 | * | ||
| 37 | */ | ||
| 38 | |||
| 39 | #include "denoise.h" | ||
| 40 | #include "../common/typedef.h" | ||
| 41 | |||
| 42 | WELSVP_NAMESPACE_BEGIN | ||
| 43 | |||
| 44 | void BilateralLumaFilter8_c (uint8_t* pSample, int32_t iStride) { | ||
| 45 | int32_t nSum = 0, nTotWeight = 0; | ||
| 46 | int32_t iCenterSample = *pSample; | ||
| 47 | uint8_t* pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS; | ||
| 48 | int32_t x, y; | ||
| 49 | int32_t iCurSample, iCurWeight, iGreyDiff; | ||
| 50 | uint8_t aSample[8]; | ||
| 51 | |||
| 52 | for (int32_t i = 0; i < 8; i++) { | ||
| 53 | nSum = 0; | ||
| 54 | nTotWeight = 0; | ||
| 55 | iCenterSample = *pSample; | ||
| 56 | pCurLine = pSample - iStride - DENOISE_GRAY_RADIUS; | ||
| 57 | for (y = 0; y < 3; y++) { | ||
| 58 | for (x = 0; x < 3; x++) { | ||
| 59 | if (x == 1 && y == 1) continue; // except center point | ||
| 60 | iCurSample = pCurLine[x]; | ||
| 61 | iCurWeight = WELS_ABS (iCurSample - iCenterSample); | ||
| 62 | iGreyDiff = 32 - iCurWeight; | ||
| 63 | if (iGreyDiff < 0) continue; | ||
| 64 | else iCurWeight = (iGreyDiff * iGreyDiff) >> 5; | ||
| 65 | nSum += iCurSample * iCurWeight; | ||
| 66 | nTotWeight += iCurWeight; | ||
| 67 | } | ||
| 68 | pCurLine += iStride; | ||
| 69 | } | ||
| 70 | nTotWeight = 256 - nTotWeight; | ||
| 71 | nSum += iCenterSample * nTotWeight; | ||
| 72 | aSample[i] = nSum >> 8; | ||
| 73 | pSample++; | ||
| 74 | } | ||
| 75 | WelsMemcpy (pSample - 8, aSample, 8); | ||
| 76 | } | ||
| 77 | |||
| 78 | |||
| 79 | /*************************************************************************** | ||
| 80 | 5x5 filter: | ||
| 81 | 1 1 2 1 1 | ||
| 82 | 1 2 4 2 1 | ||
| 83 | 2 4 20 4 2 | ||
| 84 | 1 2 4 2 1 | ||
| 85 | 1 1 2 1 1 | ||
| 86 | ***************************************************************************/ | ||
| 87 | #define SUM_LINE1(pSample) (pSample[0] +(pSample[1]) +(pSample[2]<<1) + pSample[3] + pSample[4]) | ||
| 88 | #define SUM_LINE2(pSample) (pSample[0] +(pSample[1]<<1) +(pSample[2]<<2) +(pSample[3]<<1) +pSample[4]) | ||
| 89 | #define SUM_LINE3(pSample) ((pSample[0]<<1) +(pSample[1]<<2) +(pSample[2]*20) +(pSample[3]<<2) +(pSample[4]<<1)) | ||
| 90 | void WaverageChromaFilter8_c (uint8_t* pSample, int32_t iStride) { | ||
| 91 | int32_t sum; | ||
| 92 | uint8_t* pStartPixels = pSample - UV_WINDOWS_RADIUS * iStride - UV_WINDOWS_RADIUS; | ||
| 93 | uint8_t* pCurLine1 = pStartPixels; | ||
| 94 | uint8_t* pCurLine2 = pCurLine1 + iStride; | ||
| 95 | uint8_t* pCurLine3 = pCurLine2 + iStride; | ||
| 96 | uint8_t* pCurLine4 = pCurLine3 + iStride; | ||
| 97 | uint8_t* pCurLine5 = pCurLine4 + iStride; | ||
| 98 | uint8_t aSample[8]; | ||
| 99 | |||
| 100 | for (int32_t i = 0; i < 8; i++) { | ||
| 101 | sum = SUM_LINE1 ((pCurLine1 + i)) + SUM_LINE2 ((pCurLine2 + i)) + SUM_LINE3 ((pCurLine3 + i)) | ||
| 102 | + SUM_LINE2 ((pCurLine4 + i)) + SUM_LINE1 ((pCurLine5 + i)); | ||
| 103 | aSample[i] = (sum >> 6); | ||
| 104 | pSample++; | ||
| 105 | } | ||
| 106 | WelsMemcpy (pSample - 8, aSample, 8); | ||
| 107 | } | ||
| 108 | |||
| 109 | /*************************************************************************** | ||
| 110 | edge of y/uv use a 3x3 Gauss filter, radius = 1: | ||
| 111 | 1 2 1 | ||
| 112 | 2 4 2 | ||
| 113 | 1 2 1 | ||
| 114 | ***************************************************************************/ | ||
| 115 | void Gauss3x3Filter (uint8_t* pSrc, int32_t iStride) { | ||
| 116 | int32_t nSum = 0; | ||
| 117 | uint8_t* pCurLine1 = pSrc - iStride - 1; | ||
| 118 | uint8_t* pCurLine2 = pCurLine1 + iStride; | ||
| 119 | uint8_t* pCurLine3 = pCurLine2 + iStride; | ||
| 120 | |||
| 121 | nSum = pCurLine1[0] + (pCurLine1[1] << 1) + pCurLine1[2] + | ||
| 122 | (pCurLine2[0] << 1) + (pCurLine2[1] << 2) + (pCurLine2[2] << 1) + | ||
| 123 | pCurLine3[0] + (pCurLine3[1] << 1) + pCurLine3[2]; | ||
| 124 | *pSrc = nSum >> 4; | ||
| 125 | } | ||
| 126 | |||
| 127 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,135 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "downsample.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | |||
| 39 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | CDownsampling::CDownsampling (int32_t iCpuFlag) { | ||
| 42 | m_iCPUFlag = iCpuFlag; | ||
| 43 | m_eMethod = METHOD_DOWNSAMPLE; | ||
| 44 | WelsMemset (&m_pfDownsample, 0, sizeof (m_pfDownsample)); | ||
| 45 | InitDownsampleFuncs (m_pfDownsample, m_iCPUFlag); | ||
| 46 | } | ||
| 47 | |||
| 48 | CDownsampling::~CDownsampling() { | ||
| 49 | } | ||
| 50 | |||
| 51 | void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag) { | ||
| 52 | sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsampler_c; | ||
| 53 | sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsampler_c; | ||
| 54 | sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsampler_c; | ||
| 55 | sDownsampleFunc.pfHalfAverage[3] = DyadicBilinearDownsampler_c; | ||
| 56 | sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsampler_c; | ||
| 57 | sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsampler_c; | ||
| 58 | #if defined(X86_ASM) | ||
| 59 | if (iCpuFlag & WELS_CPU_SSE) { | ||
| 60 | /* sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_sse; | ||
| 61 | sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_sse; | ||
| 62 | sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsamplerWidthx8_sse;*/ | ||
| 63 | } | ||
| 64 | if (iCpuFlag & WELS_CPU_SSE2) { | ||
| 65 | // sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_sse2; | ||
| 66 | // sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_sse2; | ||
| 67 | } | ||
| 68 | if (iCpuFlag & WELS_CPU_SSSE3) { | ||
| 69 | // sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_ssse3; | ||
| 70 | // sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_ssse3; | ||
| 71 | } | ||
| 72 | if (iCpuFlag & WELS_CPU_SSE41) { | ||
| 73 | // sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_sse4; | ||
| 74 | // sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_sse4; | ||
| 75 | } | ||
| 76 | #endif//X86_ASM | ||
| 77 | |||
| 78 | } | ||
| 79 | |||
| 80 | EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDstPixMap) { | ||
| 81 | int32_t iSrcWidthY = pSrcPixMap->sRect.iRectWidth; | ||
| 82 | int32_t iSrcHeightY = pSrcPixMap->sRect.iRectHeight; | ||
| 83 | int32_t iDstWidthY = pDstPixMap->sRect.iRectWidth; | ||
| 84 | int32_t iDstHeightY = pDstPixMap->sRect.iRectHeight; | ||
| 85 | |||
| 86 | int32_t iSrcWidthUV = iSrcWidthY >> 1; | ||
| 87 | int32_t iSrcHeightUV = iSrcHeightY >> 1; | ||
| 88 | int32_t iDstWidthUV = iDstWidthY >> 1; | ||
| 89 | int32_t iDstHeightUV = iDstHeightY >> 1; | ||
| 90 | |||
| 91 | if (iSrcWidthY <= iDstWidthY || iSrcHeightY <= iDstHeightY) { | ||
| 92 | return RET_INVALIDPARAM; | ||
| 93 | } | ||
| 94 | |||
| 95 | if ((iSrcWidthY >> 1) == iDstWidthY && (iSrcHeightY >> 1) == iDstHeightY) { | ||
| 96 | // use half average functions | ||
| 97 | uint8_t iAlignIndex = 3; | ||
| 98 | |||
| 99 | iAlignIndex = GetAlignedIndex (iSrcWidthY); | ||
| 100 | m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0], | ||
| 101 | (uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY); | ||
| 102 | |||
| 103 | iAlignIndex = GetAlignedIndex (iSrcWidthUV); | ||
| 104 | m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1], | ||
| 105 | (uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV); | ||
| 106 | m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2], | ||
| 107 | (uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV); | ||
| 108 | } else { | ||
| 109 | m_pfDownsample.pfGeneralRatioLuma ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0], iDstWidthY, iDstHeightY, | ||
| 110 | (uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY); | ||
| 111 | |||
| 112 | m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1], iDstWidthUV, iDstHeightUV, | ||
| 113 | (uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV); | ||
| 114 | |||
| 115 | m_pfDownsample.pfGeneralRatioChroma ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2], iDstWidthUV, iDstHeightUV, | ||
| 116 | (uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV); | ||
| 117 | } | ||
| 118 | return RET_SUCCESS; | ||
| 119 | } | ||
| 120 | |||
| 121 | int32_t CDownsampling::GetAlignedIndex (const int32_t kiSrcWidth) { | ||
| 122 | int32_t iAlignIndex = 3; | ||
| 123 | if ((kiSrcWidth & 0x1f) == 0) // x32 | ||
| 124 | iAlignIndex = 0; | ||
| 125 | else if ((kiSrcWidth & 0x0f) == 0) // x16 | ||
| 126 | iAlignIndex = 1; | ||
| 127 | else if ((kiSrcWidth & 0x07) == 0) // x8 | ||
| 128 | iAlignIndex = 2; | ||
| 129 | else | ||
| 130 | iAlignIndex = 3; | ||
| 131 | return iAlignIndex; | ||
| 132 | } | ||
| 133 | |||
| 134 | |||
| 135 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,128 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : downsample.h | ||
| 32 | * | ||
| 33 | * \brief : downsample class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/33 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of downsample class | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_DOWNSAMPLE_H | ||
| 43 | #define WELSVP_DOWNSAMPLE_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/WelsFrameWork.h" | ||
| 47 | #include "../../interface/IWelsVP.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | |||
| 52 | typedef void (HalveDownsampleFunc) (uint8_t* pDst, const int32_t kiDstStride, | ||
| 53 | uint8_t* pSrc, const int32_t kiSrcStride, | ||
| 54 | const int32_t kiSrcWidth, const int32_t kiSrcHeight); | ||
| 55 | |||
| 56 | typedef void (GeneralDownsampleFunc) (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 57 | const int32_t kiDstHeight, | ||
| 58 | uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight); | ||
| 59 | |||
| 60 | typedef HalveDownsampleFunc* PHalveDownsampleFunc; | ||
| 61 | typedef GeneralDownsampleFunc* PGeneralDownsampleFunc; | ||
| 62 | |||
| 63 | HalveDownsampleFunc DyadicBilinearDownsampler_c; | ||
| 64 | GeneralDownsampleFunc GeneralBilinearFastDownsampler_c; | ||
| 65 | GeneralDownsampleFunc GeneralBilinearAccurateDownsampler_c; | ||
| 66 | |||
| 67 | typedef struct { | ||
| 68 | // align_index: 0 = x32; 1 = x16; 2 = x8; 3 = common case left; | ||
| 69 | PHalveDownsampleFunc pfHalfAverage[4]; | ||
| 70 | PGeneralDownsampleFunc pfGeneralRatioLuma; | ||
| 71 | PGeneralDownsampleFunc pfGeneralRatioChroma; | ||
| 72 | } SDownsampleFuncs; | ||
| 73 | |||
| 74 | |||
| 75 | #ifdef X86_ASM | ||
| 76 | WELSVP_EXTERN_C_BEGIN | ||
| 77 | // used for scr width is multipler of 8 pixels | ||
| 78 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx8_sse; | ||
| 79 | // iSrcWidth= x16 pixels | ||
| 80 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_sse; | ||
| 81 | // iSrcWidth= x32 pixels | ||
| 82 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse; | ||
| 83 | // used for scr width is multipler of 16 pixels | ||
| 84 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_ssse3; | ||
| 85 | // iSrcWidth= x32 pixels | ||
| 86 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_ssse3; | ||
| 87 | // iSrcWidth= x16 pixels | ||
| 88 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_sse4; | ||
| 89 | // iSrcWidth= x32 pixels | ||
| 90 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse4; | ||
| 91 | |||
| 92 | GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_sse2; | ||
| 93 | GeneralDownsampleFunc GeneralBilinearAccurateDownsamplerWrap_sse2; | ||
| 94 | |||
| 95 | void GeneralBilinearFastDownsampler_sse2 (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 96 | const int32_t kiDstHeight, | ||
| 97 | uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight, | ||
| 98 | const uint32_t kuiScaleX, const uint32_t kuiScaleY); | ||
| 99 | void GeneralBilinearAccurateDownsampler_sse2 (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 100 | const int32_t kiDstHeight, | ||
| 101 | uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight, | ||
| 102 | const uint32_t kuiScaleX, const uint32_t kuiScaleY); | ||
| 103 | WELSVP_EXTERN_C_END | ||
| 104 | #endif | ||
| 105 | |||
| 106 | |||
| 107 | |||
| 108 | |||
| 109 | class CDownsampling : public IStrategy { | ||
| 110 | public: | ||
| 111 | CDownsampling (int32_t iCpuFlag); | ||
| 112 | ~CDownsampling(); | ||
| 113 | |||
| 114 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pDst); | ||
| 115 | |||
| 116 | private: | ||
| 117 | void InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag); | ||
| 118 | |||
| 119 | int32_t GetAlignedIndex (const int32_t kiSrcWidth); | ||
| 120 | |||
| 121 | private: | ||
| 122 | SDownsampleFuncs m_pfDownsample; | ||
| 123 | int32_t m_iCPUFlag; | ||
| 124 | }; | ||
| 125 | |||
| 126 | WELSVP_NAMESPACE_END | ||
| 127 | |||
| 128 | #endif | ||
| @@ -0,0 +1,234 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2008-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * downsample_yuv.c | ||
| 32 | * | ||
| 33 | * Abstract | ||
| 34 | * Implementation for source yuv data downsampling used before spatial encoding. | ||
| 35 | * | ||
| 36 | * History | ||
| 37 | * 10/24/2008 Created | ||
| 38 | * | ||
| 39 | *****************************************************************************/ | ||
| 40 | |||
| 41 | #include "../common/typedef.h" | ||
| 42 | #include "../common/util.h" | ||
| 43 | #include "downsample.h" | ||
| 44 | |||
| 45 | |||
| 46 | WELSVP_NAMESPACE_BEGIN | ||
| 47 | |||
| 48 | |||
| 49 | void DyadicBilinearDownsampler_c (uint8_t* pDst, const int32_t kiDstStride, | ||
| 50 | uint8_t* pSrc, const int32_t kiSrcStride, | ||
| 51 | const int32_t kiSrcWidth, const int32_t kiSrcHeight) | ||
| 52 | |||
| 53 | { | ||
| 54 | uint8_t* pDstLine = pDst; | ||
| 55 | uint8_t* pSrcLine = pSrc; | ||
| 56 | const int32_t kiSrcStridex2 = kiSrcStride << 1; | ||
| 57 | const int32_t kiDstWidth = kiSrcWidth >> 1; | ||
| 58 | const int32_t kiDstHeight = kiSrcHeight >> 1; | ||
| 59 | |||
| 60 | for (int32_t j = 0; j < kiDstHeight; j ++) { | ||
| 61 | for (int32_t i = 0; i < kiDstWidth; i ++) { | ||
| 62 | const int32_t kiSrcX = i << 1; | ||
| 63 | const int32_t kiTempRow1 = (pSrcLine[kiSrcX] + pSrcLine[kiSrcX + 1] + 1) >> 1; | ||
| 64 | const int32_t kiTempRow2 = (pSrcLine[kiSrcX + kiSrcStride] + pSrcLine[kiSrcX + kiSrcStride + 1] + 1) >> 1; | ||
| 65 | |||
| 66 | pDstLine[i] = (uint8_t) ((kiTempRow1 + kiTempRow2 + 1) >> 1); | ||
| 67 | } | ||
| 68 | pDstLine += kiDstStride; | ||
| 69 | pSrcLine += kiSrcStridex2; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | void GeneralBilinearFastDownsampler_c (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 74 | const int32_t kiDstHeight, | ||
| 75 | uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { | ||
| 76 | const uint32_t kuiScaleBitWidth = 16, kuiScaleBitHeight = 15; | ||
| 77 | const uint32_t kuiScaleWidth = (1 << kuiScaleBitWidth), kuiScaleHeight = (1 << kuiScaleBitHeight); | ||
| 78 | int32_t fScalex = (int32_t) ((float_t)kiSrcWidth / (float_t)kiDstWidth * kuiScaleWidth); | ||
| 79 | int32_t fScaley = (int32_t) ((float_t)kiSrcHeight / (float_t)kiDstHeight * kuiScaleHeight); | ||
| 80 | uint32_t x; | ||
| 81 | int32_t iYInverse, iXInverse; | ||
| 82 | |||
| 83 | uint8_t* pByDst = pDst; | ||
| 84 | uint8_t* pByLineDst = pDst; | ||
| 85 | |||
| 86 | iYInverse = 1 << (kuiScaleBitHeight - 1); | ||
| 87 | for (int32_t i = 0; i < kiDstHeight - 1; i++) { | ||
| 88 | int32_t iYy = iYInverse >> kuiScaleBitHeight; | ||
| 89 | int32_t fv = iYInverse & (kuiScaleHeight - 1); | ||
| 90 | |||
| 91 | uint8_t* pBySrc = pSrc + iYy * kiSrcStride; | ||
| 92 | |||
| 93 | pByDst = pByLineDst; | ||
| 94 | iXInverse = 1 << (kuiScaleBitWidth - 1); | ||
| 95 | for (int32_t j = 0; j < kiDstWidth - 1; j++) { | ||
| 96 | int32_t iXx = iXInverse >> kuiScaleBitWidth; | ||
| 97 | int32_t iFu = iXInverse & (kuiScaleWidth - 1); | ||
| 98 | |||
| 99 | uint8_t* pByCurrent = pBySrc + iXx; | ||
| 100 | uint8_t a, b, c, d; | ||
| 101 | |||
| 102 | a = *pByCurrent; | ||
| 103 | b = * (pByCurrent + 1); | ||
| 104 | c = * (pByCurrent + kiSrcStride); | ||
| 105 | d = * (pByCurrent + kiSrcStride + 1); | ||
| 106 | |||
| 107 | x = (((uint32_t) (kuiScaleWidth - 1 - iFu)) * (kuiScaleHeight - 1 - fv) >> kuiScaleBitWidth) * a; | ||
| 108 | x += (((uint32_t) (iFu)) * (kuiScaleHeight - 1 - fv) >> kuiScaleBitWidth) * b; | ||
| 109 | x += (((uint32_t) (kuiScaleWidth - 1 - iFu)) * (fv) >> kuiScaleBitWidth) * c; | ||
| 110 | x += (((uint32_t) (iFu)) * (fv) >> kuiScaleBitWidth) * d; | ||
| 111 | x >>= (kuiScaleBitHeight - 1); | ||
| 112 | x += 1; | ||
| 113 | x >>= 1; | ||
| 114 | //x = (((__int64)(SCALE_BIG - 1 - iFu))*(SCALE_BIG - 1 - fv)*a + ((__int64)iFu)*(SCALE_BIG - 1 -fv)*b + ((__int64)(SCALE_BIG - 1 -iFu))*fv*c + | ||
| 115 | // ((__int64)iFu)*fv*d + (1 << (2*SCALE_BIT_BIG-1)) ) >> (2*SCALE_BIT_BIG); | ||
| 116 | x = WELS_CLAMP (x, 0, 255); | ||
| 117 | *pByDst++ = (uint8_t)x; | ||
| 118 | |||
| 119 | iXInverse += fScalex; | ||
| 120 | } | ||
| 121 | *pByDst = * (pBySrc + (iXInverse >> kuiScaleBitWidth)); | ||
| 122 | pByLineDst += kiDstStride; | ||
| 123 | iYInverse += fScaley; | ||
| 124 | } | ||
| 125 | |||
| 126 | // last row special | ||
| 127 | { | ||
| 128 | int32_t iYy = iYInverse >> kuiScaleBitHeight; | ||
| 129 | uint8_t* pBySrc = pSrc + iYy * kiSrcStride; | ||
| 130 | |||
| 131 | pByDst = pByLineDst; | ||
| 132 | iXInverse = 1 << (kuiScaleBitWidth - 1); | ||
| 133 | for (int32_t j = 0; j < kiDstWidth; j++) { | ||
| 134 | int32_t iXx = iXInverse >> kuiScaleBitWidth; | ||
| 135 | *pByDst++ = * (pBySrc + iXx); | ||
| 136 | |||
| 137 | iXInverse += fScalex; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | void GeneralBilinearAccurateDownsampler_c (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 143 | const int32_t kiDstHeight, | ||
| 144 | uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { | ||
| 145 | const int32_t kiScaleBit = 15; | ||
| 146 | const int32_t kiScale = (1 << kiScaleBit); | ||
| 147 | int32_t iScalex = (int32_t) ((float_t)kiSrcWidth / (float_t)kiDstWidth * kiScale); | ||
| 148 | int32_t iScaley = (int32_t) ((float_t)kiSrcHeight / (float_t)kiDstHeight * kiScale); | ||
| 149 | int64_t x; | ||
| 150 | int32_t iYInverse, iXInverse; | ||
| 151 | |||
| 152 | uint8_t* pByDst = pDst; | ||
| 153 | uint8_t* pByLineDst = pDst; | ||
| 154 | |||
| 155 | iYInverse = 1 << (kiScaleBit - 1); | ||
| 156 | for (int32_t i = 0; i < kiDstHeight - 1; i++) { | ||
| 157 | int32_t iYy = iYInverse >> kiScaleBit; | ||
| 158 | int32_t iFv = iYInverse & (kiScale - 1); | ||
| 159 | |||
| 160 | uint8_t* pBySrc = pSrc + iYy * kiSrcStride; | ||
| 161 | |||
| 162 | pByDst = pByLineDst; | ||
| 163 | iXInverse = 1 << (kiScaleBit - 1); | ||
| 164 | for (int32_t j = 0; j < kiDstWidth - 1; j++) { | ||
| 165 | int32_t iXx = iXInverse >> kiScaleBit; | ||
| 166 | int32_t iFu = iXInverse & (kiScale - 1); | ||
| 167 | |||
| 168 | uint8_t* pByCurrent = pBySrc + iXx; | ||
| 169 | uint8_t a, b, c, d; | ||
| 170 | |||
| 171 | a = *pByCurrent; | ||
| 172 | b = * (pByCurrent + 1); | ||
| 173 | c = * (pByCurrent + kiSrcStride); | ||
| 174 | d = * (pByCurrent + kiSrcStride + 1); | ||
| 175 | |||
| 176 | x = (((int64_t) (kiScale - 1 - iFu)) * (kiScale - 1 - iFv) * a + ((int64_t)iFu) * (kiScale - 1 - iFv) * b + ((int64_t) ( | ||
| 177 | kiScale - 1 - iFu)) * iFv * c + | ||
| 178 | ((int64_t)iFu) * iFv * d + (int64_t) (1 << (2 * kiScaleBit - 1))) >> (2 * kiScaleBit); | ||
| 179 | x = WELS_CLAMP (x, 0, 255); | ||
| 180 | *pByDst++ = (uint8_t)x; | ||
| 181 | |||
| 182 | iXInverse += iScalex; | ||
| 183 | } | ||
| 184 | *pByDst = * (pBySrc + (iXInverse >> kiScaleBit)); | ||
| 185 | pByLineDst += kiDstStride; | ||
| 186 | iYInverse += iScaley; | ||
| 187 | } | ||
| 188 | |||
| 189 | // last row special | ||
| 190 | { | ||
| 191 | int32_t iYy = iYInverse >> kiScaleBit; | ||
| 192 | uint8_t* pBySrc = pSrc + iYy * kiSrcStride; | ||
| 193 | |||
| 194 | pByDst = pByLineDst; | ||
| 195 | iXInverse = 1 << (kiScaleBit - 1); | ||
| 196 | for (int32_t j = 0; j < kiDstWidth; j++) { | ||
| 197 | int32_t iXx = iXInverse >> kiScaleBit; | ||
| 198 | *pByDst++ = * (pBySrc + iXx); | ||
| 199 | |||
| 200 | iXInverse += iScalex; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | |||
| 206 | #ifdef X86_ASM | ||
| 207 | //void GeneralBilinearFastDownsamplerWrap_sse2 (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 208 | // const int32_t kiDstHeight, | ||
| 209 | // uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { | ||
| 210 | // const int32_t kiScaleBitWidth = 16, kiScaleBitHeight = 15; | ||
| 211 | // const uint32_t kuiScaleWidth = (1 << kiScaleBitWidth), kuiScaleHeight = (1 << kiScaleBitHeight); | ||
| 212 | // | ||
| 213 | // uint32_t uiScalex = (uint32_t) ((float_t)kiSrcWidth / (float_t)kiDstWidth * kuiScaleWidth); | ||
| 214 | // uint32_t uiScaley = (uint32_t) ((float_t)kiSrcHeight / (float_t)kiDstHeight * kuiScaleHeight); | ||
| 215 | // | ||
| 216 | // GeneralBilinearFastDownsampler_sse2 (pDst, kiDstStride, kiDstWidth, kiDstHeight, | ||
| 217 | // pSrc, kiSrcStride, kiSrcWidth, kiSrcHeight, uiScalex, uiScaley); | ||
| 218 | //} | ||
| 219 | // | ||
| 220 | //void GeneralBilinearAccurateDownsamplerWrap_sse2 (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth, | ||
| 221 | // const int32_t kiDstHeight, | ||
| 222 | // uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) { | ||
| 223 | // const int32_t kiScaleBit = 15; | ||
| 224 | // const uint32_t kuiScale = (1 << kiScaleBit); | ||
| 225 | // | ||
| 226 | // uint32_t uiScalex = (uint32_t) ((float_t)kiSrcWidth / (float_t)kiDstWidth * kuiScale); | ||
| 227 | // uint32_t uiScaley = (uint32_t) ((float_t)kiSrcHeight / (float_t)kiDstHeight * kuiScale); | ||
| 228 | // | ||
| 229 | // GeneralBilinearAccurateDownsampler_sse2 (pDst, kiDstStride, kiDstWidth, kiDstHeight, | ||
| 230 | // pSrc, kiSrcStride, kiSrcWidth, kiSrcHeight, uiScalex, uiScaley); | ||
| 231 | //} | ||
| 232 | #endif //X86_ASM | ||
| 233 | |||
| 234 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,93 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "imagerotate.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 39 | |||
| 40 | CImageRotating::CImageRotating (int32_t iCpuFlag) { | ||
| 41 | m_iCPUFlag = iCpuFlag; | ||
| 42 | m_eMethod = METHOD_IMAGE_ROTATE; | ||
| 43 | WelsMemset (&m_pfRotateImage, 0, sizeof (m_pfRotateImage)); | ||
| 44 | InitImageRotateFuncs (m_pfRotateImage, m_iCPUFlag); | ||
| 45 | } | ||
| 46 | |||
| 47 | CImageRotating::~CImageRotating() { | ||
| 48 | } | ||
| 49 | |||
| 50 | void CImageRotating::InitImageRotateFuncs (SImageRotateFuncs& sImageRotateFuncs, int32_t iCpuFlag) { | ||
| 51 | sImageRotateFuncs.pfImageRotate90D = ImageRotate90D_c; | ||
| 52 | sImageRotateFuncs.pfImageRotate180D = ImageRotate180D_c; | ||
| 53 | sImageRotateFuncs.pfImageRotate270D = ImageRotate270D_c; | ||
| 54 | } | ||
| 55 | EResult CImageRotating::ProcessImageRotate (int32_t iType, uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, | ||
| 56 | uint32_t iHeight, uint8_t* pDst) { | ||
| 57 | if (iType == 90) { | ||
| 58 | m_pfRotateImage.pfImageRotate90D (pSrc, uiBytesPerPixel, iWidth, iHeight, pDst); | ||
| 59 | } else if (iType == 180) { | ||
| 60 | m_pfRotateImage.pfImageRotate180D (pSrc, uiBytesPerPixel, iWidth, iHeight, pDst); | ||
| 61 | } else if (iType == 270) { | ||
| 62 | m_pfRotateImage.pfImageRotate270D (pSrc, uiBytesPerPixel, iWidth, iHeight, pDst); | ||
| 63 | } else { | ||
| 64 | return RET_NOTSUPPORTED; | ||
| 65 | } | ||
| 66 | return RET_SUCCESS; | ||
| 67 | } | ||
| 68 | |||
| 69 | EResult CImageRotating::Process (int32_t iType, SPixMap* pSrc, SPixMap* pDst) { | ||
| 70 | EResult eReturn = RET_INVALIDPARAM; | ||
| 71 | |||
| 72 | if ((pSrc->eFormat == VIDEO_FORMAT_RGBA) || | ||
| 73 | (pSrc->eFormat == VIDEO_FORMAT_BGRA) || | ||
| 74 | (pSrc->eFormat == VIDEO_FORMAT_ABGR) || | ||
| 75 | (pSrc->eFormat == VIDEO_FORMAT_ARGB)) { | ||
| 76 | eReturn = ProcessImageRotate (iType, (uint8_t*)pSrc->pPixel[0], pSrc->iSizeInBits * 8, pSrc->sRect.iRectWidth, | ||
| 77 | pSrc->sRect.iRectHeight, (uint8_t*)pDst->pPixel[0]); | ||
| 78 | } else if (pSrc->eFormat == VIDEO_FORMAT_I420) { | ||
| 79 | ProcessImageRotate (iType, (uint8_t*)pSrc->pPixel[0], pSrc->iSizeInBits * 8, pSrc->sRect.iRectWidth, | ||
| 80 | pSrc->sRect.iRectHeight, (uint8_t*)pDst->pPixel[0]); | ||
| 81 | ProcessImageRotate (iType, (uint8_t*)pSrc->pPixel[1], pSrc->iSizeInBits * 8, (pSrc->sRect.iRectWidth >> 1), | ||
| 82 | (pSrc->sRect.iRectHeight >> 1), (uint8_t*)pDst->pPixel[1]); | ||
| 83 | eReturn = ProcessImageRotate (iType, (uint8_t*)pSrc->pPixel[2], pSrc->iSizeInBits * 8, (pSrc->sRect.iRectWidth >> 1), | ||
| 84 | (pSrc->sRect.iRectHeight >> 1), (uint8_t*)pDst->pPixel[2]); | ||
| 85 | } else { | ||
| 86 | eReturn = RET_NOTSUPPORTED; | ||
| 87 | } | ||
| 88 | |||
| 89 | return eReturn; | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 93 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,85 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : downsample.h | ||
| 32 | * | ||
| 33 | * \brief : image rotate class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/04/06 | ||
| 36 | * | ||
| 37 | * \description : | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_IMAGEROTATE_H | ||
| 43 | #define WELSVP_IMAGEROTATE_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/WelsFrameWork.h" | ||
| 47 | #include "../../interface/IWelsVP.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | typedef void (ImageRotateFunc) (uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight, | ||
| 52 | uint8_t* pDst); | ||
| 53 | |||
| 54 | typedef ImageRotateFunc* ImageRotateFuncPtr; | ||
| 55 | |||
| 56 | ImageRotateFunc ImageRotate90D_c; | ||
| 57 | ImageRotateFunc ImageRotate180D_c; | ||
| 58 | ImageRotateFunc ImageRotate270D_c; | ||
| 59 | |||
| 60 | typedef struct { | ||
| 61 | ImageRotateFuncPtr pfImageRotate90D; | ||
| 62 | ImageRotateFuncPtr pfImageRotate180D; | ||
| 63 | ImageRotateFuncPtr pfImageRotate270D; | ||
| 64 | } SImageRotateFuncs; | ||
| 65 | |||
| 66 | class CImageRotating : public IStrategy { | ||
| 67 | public: | ||
| 68 | CImageRotating (int32_t iCpuFlag); | ||
| 69 | ~CImageRotating(); | ||
| 70 | |||
| 71 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pDst); | ||
| 72 | |||
| 73 | private: | ||
| 74 | void InitImageRotateFuncs (SImageRotateFuncs& pf, int32_t iCpuFlag); | ||
| 75 | EResult ProcessImageRotate (int32_t iType, uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight, | ||
| 76 | uint8_t* pDst); | ||
| 77 | |||
| 78 | private: | ||
| 79 | SImageRotateFuncs m_pfRotateImage; | ||
| 80 | int32_t m_iCPUFlag; | ||
| 81 | }; | ||
| 82 | |||
| 83 | WELSVP_NAMESPACE_END | ||
| 84 | |||
| 85 | #endif | ||
| @@ -0,0 +1,66 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * image_rotate.c | ||
| 32 | * | ||
| 33 | * Created on 11-2-21. | ||
| 34 | * | ||
| 35 | */ | ||
| 36 | |||
| 37 | #include "imagerotate.h" | ||
| 38 | #include "../common/cpu.h" | ||
| 39 | |||
| 40 | WELSVP_NAMESPACE_BEGIN | ||
| 41 | |||
| 42 | void ImageRotate90D_c (uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight, uint8_t* pDst) { | ||
| 43 | for (uint32_t j = 0; j < iHeight; j++) { | ||
| 44 | for (uint32_t i = 0; i < iWidth; i++) { | ||
| 45 | for (uint32_t n = 0; n < uiBytesPerPixel; n++) | ||
| 46 | pDst[ (i * iHeight + iHeight - 1 - j)*uiBytesPerPixel + n] = pSrc[ (iWidth * j + i) * uiBytesPerPixel + n]; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | void ImageRotate180D_c (uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight, uint8_t* pDst) { | ||
| 51 | for (uint32_t j = 0; j < iHeight; j++) { | ||
| 52 | for (uint32_t i = 0; i < iWidth; i++) { | ||
| 53 | for (uint32_t n = 0; n < uiBytesPerPixel; n++) | ||
| 54 | pDst[ ((iHeight - 1 - j)*iWidth + iWidth - 1 - i)*uiBytesPerPixel + n] = pSrc[ (iWidth * j + i) * uiBytesPerPixel + n]; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | } | ||
| 58 | void ImageRotate270D_c (uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight, uint8_t* pDst) { | ||
| 59 | for (uint32_t j = 0; j < iWidth; j++) { | ||
| 60 | for (uint32_t i = 0; i < iHeight; i++) { | ||
| 61 | for (uint32_t n = 0; n < uiBytesPerPixel; n++) | ||
| 62 | pDst[ ((iWidth - 1 - j)*iHeight + i)*uiBytesPerPixel + n] = pSrc[ (iWidth * i + j) * uiBytesPerPixel + n]; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | } | ||
| 66 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,136 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "SceneChangeDetection.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | #define HIGH_MOTION_BLOCK_THRESHOLD 320 | ||
| 39 | #define SCENE_CHANGE_MOTION_RATIO 0.85f | ||
| 40 | |||
| 41 | |||
| 42 | |||
| 43 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 44 | |||
| 45 | CSceneChangeDetection::CSceneChangeDetection (int32_t iCpuFlag) { | ||
| 46 | m_iCpuFlag = iCpuFlag; | ||
| 47 | m_eMethod = METHOD_SCENE_CHANGE_DETECTION; | ||
| 48 | m_pfSad = NULL; | ||
| 49 | WelsMemset (&m_sSceneChangeParam, 0, sizeof (m_sSceneChangeParam)); | ||
| 50 | InitSadFuncs (m_pfSad, m_iCpuFlag); | ||
| 51 | } | ||
| 52 | |||
| 53 | CSceneChangeDetection::~CSceneChangeDetection() { | ||
| 54 | } | ||
| 55 | |||
| 56 | EResult CSceneChangeDetection::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 57 | EResult eReturn = RET_INVALIDPARAM; | ||
| 58 | |||
| 59 | int32_t iWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 60 | int32_t iHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 61 | int32_t iBlock8x8Width = iWidth >> 3; | ||
| 62 | int32_t iBlock8x8Height = iHeight >> 3; | ||
| 63 | int32_t iBlock8x8Num = iBlock8x8Width * iBlock8x8Height; | ||
| 64 | int32_t iSceneChangeThreshold = WelsStaticCast (int32_t, SCENE_CHANGE_MOTION_RATIO * iBlock8x8Num + 0.5f + PESN); | ||
| 65 | |||
| 66 | int32_t iBlockSad = 0; | ||
| 67 | int32_t iMotionBlockNum = 0; | ||
| 68 | |||
| 69 | uint8_t* pRefY = NULL, *pCurY = NULL; | ||
| 70 | int32_t iRefStride = 0, iCurStride = 0; | ||
| 71 | int32_t iRefRowStride = 0, iCurRowStride = 0; | ||
| 72 | |||
| 73 | uint8_t* pRefTmp = NULL, *pCurTmp = NULL; | ||
| 74 | |||
| 75 | pRefY = (uint8_t*)pRefPixMap->pPixel[0]; | ||
| 76 | pCurY = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 77 | |||
| 78 | iRefStride = pRefPixMap->iStride[0]; | ||
| 79 | iCurStride = pSrcPixMap->iStride[0]; | ||
| 80 | |||
| 81 | iRefRowStride = pRefPixMap->iStride[0] << 3; | ||
| 82 | iCurRowStride = pSrcPixMap->iStride[0] << 3; | ||
| 83 | |||
| 84 | m_sSceneChangeParam.bSceneChangeFlag = 0; | ||
| 85 | |||
| 86 | for (int32_t j = 0; j < iBlock8x8Height; j ++) { | ||
| 87 | pRefTmp = pRefY; | ||
| 88 | pCurTmp = pCurY; | ||
| 89 | |||
| 90 | for (int32_t i = 0; i < iBlock8x8Width; i++) { | ||
| 91 | iBlockSad = m_pfSad (pRefTmp, iRefStride, pCurTmp, iCurStride); | ||
| 92 | |||
| 93 | iMotionBlockNum += (iBlockSad > HIGH_MOTION_BLOCK_THRESHOLD); | ||
| 94 | |||
| 95 | pRefTmp += 8; | ||
| 96 | pCurTmp += 8; | ||
| 97 | } | ||
| 98 | |||
| 99 | pRefY += iRefRowStride; | ||
| 100 | pCurY += iCurRowStride; | ||
| 101 | } | ||
| 102 | |||
| 103 | if (iMotionBlockNum >= iSceneChangeThreshold) { | ||
| 104 | m_sSceneChangeParam.bSceneChangeFlag = 1; | ||
| 105 | } | ||
| 106 | |||
| 107 | eReturn = RET_SUCCESS; | ||
| 108 | |||
| 109 | return eReturn; | ||
| 110 | } | ||
| 111 | |||
| 112 | |||
| 113 | EResult CSceneChangeDetection::Get (int32_t iType, void* pParam) { | ||
| 114 | if (pParam == NULL) { | ||
| 115 | return RET_INVALIDPARAM; | ||
| 116 | } | ||
| 117 | |||
| 118 | * (SSceneChangeResult*)pParam = m_sSceneChangeParam; | ||
| 119 | |||
| 120 | return RET_SUCCESS; | ||
| 121 | } | ||
| 122 | |||
| 123 | /////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 124 | |||
| 125 | void CSceneChangeDetection::InitSadFuncs (SadFuncPtr& pfSad, int32_t iCpuFlag) { | ||
| 126 | pfSad = WelsSampleSad8x8_c; | ||
| 127 | |||
| 128 | #ifdef X86_ASM | ||
| 129 | if (iCpuFlag & WELS_CPU_SSE2) { | ||
| 130 | pfSad = WelsSampleSad8x8_sse21; | ||
| 131 | } | ||
| 132 | #endif | ||
| 133 | } | ||
| 134 | |||
| 135 | |||
| 136 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,72 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : SceneChangeDetection.h | ||
| 32 | * | ||
| 33 | * \brief : scene change detection class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/14 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of scene change detection class | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_SCENECHANGEDETECTION_H | ||
| 43 | #define WELSVP_SCENECHANGEDETECTION_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/memory.h" | ||
| 47 | #include "../common/WelsFrameWork.h" | ||
| 48 | #include "../../interface/IWelsVP.h" | ||
| 49 | #include "SceneChangeDetectionCommon.h" | ||
| 50 | |||
| 51 | WELSVP_NAMESPACE_BEGIN | ||
| 52 | |||
| 53 | class CSceneChangeDetection : public IStrategy { | ||
| 54 | public: | ||
| 55 | CSceneChangeDetection (int32_t iCpuFlag); | ||
| 56 | ~CSceneChangeDetection(); | ||
| 57 | |||
| 58 | EResult Process (int32_t iType, SPixMap* pSrc, SPixMap* pRef); | ||
| 59 | EResult Get (int32_t iType, void* pParam); | ||
| 60 | |||
| 61 | private: | ||
| 62 | void InitSadFuncs (SadFuncPtr& pfSadFunc, int32_t iCpuFlag); | ||
| 63 | |||
| 64 | private: | ||
| 65 | SadFuncPtr m_pfSad; | ||
| 66 | int32_t m_iCpuFlag; | ||
| 67 | SSceneChangeResult m_sSceneChangeParam; | ||
| 68 | }; | ||
| 69 | |||
| 70 | WELSVP_NAMESPACE_END | ||
| 71 | |||
| 72 | #endif | ||
| @@ -0,0 +1,60 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "SceneChangeDetectionCommon.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | |||
| 39 | int32_t WelsSampleSad8x8_c (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY) { | ||
| 40 | int32_t iSadSum = 0; | ||
| 41 | uint8_t* pSrcA = pSrcY; | ||
| 42 | uint8_t* pSrcB = pRefY; | ||
| 43 | for (int32_t i = 0; i < 8; i++) { | ||
| 44 | iSadSum += WELS_ABS ((pSrcA[0] - pSrcB[0])); | ||
| 45 | iSadSum += WELS_ABS ((pSrcA[1] - pSrcB[1])); | ||
| 46 | iSadSum += WELS_ABS ((pSrcA[2] - pSrcB[2])); | ||
| 47 | iSadSum += WELS_ABS ((pSrcA[3] - pSrcB[3])); | ||
| 48 | iSadSum += WELS_ABS ((pSrcA[4] - pSrcB[4])); | ||
| 49 | iSadSum += WELS_ABS ((pSrcA[5] - pSrcB[5])); | ||
| 50 | iSadSum += WELS_ABS ((pSrcA[6] - pSrcB[6])); | ||
| 51 | iSadSum += WELS_ABS ((pSrcA[7] - pSrcB[7])); | ||
| 52 | |||
| 53 | pSrcA += iSrcStrideY; | ||
| 54 | pSrcB += iRefStrideY; | ||
| 55 | } | ||
| 56 | |||
| 57 | return iSadSum; | ||
| 58 | } | ||
| 59 | |||
| 60 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : SceneChangeDetectionCommon.h | ||
| 32 | * | ||
| 33 | * \brief : scene change detection class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/14 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of scene change detection class | ||
| 38 | * | ||
| 39 | */ | ||
| 40 | |||
| 41 | #ifndef WELSVP_SCENECHANGEDETECTIONCOMMON_H | ||
| 42 | #define WELSVP_SCENECHANGEDETECTIONCOMMON_H | ||
| 43 | |||
| 44 | #include "../common/util.h" | ||
| 45 | #include "../common/memory.h" | ||
| 46 | #include "../common/WelsFrameWork.h" | ||
| 47 | #include "../../interface/IWelsVP.h" | ||
| 48 | |||
| 49 | WELSVP_NAMESPACE_BEGIN | ||
| 50 | |||
| 51 | typedef int32_t (SadFunc) (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY); | ||
| 52 | |||
| 53 | typedef SadFunc* SadFuncPtr; | ||
| 54 | |||
| 55 | SadFunc WelsSampleSad8x8_c; | ||
| 56 | |||
| 57 | #ifdef X86_ASM | ||
| 58 | WELSVP_EXTERN_C_BEGIN | ||
| 59 | SadFunc WelsSampleSad8x8_sse21; | ||
| 60 | WELSVP_EXTERN_C_END | ||
| 61 | #endif | ||
| 62 | |||
| 63 | WELSVP_NAMESPACE_END | ||
| 64 | |||
| 65 | #endif | ||
| @@ -0,0 +1,595 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "../common/typedef.h" | ||
| 34 | #include "../common/util.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | void VAACalcSadSsd_c (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, int32_t iPicStride, | ||
| 39 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* psqsum16x16, int32_t* psqdiff16x16) { | ||
| 40 | uint8_t* tmp_ref = pRefData; | ||
| 41 | uint8_t* tmp_cur = pCurData; | ||
| 42 | int32_t iMbWidth = (iPicWidth >> 4); | ||
| 43 | int32_t mb_heigth = (iPicHeight >> 4); | ||
| 44 | int32_t mb_index = 0; | ||
| 45 | int32_t pic_stride_x8 = iPicStride << 3; | ||
| 46 | int32_t step = (iPicStride << 4) - iPicWidth; | ||
| 47 | |||
| 48 | *pFrameSad = 0; | ||
| 49 | for (int32_t i = 0; i < mb_heigth; i ++) { | ||
| 50 | for (int32_t j = 0; j < iMbWidth; j ++) { | ||
| 51 | int32_t k, l; | ||
| 52 | int32_t l_sad, l_sqdiff, l_sum, l_sqsum; | ||
| 53 | uint8_t* tmp_cur_row; | ||
| 54 | uint8_t* tmp_ref_row; | ||
| 55 | |||
| 56 | pSum16x16[mb_index] = 0; | ||
| 57 | psqsum16x16[mb_index] = 0; | ||
| 58 | psqdiff16x16[mb_index] = 0; | ||
| 59 | |||
| 60 | l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 61 | tmp_cur_row = tmp_cur; | ||
| 62 | tmp_ref_row = tmp_ref; | ||
| 63 | for (k = 0; k < 8; k ++) { | ||
| 64 | for (l = 0; l < 8; l ++) { | ||
| 65 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 66 | l_sad += diff; | ||
| 67 | l_sqdiff += diff * diff; | ||
| 68 | l_sum += tmp_cur_row[l]; | ||
| 69 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 70 | } | ||
| 71 | tmp_cur_row += iPicStride; | ||
| 72 | tmp_ref_row += iPicStride; | ||
| 73 | } | ||
| 74 | *pFrameSad += l_sad; | ||
| 75 | pSad8x8[ (mb_index << 2) + 0] = l_sad; | ||
| 76 | pSum16x16[mb_index] += l_sum; | ||
| 77 | psqsum16x16[mb_index] += l_sqsum; | ||
| 78 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 79 | |||
| 80 | l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 81 | tmp_cur_row = tmp_cur + 8; | ||
| 82 | tmp_ref_row = tmp_ref + 8; | ||
| 83 | for (k = 0; k < 8; k ++) { | ||
| 84 | for (l = 0; l < 8; l ++) { | ||
| 85 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 86 | l_sad += diff; | ||
| 87 | l_sqdiff += diff * diff; | ||
| 88 | l_sum += tmp_cur_row[l]; | ||
| 89 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 90 | } | ||
| 91 | tmp_cur_row += iPicStride; | ||
| 92 | tmp_ref_row += iPicStride; | ||
| 93 | } | ||
| 94 | *pFrameSad += l_sad; | ||
| 95 | pSad8x8[ (mb_index << 2) + 1] = l_sad; | ||
| 96 | pSum16x16[mb_index] += l_sum; | ||
| 97 | psqsum16x16[mb_index] += l_sqsum; | ||
| 98 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 99 | |||
| 100 | l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 101 | tmp_cur_row = tmp_cur + pic_stride_x8; | ||
| 102 | tmp_ref_row = tmp_ref + pic_stride_x8; | ||
| 103 | for (k = 0; k < 8; k ++) { | ||
| 104 | for (l = 0; l < 8; l ++) { | ||
| 105 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 106 | l_sad += diff; | ||
| 107 | l_sqdiff += diff * diff; | ||
| 108 | l_sum += tmp_cur_row[l]; | ||
| 109 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 110 | } | ||
| 111 | tmp_cur_row += iPicStride; | ||
| 112 | tmp_ref_row += iPicStride; | ||
| 113 | } | ||
| 114 | *pFrameSad += l_sad; | ||
| 115 | pSad8x8[ (mb_index << 2) + 2] = l_sad; | ||
| 116 | pSum16x16[mb_index] += l_sum; | ||
| 117 | psqsum16x16[mb_index] += l_sqsum; | ||
| 118 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 119 | |||
| 120 | l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 121 | tmp_cur_row = tmp_cur + pic_stride_x8 + 8; | ||
| 122 | tmp_ref_row = tmp_ref + pic_stride_x8 + 8; | ||
| 123 | for (k = 0; k < 8; k ++) { | ||
| 124 | for (l = 0; l < 8; l ++) { | ||
| 125 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 126 | l_sad += diff; | ||
| 127 | l_sqdiff += diff * diff; | ||
| 128 | l_sum += tmp_cur_row[l]; | ||
| 129 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 130 | } | ||
| 131 | tmp_cur_row += iPicStride; | ||
| 132 | tmp_ref_row += iPicStride; | ||
| 133 | } | ||
| 134 | *pFrameSad += l_sad; | ||
| 135 | pSad8x8[ (mb_index << 2) + 3] = l_sad; | ||
| 136 | pSum16x16[mb_index] += l_sum; | ||
| 137 | psqsum16x16[mb_index] += l_sqsum; | ||
| 138 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 139 | |||
| 140 | |||
| 141 | tmp_ref += 16; | ||
| 142 | tmp_cur += 16; | ||
| 143 | ++mb_index; | ||
| 144 | } | ||
| 145 | tmp_ref += step; | ||
| 146 | tmp_cur += step; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | void VAACalcSadVar_c (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, int32_t iPicStride, | ||
| 150 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* psqsum16x16) { | ||
| 151 | uint8_t* tmp_ref = pRefData; | ||
| 152 | uint8_t* tmp_cur = pCurData; | ||
| 153 | int32_t iMbWidth = (iPicWidth >> 4); | ||
| 154 | int32_t mb_heigth = (iPicHeight >> 4); | ||
| 155 | int32_t mb_index = 0; | ||
| 156 | int32_t pic_stride_x8 = iPicStride << 3; | ||
| 157 | int32_t step = (iPicStride << 4) - iPicWidth; | ||
| 158 | |||
| 159 | *pFrameSad = 0; | ||
| 160 | for (int32_t i = 0; i < mb_heigth; i ++) { | ||
| 161 | for (int32_t j = 0; j < iMbWidth; j ++) { | ||
| 162 | int32_t k, l; | ||
| 163 | int32_t l_sad, l_sum, l_sqsum; | ||
| 164 | uint8_t* tmp_cur_row; | ||
| 165 | uint8_t* tmp_ref_row; | ||
| 166 | |||
| 167 | pSum16x16[mb_index] = 0; | ||
| 168 | psqsum16x16[mb_index] = 0; | ||
| 169 | |||
| 170 | l_sad = l_sum = l_sqsum = 0; | ||
| 171 | tmp_cur_row = tmp_cur; | ||
| 172 | tmp_ref_row = tmp_ref; | ||
| 173 | for (k = 0; k < 8; k ++) { | ||
| 174 | for (l = 0; l < 8; l ++) { | ||
| 175 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 176 | l_sad += diff; | ||
| 177 | l_sum += tmp_cur_row[l]; | ||
| 178 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 179 | } | ||
| 180 | tmp_cur_row += iPicStride; | ||
| 181 | tmp_ref_row += iPicStride; | ||
| 182 | } | ||
| 183 | *pFrameSad += l_sad; | ||
| 184 | pSad8x8[ (mb_index << 2) + 0] = l_sad; | ||
| 185 | pSum16x16[mb_index] += l_sum; | ||
| 186 | psqsum16x16[mb_index] += l_sqsum; | ||
| 187 | |||
| 188 | l_sad = l_sum = l_sqsum = 0; | ||
| 189 | tmp_cur_row = tmp_cur + 8; | ||
| 190 | tmp_ref_row = tmp_ref + 8; | ||
| 191 | for (k = 0; k < 8; k ++) { | ||
| 192 | for (l = 0; l < 8; l ++) { | ||
| 193 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 194 | l_sad += diff; | ||
| 195 | l_sum += tmp_cur_row[l]; | ||
| 196 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 197 | } | ||
| 198 | tmp_cur_row += iPicStride; | ||
| 199 | tmp_ref_row += iPicStride; | ||
| 200 | } | ||
| 201 | *pFrameSad += l_sad; | ||
| 202 | pSad8x8[ (mb_index << 2) + 1] = l_sad; | ||
| 203 | pSum16x16[mb_index] += l_sum; | ||
| 204 | psqsum16x16[mb_index] += l_sqsum; | ||
| 205 | |||
| 206 | l_sad = l_sum = l_sqsum = 0; | ||
| 207 | tmp_cur_row = tmp_cur + pic_stride_x8; | ||
| 208 | tmp_ref_row = tmp_ref + pic_stride_x8; | ||
| 209 | for (k = 0; k < 8; k ++) { | ||
| 210 | for (l = 0; l < 8; l ++) { | ||
| 211 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 212 | l_sad += diff; | ||
| 213 | l_sum += tmp_cur_row[l]; | ||
| 214 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 215 | } | ||
| 216 | tmp_cur_row += iPicStride; | ||
| 217 | tmp_ref_row += iPicStride; | ||
| 218 | } | ||
| 219 | *pFrameSad += l_sad; | ||
| 220 | pSad8x8[ (mb_index << 2) + 2] = l_sad; | ||
| 221 | pSum16x16[mb_index] += l_sum; | ||
| 222 | psqsum16x16[mb_index] += l_sqsum; | ||
| 223 | |||
| 224 | l_sad = l_sum = l_sqsum = 0; | ||
| 225 | tmp_cur_row = tmp_cur + pic_stride_x8 + 8; | ||
| 226 | tmp_ref_row = tmp_ref + pic_stride_x8 + 8; | ||
| 227 | for (k = 0; k < 8; k ++) { | ||
| 228 | for (l = 0; l < 8; l ++) { | ||
| 229 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 230 | l_sad += diff; | ||
| 231 | l_sum += tmp_cur_row[l]; | ||
| 232 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 233 | } | ||
| 234 | tmp_cur_row += iPicStride; | ||
| 235 | tmp_ref_row += iPicStride; | ||
| 236 | } | ||
| 237 | *pFrameSad += l_sad; | ||
| 238 | pSad8x8[ (mb_index << 2) + 3] = l_sad; | ||
| 239 | pSum16x16[mb_index] += l_sum; | ||
| 240 | psqsum16x16[mb_index] += l_sqsum; | ||
| 241 | |||
| 242 | |||
| 243 | tmp_ref += 16; | ||
| 244 | tmp_cur += 16; | ||
| 245 | ++mb_index; | ||
| 246 | } | ||
| 247 | tmp_ref += step; | ||
| 248 | tmp_cur += step; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | |||
| 253 | void VAACalcSad_c (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, int32_t iPicStride, | ||
| 254 | int32_t* pFrameSad, int32_t* pSad8x8) { | ||
| 255 | uint8_t* tmp_ref = pRefData; | ||
| 256 | uint8_t* tmp_cur = pCurData; | ||
| 257 | int32_t iMbWidth = (iPicWidth >> 4); | ||
| 258 | int32_t mb_heigth = (iPicHeight >> 4); | ||
| 259 | int32_t mb_index = 0; | ||
| 260 | int32_t pic_stride_x8 = iPicStride << 3; | ||
| 261 | int32_t step = (iPicStride << 4) - iPicWidth; | ||
| 262 | |||
| 263 | *pFrameSad = 0; | ||
| 264 | for (int32_t i = 0; i < mb_heigth; i ++) { | ||
| 265 | for (int32_t j = 0; j < iMbWidth; j ++) { | ||
| 266 | int32_t k, l; | ||
| 267 | int32_t l_sad; | ||
| 268 | uint8_t* tmp_cur_row; | ||
| 269 | uint8_t* tmp_ref_row; | ||
| 270 | |||
| 271 | l_sad = 0; | ||
| 272 | tmp_cur_row = tmp_cur; | ||
| 273 | tmp_ref_row = tmp_ref; | ||
| 274 | for (k = 0; k < 8; k ++) { | ||
| 275 | for (l = 0; l < 8; l ++) { | ||
| 276 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 277 | l_sad += diff; | ||
| 278 | } | ||
| 279 | tmp_cur_row += iPicStride; | ||
| 280 | tmp_ref_row += iPicStride; | ||
| 281 | } | ||
| 282 | *pFrameSad += l_sad; | ||
| 283 | pSad8x8[ (mb_index << 2) + 0] = l_sad; | ||
| 284 | |||
| 285 | l_sad = 0; | ||
| 286 | tmp_cur_row = tmp_cur + 8; | ||
| 287 | tmp_ref_row = tmp_ref + 8; | ||
| 288 | for (k = 0; k < 8; k ++) { | ||
| 289 | for (l = 0; l < 8; l ++) { | ||
| 290 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 291 | l_sad += diff; | ||
| 292 | } | ||
| 293 | tmp_cur_row += iPicStride; | ||
| 294 | tmp_ref_row += iPicStride; | ||
| 295 | } | ||
| 296 | *pFrameSad += l_sad; | ||
| 297 | pSad8x8[ (mb_index << 2) + 1] = l_sad; | ||
| 298 | |||
| 299 | l_sad = 0; | ||
| 300 | tmp_cur_row = tmp_cur + pic_stride_x8; | ||
| 301 | tmp_ref_row = tmp_ref + pic_stride_x8; | ||
| 302 | for (k = 0; k < 8; k ++) { | ||
| 303 | for (l = 0; l < 8; l ++) { | ||
| 304 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 305 | l_sad += diff; | ||
| 306 | } | ||
| 307 | tmp_cur_row += iPicStride; | ||
| 308 | tmp_ref_row += iPicStride; | ||
| 309 | } | ||
| 310 | *pFrameSad += l_sad; | ||
| 311 | pSad8x8[ (mb_index << 2) + 2] = l_sad; | ||
| 312 | |||
| 313 | l_sad = 0; | ||
| 314 | tmp_cur_row = tmp_cur + pic_stride_x8 + 8; | ||
| 315 | tmp_ref_row = tmp_ref + pic_stride_x8 + 8; | ||
| 316 | for (k = 0; k < 8; k ++) { | ||
| 317 | for (l = 0; l < 8; l ++) { | ||
| 318 | int32_t diff = WELS_ABS (tmp_cur_row[l] - tmp_ref_row[l]); | ||
| 319 | l_sad += diff; | ||
| 320 | } | ||
| 321 | tmp_cur_row += iPicStride; | ||
| 322 | tmp_ref_row += iPicStride; | ||
| 323 | } | ||
| 324 | *pFrameSad += l_sad; | ||
| 325 | pSad8x8[ (mb_index << 2) + 3] = l_sad; | ||
| 326 | |||
| 327 | tmp_ref += 16; | ||
| 328 | tmp_cur += 16; | ||
| 329 | ++mb_index; | ||
| 330 | } | ||
| 331 | tmp_ref += step; | ||
| 332 | tmp_cur += step; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | void VAACalcSadSsdBgd_c (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 337 | int32_t iPicStride, | ||
| 338 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* psqsum16x16, int32_t* psqdiff16x16, int32_t* pSd8x8, | ||
| 339 | uint8_t* pMad8x8) | ||
| 340 | |||
| 341 | { | ||
| 342 | uint8_t* tmp_ref = pRefData; | ||
| 343 | uint8_t* tmp_cur = pCurData; | ||
| 344 | int32_t iMbWidth = (iPicWidth >> 4); | ||
| 345 | int32_t mb_heigth = (iPicHeight >> 4); | ||
| 346 | int32_t mb_index = 0; | ||
| 347 | int32_t pic_stride_x8 = iPicStride << 3; | ||
| 348 | int32_t step = (iPicStride << 4) - iPicWidth; | ||
| 349 | |||
| 350 | *pFrameSad = 0; | ||
| 351 | for (int32_t i = 0; i < mb_heigth; i ++) { | ||
| 352 | for (int32_t j = 0; j < iMbWidth; j ++) { | ||
| 353 | int32_t k, l; | ||
| 354 | int32_t l_sad, l_sqdiff, l_sum, l_sqsum, l_sd, l_mad; | ||
| 355 | uint8_t* tmp_cur_row; | ||
| 356 | uint8_t* tmp_ref_row; | ||
| 357 | |||
| 358 | pSum16x16[mb_index] = 0; | ||
| 359 | psqsum16x16[mb_index] = 0; | ||
| 360 | psqdiff16x16[mb_index] = 0; | ||
| 361 | |||
| 362 | l_sd = l_mad = l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 363 | tmp_cur_row = tmp_cur; | ||
| 364 | tmp_ref_row = tmp_ref; | ||
| 365 | for (k = 0; k < 8; k ++) { | ||
| 366 | for (l = 0; l < 8; l ++) { | ||
| 367 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 368 | int32_t abs_diff = WELS_ABS (diff); | ||
| 369 | |||
| 370 | l_sd += diff; | ||
| 371 | if (abs_diff > l_mad) { | ||
| 372 | l_mad = abs_diff; | ||
| 373 | } | ||
| 374 | l_sad += abs_diff; | ||
| 375 | l_sqdiff += abs_diff * abs_diff; | ||
| 376 | l_sum += tmp_cur_row[l]; | ||
| 377 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 378 | } | ||
| 379 | tmp_cur_row += iPicStride; | ||
| 380 | tmp_ref_row += iPicStride; | ||
| 381 | } | ||
| 382 | *pFrameSad += l_sad; | ||
| 383 | pSad8x8[ (mb_index << 2) + 0] = l_sad; | ||
| 384 | pSum16x16[mb_index] += l_sum; | ||
| 385 | psqsum16x16[mb_index] += l_sqsum; | ||
| 386 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 387 | pSd8x8[ (mb_index << 2) + 0] = l_sd; | ||
| 388 | pMad8x8[ (mb_index << 2) + 0] = l_mad; | ||
| 389 | |||
| 390 | |||
| 391 | l_sd = l_mad = l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 392 | tmp_cur_row = tmp_cur + 8; | ||
| 393 | tmp_ref_row = tmp_ref + 8; | ||
| 394 | for (k = 0; k < 8; k ++) { | ||
| 395 | for (l = 0; l < 8; l ++) { | ||
| 396 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 397 | int32_t abs_diff = WELS_ABS (diff); | ||
| 398 | |||
| 399 | l_sd += diff; | ||
| 400 | if (abs_diff > l_mad) { | ||
| 401 | l_mad = abs_diff; | ||
| 402 | } | ||
| 403 | l_sad += abs_diff; | ||
| 404 | l_sqdiff += abs_diff * abs_diff; | ||
| 405 | l_sum += tmp_cur_row[l]; | ||
| 406 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 407 | } | ||
| 408 | tmp_cur_row += iPicStride; | ||
| 409 | tmp_ref_row += iPicStride; | ||
| 410 | } | ||
| 411 | *pFrameSad += l_sad; | ||
| 412 | pSad8x8[ (mb_index << 2) + 1] = l_sad; | ||
| 413 | pSum16x16[mb_index] += l_sum; | ||
| 414 | psqsum16x16[mb_index] += l_sqsum; | ||
| 415 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 416 | pSd8x8[ (mb_index << 2) + 1] = l_sd; | ||
| 417 | pMad8x8[ (mb_index << 2) + 1] = l_mad; | ||
| 418 | |||
| 419 | l_sd = l_mad = l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 420 | tmp_cur_row = tmp_cur + pic_stride_x8; | ||
| 421 | tmp_ref_row = tmp_ref + pic_stride_x8; | ||
| 422 | for (k = 0; k < 8; k ++) { | ||
| 423 | for (l = 0; l < 8; l ++) { | ||
| 424 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 425 | int32_t abs_diff = WELS_ABS (diff); | ||
| 426 | |||
| 427 | l_sd += diff; | ||
| 428 | if (abs_diff > l_mad) { | ||
| 429 | l_mad = abs_diff; | ||
| 430 | } | ||
| 431 | l_sad += abs_diff; | ||
| 432 | l_sqdiff += abs_diff * abs_diff; | ||
| 433 | l_sum += tmp_cur_row[l]; | ||
| 434 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 435 | } | ||
| 436 | tmp_cur_row += iPicStride; | ||
| 437 | tmp_ref_row += iPicStride; | ||
| 438 | } | ||
| 439 | *pFrameSad += l_sad; | ||
| 440 | pSad8x8[ (mb_index << 2) + 2] = l_sad; | ||
| 441 | pSum16x16[mb_index] += l_sum; | ||
| 442 | psqsum16x16[mb_index] += l_sqsum; | ||
| 443 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 444 | pSd8x8[ (mb_index << 2) + 2] = l_sd; | ||
| 445 | pMad8x8[ (mb_index << 2) + 2] = l_mad; | ||
| 446 | |||
| 447 | l_sd = l_mad = l_sad = l_sqdiff = l_sum = l_sqsum = 0; | ||
| 448 | tmp_cur_row = tmp_cur + pic_stride_x8 + 8; | ||
| 449 | tmp_ref_row = tmp_ref + pic_stride_x8 + 8; | ||
| 450 | for (k = 0; k < 8; k ++) { | ||
| 451 | for (l = 0; l < 8; l ++) { | ||
| 452 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 453 | int32_t abs_diff = WELS_ABS (diff); | ||
| 454 | |||
| 455 | l_sd += diff; | ||
| 456 | if (abs_diff > l_mad) { | ||
| 457 | l_mad = abs_diff; | ||
| 458 | } | ||
| 459 | l_sad += abs_diff; | ||
| 460 | l_sqdiff += abs_diff * abs_diff; | ||
| 461 | l_sum += tmp_cur_row[l]; | ||
| 462 | l_sqsum += tmp_cur_row[l] * tmp_cur_row[l]; | ||
| 463 | } | ||
| 464 | tmp_cur_row += iPicStride; | ||
| 465 | tmp_ref_row += iPicStride; | ||
| 466 | } | ||
| 467 | *pFrameSad += l_sad; | ||
| 468 | pSad8x8[ (mb_index << 2) + 3] = l_sad; | ||
| 469 | pSum16x16[mb_index] += l_sum; | ||
| 470 | psqsum16x16[mb_index] += l_sqsum; | ||
| 471 | psqdiff16x16[mb_index] += l_sqdiff; | ||
| 472 | pSd8x8[ (mb_index << 2) + 3] = l_sd; | ||
| 473 | pMad8x8[ (mb_index << 2) + 3] = l_mad; | ||
| 474 | |||
| 475 | tmp_ref += 16; | ||
| 476 | tmp_cur += 16; | ||
| 477 | ++mb_index; | ||
| 478 | } | ||
| 479 | tmp_ref += step; | ||
| 480 | tmp_cur += step; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | void VAACalcSadBgd_c (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, int32_t iPicStride, | ||
| 485 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSd8x8, uint8_t* pMad8x8) { | ||
| 486 | uint8_t* tmp_ref = pRefData; | ||
| 487 | uint8_t* tmp_cur = pCurData; | ||
| 488 | int32_t iMbWidth = (iPicWidth >> 4); | ||
| 489 | int32_t mb_heigth = (iPicHeight >> 4); | ||
| 490 | int32_t mb_index = 0; | ||
| 491 | int32_t pic_stride_x8 = iPicStride << 3; | ||
| 492 | int32_t step = (iPicStride << 4) - iPicWidth; | ||
| 493 | |||
| 494 | *pFrameSad = 0; | ||
| 495 | for (int32_t i = 0; i < mb_heigth; i ++) { | ||
| 496 | for (int32_t j = 0; j < iMbWidth; j ++) { | ||
| 497 | int32_t k, l; | ||
| 498 | int32_t l_sad, l_sd, l_mad; | ||
| 499 | uint8_t* tmp_cur_row; | ||
| 500 | uint8_t* tmp_ref_row; | ||
| 501 | |||
| 502 | l_mad = l_sd = l_sad = 0; | ||
| 503 | tmp_cur_row = tmp_cur; | ||
| 504 | tmp_ref_row = tmp_ref; | ||
| 505 | for (k = 0; k < 8; k ++) { | ||
| 506 | for (l = 0; l < 8; l ++) { | ||
| 507 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 508 | int32_t abs_diff = WELS_ABS (diff); | ||
| 509 | l_sd += diff; | ||
| 510 | l_sad += abs_diff; | ||
| 511 | if (abs_diff > l_mad) { | ||
| 512 | l_mad = abs_diff; | ||
| 513 | } | ||
| 514 | } | ||
| 515 | tmp_cur_row += iPicStride; | ||
| 516 | tmp_ref_row += iPicStride; | ||
| 517 | } | ||
| 518 | *pFrameSad += l_sad; | ||
| 519 | pSad8x8[ (mb_index << 2) + 0] = l_sad; | ||
| 520 | pSd8x8[ (mb_index << 2) + 0] = l_sd; | ||
| 521 | pMad8x8[ (mb_index << 2) + 0] = l_mad; | ||
| 522 | |||
| 523 | l_mad = l_sd = l_sad = 0; | ||
| 524 | tmp_cur_row = tmp_cur + 8; | ||
| 525 | tmp_ref_row = tmp_ref + 8; | ||
| 526 | for (k = 0; k < 8; k ++) { | ||
| 527 | for (l = 0; l < 8; l ++) { | ||
| 528 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 529 | int32_t abs_diff = WELS_ABS (diff); | ||
| 530 | l_sd += diff; | ||
| 531 | l_sad += abs_diff; | ||
| 532 | if (abs_diff > l_mad) { | ||
| 533 | l_mad = abs_diff; | ||
| 534 | } | ||
| 535 | } | ||
| 536 | tmp_cur_row += iPicStride; | ||
| 537 | tmp_ref_row += iPicStride; | ||
| 538 | } | ||
| 539 | *pFrameSad += l_sad; | ||
| 540 | pSad8x8[ (mb_index << 2) + 1] = l_sad; | ||
| 541 | pSd8x8[ (mb_index << 2) + 1] = l_sd; | ||
| 542 | pMad8x8[ (mb_index << 2) + 1] = l_mad; | ||
| 543 | |||
| 544 | l_mad = l_sd = l_sad = 0; | ||
| 545 | tmp_cur_row = tmp_cur + pic_stride_x8; | ||
| 546 | tmp_ref_row = tmp_ref + pic_stride_x8; | ||
| 547 | for (k = 0; k < 8; k ++) { | ||
| 548 | for (l = 0; l < 8; l ++) { | ||
| 549 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 550 | int32_t abs_diff = WELS_ABS (diff); | ||
| 551 | l_sd += diff; | ||
| 552 | l_sad += abs_diff; | ||
| 553 | if (abs_diff > l_mad) { | ||
| 554 | l_mad = abs_diff; | ||
| 555 | } | ||
| 556 | } | ||
| 557 | tmp_cur_row += iPicStride; | ||
| 558 | tmp_ref_row += iPicStride; | ||
| 559 | } | ||
| 560 | *pFrameSad += l_sad; | ||
| 561 | pSad8x8[ (mb_index << 2) + 2] = l_sad; | ||
| 562 | pSd8x8[ (mb_index << 2) + 2] = l_sd; | ||
| 563 | pMad8x8[ (mb_index << 2) + 2] = l_mad; | ||
| 564 | |||
| 565 | l_mad = l_sd = l_sad = 0; | ||
| 566 | tmp_cur_row = tmp_cur + pic_stride_x8 + 8; | ||
| 567 | tmp_ref_row = tmp_ref + pic_stride_x8 + 8; | ||
| 568 | for (k = 0; k < 8; k ++) { | ||
| 569 | for (l = 0; l < 8; l ++) { | ||
| 570 | int32_t diff = tmp_cur_row[l] - tmp_ref_row[l]; | ||
| 571 | int32_t abs_diff = WELS_ABS (diff); | ||
| 572 | l_sd += diff; | ||
| 573 | l_sad += abs_diff; | ||
| 574 | if (abs_diff > l_mad) { | ||
| 575 | l_mad = abs_diff; | ||
| 576 | } | ||
| 577 | } | ||
| 578 | tmp_cur_row += iPicStride; | ||
| 579 | tmp_ref_row += iPicStride; | ||
| 580 | } | ||
| 581 | *pFrameSad += l_sad; | ||
| 582 | pSad8x8[ (mb_index << 2) + 3] = l_sad; | ||
| 583 | pSd8x8[ (mb_index << 2) + 3] = l_sd; | ||
| 584 | pMad8x8[ (mb_index << 2) + 3] = l_mad; | ||
| 585 | |||
| 586 | tmp_ref += 16; | ||
| 587 | tmp_cur += 16; | ||
| 588 | ++mb_index; | ||
| 589 | } | ||
| 590 | tmp_ref += step; | ||
| 591 | tmp_cur += step; | ||
| 592 | } | ||
| 593 | } | ||
| 594 | |||
| 595 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,123 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | */ | ||
| 32 | |||
| 33 | #include "vaacalculation.h" | ||
| 34 | #include "../common/cpu.h" | ||
| 35 | |||
| 36 | WELSVP_NAMESPACE_BEGIN | ||
| 37 | |||
| 38 | |||
| 39 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | CVAACalculation::CVAACalculation (int32_t iCpuFlag) { | ||
| 42 | m_iCPUFlag = iCpuFlag; | ||
| 43 | m_eMethod = METHOD_VAA_STATISTICS; | ||
| 44 | |||
| 45 | WelsMemset (&m_sCalcParam, 0, sizeof (m_sCalcParam)); | ||
| 46 | WelsMemset (&m_sVaaFuncs, 0, sizeof (m_sVaaFuncs)); | ||
| 47 | InitVaaFuncs (m_sVaaFuncs, m_iCPUFlag); | ||
| 48 | } | ||
| 49 | |||
| 50 | CVAACalculation::~CVAACalculation() { | ||
| 51 | } | ||
| 52 | |||
| 53 | void CVAACalculation::InitVaaFuncs (SVaaFuncs& sVaaFuncs, int32_t iCpuFlag) { | ||
| 54 | sVaaFuncs.pfVAACalcSad = VAACalcSad_c; | ||
| 55 | sVaaFuncs.pfVAACalcSadBgd = VAACalcSadBgd_c; | ||
| 56 | sVaaFuncs.pfVAACalcSadSsd = VAACalcSadSsd_c; | ||
| 57 | sVaaFuncs.pfVAACalcSadSsdBgd = VAACalcSadSsdBgd_c; | ||
| 58 | sVaaFuncs.pfVAACalcSadVar = VAACalcSadVar_c; | ||
| 59 | #ifdef X86_ASM | ||
| 60 | if ((iCpuFlag & WELS_CPU_SSE2) == WELS_CPU_SSE2) { | ||
| 61 | /* sVaaFuncs.pfVAACalcSad = VAACalcSad_sse2; | ||
| 62 | sVaaFuncs.pfVAACalcSadBgd = VAACalcSadBgd_sse2; | ||
| 63 | sVaaFuncs.pfVAACalcSadSsd = VAACalcSadSsd_sse2; | ||
| 64 | sVaaFuncs.pfVAACalcSadSsdBgd = VAACalcSadSsdBgd_sse2; | ||
| 65 | sVaaFuncs.pfVAACalcSadVar = VAACalcSadVar_sse2;*/ | ||
| 66 | } | ||
| 67 | #endif//X86_ASM | ||
| 68 | } | ||
| 69 | |||
| 70 | EResult CVAACalculation::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { | ||
| 71 | uint8_t* pCurData = (uint8_t*)pSrcPixMap->pPixel[0]; | ||
| 72 | uint8_t* pRefData = (uint8_t*)pRefPixMap->pPixel[0]; | ||
| 73 | int32_t iPicWidth = pSrcPixMap->sRect.iRectWidth; | ||
| 74 | int32_t iPicHeight = pSrcPixMap->sRect.iRectHeight; | ||
| 75 | int32_t iPicStride = pSrcPixMap->iStride[0]; | ||
| 76 | |||
| 77 | SVAACalcResult* pResult = m_sCalcParam.pCalcResult; | ||
| 78 | |||
| 79 | if (pCurData == NULL || pRefData == NULL) { | ||
| 80 | return RET_INVALIDPARAM; | ||
| 81 | } | ||
| 82 | |||
| 83 | pResult->pCurY = pCurData; | ||
| 84 | pResult->pRefY = pRefData; | ||
| 85 | if (m_sCalcParam.iCalcBgd) { | ||
| 86 | if (m_sCalcParam.iCalcSsd) { | ||
| 87 | m_sVaaFuncs.pfVAACalcSadSsdBgd (pCurData, pRefData, iPicWidth, iPicHeight, iPicStride, &pResult->iFrameSad, | ||
| 88 | (int32_t*)pResult->pSad8x8, pResult->pSum16x16, pResult->pSumOfSquare16x16, pResult->pSsd16x16, | ||
| 89 | (int32_t*)pResult->pSumOfDiff8x8, (uint8_t*)pResult->pMad8x8); | ||
| 90 | } else { | ||
| 91 | m_sVaaFuncs.pfVAACalcSadBgd (pCurData, pRefData, iPicWidth, iPicHeight, iPicStride, &pResult->iFrameSad, | ||
| 92 | (int32_t*) (pResult->pSad8x8), (int32_t*) (pResult->pSumOfDiff8x8), (uint8_t*)pResult->pMad8x8); | ||
| 93 | } | ||
| 94 | } else { | ||
| 95 | if (m_sCalcParam.iCalcSsd) { | ||
| 96 | m_sVaaFuncs.pfVAACalcSadSsd (pCurData, pRefData, iPicWidth, iPicHeight, iPicStride, &pResult->iFrameSad, | ||
| 97 | (int32_t*)pResult->pSad8x8, pResult->pSum16x16, pResult->pSumOfSquare16x16, pResult->pSsd16x16); | ||
| 98 | } else { | ||
| 99 | if (m_sCalcParam.iCalcVar) { | ||
| 100 | m_sVaaFuncs.pfVAACalcSadVar (pCurData, pRefData, iPicWidth, iPicHeight, iPicStride, &pResult->iFrameSad, | ||
| 101 | (int32_t*)pResult->pSad8x8, pResult->pSum16x16, pResult->pSumOfSquare16x16); | ||
| 102 | } else { | ||
| 103 | m_sVaaFuncs.pfVAACalcSad (pCurData, pRefData, iPicWidth, iPicHeight, iPicStride, &pResult->iFrameSad, | ||
| 104 | (int32_t*)pResult->pSad8x8); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | return RET_SUCCESS; | ||
| 110 | } | ||
| 111 | |||
| 112 | EResult CVAACalculation::Set (int32_t iType, void* pParam) { | ||
| 113 | if (pParam == NULL || ((SVAACalcParam*)pParam)->pCalcResult == NULL) { | ||
| 114 | return RET_INVALIDPARAM; | ||
| 115 | } | ||
| 116 | |||
| 117 | m_sCalcParam = * (SVAACalcParam*)pParam; | ||
| 118 | |||
| 119 | return RET_SUCCESS; | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 123 | WELSVP_NAMESPACE_END | ||
| @@ -0,0 +1,125 @@ | |||
| 1 | /*! | ||
| 2 | * \copy | ||
| 3 | * Copyright (c) 2011-2013, Cisco Systems | ||
| 4 | * All rights reserved. | ||
| 5 | * | ||
| 6 | * Redistribution and use in source and binary forms, with or without | ||
| 7 | * modification, are permitted provided that the following conditions | ||
| 8 | * are met: | ||
| 9 | * | ||
| 10 | * * Redistributions of source code must retain the above copyright | ||
| 11 | * notice, this list of conditions and the following disclaimer. | ||
| 12 | * | ||
| 13 | * * Redistributions in binary form must reproduce the above copyright | ||
| 14 | * notice, this list of conditions and the following disclaimer in | ||
| 15 | * the documentation and/or other materials provided with the | ||
| 16 | * distribution. | ||
| 17 | * | ||
| 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
| 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 24 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 26 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||
| 28 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 29 | * POSSIBILITY OF SUCH DAMAGE. | ||
| 30 | * | ||
| 31 | * \file : vaacalculation.h | ||
| 32 | * | ||
| 33 | * \brief : pVaa calculation class of wels video processor class | ||
| 34 | * | ||
| 35 | * \date : 2011/03/18 | ||
| 36 | * | ||
| 37 | * \description : 1. rewrite the package code of pVaa calculation class | ||
| 38 | * | ||
| 39 | ************************************************************************************* | ||
| 40 | */ | ||
| 41 | |||
| 42 | #ifndef WELSVP_VAACALCULATION_H | ||
| 43 | #define WELSVP_VAACALCULATION_H | ||
| 44 | |||
| 45 | #include "../common/util.h" | ||
| 46 | #include "../common/memory.h" | ||
| 47 | #include "../common/WelsFrameWork.h" | ||
| 48 | #include "../../interface/IWelsVP.h" | ||
| 49 | |||
| 50 | WELSVP_NAMESPACE_BEGIN | ||
| 51 | |||
| 52 | typedef void (VAACalcSadBgdFunc) (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 53 | int32_t iPicStride, | ||
| 54 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSd8x8, uint8_t* pMad8x8); | ||
| 55 | |||
| 56 | typedef void (VAACalcSadSsdBgdFunc) (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 57 | int32_t iPicStride, | ||
| 58 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* pSumSquare16x16, | ||
| 59 | int32_t* pSsd16x16, int32_t* pSd8x8, uint8_t* pMad8x8); | ||
| 60 | |||
| 61 | typedef void (VAACalcSadFunc) (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 62 | int32_t iPicStride, | ||
| 63 | int32_t* pFrameSad, int32_t* pSad8x8); | ||
| 64 | |||
| 65 | typedef void (VAACalcSadVarFunc) (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 66 | int32_t iPicStride, | ||
| 67 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* pSumSquare16x16); | ||
| 68 | |||
| 69 | typedef void (VAACalcSadSsdFunc) (uint8_t* pCurData, uint8_t* pRefData, int32_t iPicWidth, int32_t iPicHeight, | ||
| 70 | int32_t iPicStride, | ||
| 71 | int32_t* pFrameSad, int32_t* pSad8x8, int32_t* pSum16x16, int32_t* pSumSquare16x16, int32_t* pSsd16x16); | ||
| 72 | |||
| 73 | |||
| 74 | typedef VAACalcSadBgdFunc* PVAACalcSadBgdFunc; | ||
| 75 | typedef VAACalcSadSsdBgdFunc* PVAACalcSadSsdBgdFunc; | ||
| 76 | typedef VAACalcSadFunc* PVAACalcSadFunc; | ||
| 77 | typedef VAACalcSadVarFunc* PVAACalcSadVarFunc; | ||
| 78 | typedef VAACalcSadSsdFunc* PVAACalcSadSsdFunc; | ||
| 79 | |||
| 80 | typedef struct TagVaaFuncs { | ||
| 81 | PVAACalcSadBgdFunc pfVAACalcSadBgd; | ||
| 82 | PVAACalcSadSsdBgdFunc pfVAACalcSadSsdBgd; | ||
| 83 | PVAACalcSadFunc pfVAACalcSad; | ||
| 84 | PVAACalcSadVarFunc pfVAACalcSadVar; | ||
| 85 | PVAACalcSadSsdFunc pfVAACalcSadSsd; | ||
| 86 | } SVaaFuncs; | ||
| 87 | |||
| 88 | |||
| 89 | VAACalcSadBgdFunc VAACalcSadBgd_c; | ||
| 90 | VAACalcSadSsdBgdFunc VAACalcSadSsdBgd_c; | ||
| 91 | VAACalcSadFunc VAACalcSad_c; | ||
| 92 | VAACalcSadVarFunc VAACalcSadVar_c; | ||
| 93 | VAACalcSadSsdFunc VAACalcSadSsd_c; | ||
| 94 | |||
| 95 | |||
| 96 | #ifdef X86_ASM | ||
| 97 | WELSVP_EXTERN_C_BEGIN | ||
| 98 | VAACalcSadBgdFunc VAACalcSadBgd_sse2; | ||
| 99 | VAACalcSadSsdBgdFunc VAACalcSadSsdBgd_sse2; | ||
| 100 | VAACalcSadFunc VAACalcSad_sse2; | ||
| 101 | VAACalcSadVarFunc VAACalcSadVar_sse2; | ||
| 102 | VAACalcSadSsdFunc VAACalcSadSsd_sse2; | ||
| 103 | WELSVP_EXTERN_C_END | ||
| 104 | #endif | ||
| 105 | |||
| 106 | class CVAACalculation : public IStrategy { | ||
| 107 | public: | ||
| 108 | CVAACalculation (int32_t iCpuFlag); | ||
| 109 | ~CVAACalculation(); | ||
| 110 | |||
| 111 | EResult Process (int32_t iType, SPixMap* pCurPixMap, SPixMap* pRefPixMap); | ||
| 112 | EResult Set (int32_t iType, void* pParam); | ||
| 113 | |||
| 114 | private: | ||
| 115 | void InitVaaFuncs (SVaaFuncs& sVaaFunc, int32_t iCpuFlag); | ||
| 116 | |||
| 117 | private: | ||
| 118 | SVaaFuncs m_sVaaFuncs; | ||
| 119 | int32_t m_iCPUFlag; | ||
| 120 | SVAACalcParam m_sCalcParam; | ||
| 121 | }; | ||
| 122 | |||
| 123 | WELSVP_NAMESPACE_END | ||
| 124 | |||
| 125 | #endif | ||