History

resolve conflict

volvet committed 12 years ago

Commit ec84f4b1 parent 3958118124 files · +15352 −15696Browse files

Showing the changes to codec/processing/src (43 of 124 files). Show all

Unified · Split

43 files
  1. codec/processing/src/adaptivequantization/AdaptiveQuantization.cpp +256 −0
  2. codec/processing/src/adaptivequantization/AdaptiveQuantization.h +85 −0
  3. codec/processing/src/asm/denoisefilter.asm +279 −0
  4. codec/processing/src/asm/downsample_bilinear.asm +1225 −0
  5. codec/processing/src/asm/intra_pred.asm +1505 −0
  6. codec/processing/src/asm/sad.asm +220 −0
  7. codec/processing/src/asm/vaa.asm +1414 −0
  8. codec/processing/src/backgounddetection/BackgroundDetection.cpp +389 −0
  9. codec/processing/src/backgounddetection/BackgroundDetection.h +106 −0
  10. codec/processing/src/common/WelsFrameWork.cpp +301 −0
  11. codec/processing/src/common/WelsFrameWork.h +130 −0
  12. codec/processing/src/common/WelsFrameWorkEx.cpp +96 −0
  13. codec/processing/src/common/WelsVP.aps +0 −0
  14. codec/processing/src/common/WelsVP.def +36 −0
  15. codec/processing/src/common/WelsVP.rc +115 −0
  16. codec/processing/src/common/cpu.cpp +196 −0
  17. codec/processing/src/common/cpu.h +102 −0
  18. codec/processing/src/common/memory.cpp +117 −0
  19. codec/processing/src/common/memory.h +110 −0
  20. codec/processing/src/common/resource.h +15 −0
  21. codec/processing/src/common/thread.cpp +93 −0
  22. codec/processing/src/common/thread.h +89 −0
  23. codec/processing/src/common/typedef.h +102 −0
  24. codec/processing/src/common/util.cpp +45 −0
  25. codec/processing/src/common/util.h +107 −0
  26. codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp +304 −0
  27. codec/processing/src/complexityanalysis/ComplexityAnalysis.h +83 −0
  28. codec/processing/src/denoise/denoise.cpp +124 −0
  29. codec/processing/src/denoise/denoise.h +111 −0
  30. codec/processing/src/denoise/denoise_filter.cpp +127 −0
  31. codec/processing/src/downsample/downsample.cpp +135 −0
  32. codec/processing/src/downsample/downsample.h +128 −0
  33. codec/processing/src/downsample/downsamplefuncs.cpp +234 −0
  34. codec/processing/src/imagerotate/imagerotate.cpp +93 −0
  35. codec/processing/src/imagerotate/imagerotate.h +85 −0
  36. codec/processing/src/imagerotate/imagerotatefuncs.cpp +66 −0
  37. codec/processing/src/scenechangedetection/SceneChangeDetection.cpp +136 −0
  38. codec/processing/src/scenechangedetection/SceneChangeDetection.h +72 −0
  39. codec/processing/src/scenechangedetection/SceneChangeDetectionCommon.cpp +60 −0
  40. codec/processing/src/scenechangedetection/SceneChangeDetectionCommon.h +65 −0
  41. codec/processing/src/vaacalc/vaacalcfuncs.cpp +595 −0
  42. codec/processing/src/vaacalc/vaacalculation.cpp +123 −0
  43. codec/processing/src/vaacalc/vaacalculation.h +125 −0
codec/processing/src/adaptivequantization/AdaptiveQuantization.cpp+256−0
@@ -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
codec/processing/src/adaptivequantization/AdaptiveQuantization.h+85−0
@@ -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
codec/processing/src/asm/denoisefilter.asm+279−0
@@ -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
codec/processing/src/asm/downsample_bilinear.asm+1225−0
@@ -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
codec/processing/src/asm/intra_pred.asm+1505−0
@@ -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+
codec/processing/src/asm/sad.asm+220−0
@@ -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
codec/processing/src/asm/vaa.asm+1414−0
@@ -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
codec/processing/src/backgounddetection/BackgroundDetection.cpp+389−0
@@ -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
codec/processing/src/backgounddetection/BackgroundDetection.h+106−0
@@ -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
codec/processing/src/common/WelsFrameWork.cpp+301−0
@@ -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
codec/processing/src/common/WelsFrameWork.h+130−0
@@ -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
codec/processing/src/common/WelsFrameWorkEx.cpp+96−0
@@ -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
codec/processing/src/common/WelsVP.aps+0−0

Binary file not shown.

codec/processing/src/common/WelsVP.def+36−0
@@ -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
codec/processing/src/common/WelsVP.rc+115−0
@@ -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+
codec/processing/src/common/cpu.cpp+196−0
@@ -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+
codec/processing/src/common/cpu.h+102−0
@@ -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
codec/processing/src/common/memory.cpp+117−0
@@ -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
codec/processing/src/common/memory.h+110−0
@@ -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+
codec/processing/src/common/resource.h+15−0
@@ -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
codec/processing/src/common/thread.cpp+93−0
@@ -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+
codec/processing/src/common/thread.h+89−0
@@ -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
codec/processing/src/common/typedef.h+102−0
@@ -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
codec/processing/src/common/util.cpp+45−0
@@ -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
codec/processing/src/common/util.h+107−0
@@ -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+
codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp+304−0
@@ -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
codec/processing/src/complexityanalysis/ComplexityAnalysis.h+83−0
@@ -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
codec/processing/src/denoise/denoise.cpp+124−0
@@ -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
codec/processing/src/denoise/denoise.h+111−0
@@ -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
codec/processing/src/denoise/denoise_filter.cpp+127−0
@@ -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
codec/processing/src/downsample/downsample.cpp+135−0
@@ -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
codec/processing/src/downsample/downsample.h+128−0
@@ -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
codec/processing/src/downsample/downsamplefuncs.cpp+234−0
@@ -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
codec/processing/src/imagerotate/imagerotate.cpp+93−0
@@ -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
codec/processing/src/imagerotate/imagerotate.h+85−0
@@ -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
codec/processing/src/imagerotate/imagerotatefuncs.cpp+66−0
@@ -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
codec/processing/src/scenechangedetection/SceneChangeDetection.cpp+136−0
@@ -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
codec/processing/src/scenechangedetection/SceneChangeDetection.h+72−0
@@ -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
codec/processing/src/scenechangedetection/SceneChangeDetectionCommon.cpp+60−0
@@ -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
codec/processing/src/scenechangedetection/SceneChangeDetectionCommon.h+65−0
@@ -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
codec/processing/src/vaacalc/vaacalcfuncs.cpp+595−0
@@ -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
codec/processing/src/vaacalc/vaacalculation.cpp+123−0
@@ -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
codec/processing/src/vaacalc/vaacalculation.h+125−0
@@ -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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

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

Repository code

Go to file
t