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
35WELSVP_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
47CAdaptiveQuantization::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
55CAdaptiveQuantization::~CAdaptiveQuantization() {
56}
57
58EResult 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
197EResult 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
207EResult 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
221void 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
231void 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
256WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51typedef void (VarFunc) (uint8_t* pRefY, int32_t iRefStrideY, uint8_t* pSrc, int32_t iSrcStrideY,
52 SMotionTextureUnit* pMotionTexture);
53
54typedef VarFunc* PVarFunc;
55
56VarFunc SampleVariance16x16_c;
57
58#ifdef X86_ASM
59WELSVP_EXTERN_C_BEGIN
60VarFunc SampleVariance16x16_sse2;
61WELSVP_EXTERN_C_END
62#endif
63
64
65class 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
83WELSVP_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;***********************************************************************
47SECTION .rodata align=16
48
49sse2_32 times 8 dw 32
50sse2_20 times 8 dw 20
51
52
53
54;***********************************************************************
55; Code
56;***********************************************************************
57SECTION .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
166ALIGN 16
167WELS_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
181BilateralLumaFilter8_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
227WELS_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
238ALIGN 16
239WaverageChromaFilter8_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
56SECTION .rodata align=16
57
58;***********************************************************************
59; Various memory constants (trigonometric values or rounding values)
60;***********************************************************************
61
62ALIGN 16
63shufb_mask_low:
64 db 00h, 80h, 02h, 80h, 04h, 80h, 06h, 80h, 08h, 80h, 0ah, 80h, 0ch, 80h, 0eh, 80h
65shufb_mask_high:
66 db 01h, 80h, 03h, 80h, 05h, 80h, 07h, 80h, 09h, 80h, 0bh, 80h, 0dh, 80h, 0fh, 80h
67
68
69ALIGN 16
70
71;***********************************************************************
72; Code
73;***********************************************************************
74
75SECTION .text
76
77WELS_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;***********************************************************************
83ALIGN 16
84DyadicBilinearDownsamplerWidthx32_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
230WELS_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;***********************************************************************
236ALIGN 16
237DyadicBilinearDownsamplerWidthx16_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
334WELS_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;***********************************************************************
340ALIGN 16
341DyadicBilinearDownsamplerWidthx8_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
425WELS_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;***********************************************************************
431ALIGN 16
432DyadicBilinearDownsamplerWidthx32_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
536WELS_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;***********************************************************************
542ALIGN 16
543DyadicBilinearDownsamplerWidthx16_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
626WELS_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;***********************************************************************
632ALIGN 16
633DyadicBilinearDownsamplerWidthx32_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
736WELS_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;***********************************************************************
742ALIGN 16
743DyadicBilinearDownsamplerWidthx16_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
828WELS_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
836ALIGN 16
837GeneralBilinearAccurateDownsampler_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
891DOWNSAMPLE:
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
906HEIGHT:
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
922WIDTH:
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
960WIDTH_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
979LAST_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
990LAST_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
1003LAST_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
1032WELS_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
1040ALIGN 16
1041GeneralBilinearFastDownsampler_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
1095FAST_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
1111FAST_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
1127FAST_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
1157FAST_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
1176FAST_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
1187FAST_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
1200FAST_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
49SECTION .rodata pData
50%else
51SECTION .rodata align=16
52%endif
53
54align 16
55sse2_plane_inc_minus dw -7, -6, -5, -4, -3, -2, -1, 0
56align 16
57sse2_plane_inc dw 1, 2, 3, 4, 5, 6, 7, 8
58align 16
59sse2_plane_dec dw 8, 7, 6, 5, 4, 3, 2, 1
60
61; for chroma plane mode
62sse2_plane_inc_c dw 1, 2, 3, 4
63sse2_plane_dec_c dw 4, 3, 2, 1
64align 16
65sse2_plane_mul_b_c dw -3, -2, -1, 0, 1, 2, 3, 4
66
67align 16
68mmx_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
74align 16
75mmx_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
190SECTION .text
191WELS_EXTERN WelsI4x4LumaPredH_sse2
192WELS_EXTERN WelsI4x4LumaPredDDR_mmx
193WELS_EXTERN WelsI4x4LumaPredDc_sse2
194WELS_EXTERN WelsI16x16LumaPredPlane_sse2
195
196ALIGN 16
197;***********************************************************************
198; void __cdecl WelsI4x4LumaPredH_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride)
199;
200; pred must align to 16
201;***********************************************************************
202WelsI4x4LumaPredH_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;***********************************************************************
238WelsI16x16LumaPredPlane_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
309get_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
341WELS_EXTERN WelsI16x16LumaPredH_sse2
342WelsI16x16LumaPredH_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;***********************************************************************
374WELS_EXTERN WelsI16x16LumaPredV_sse2
375WelsI16x16LumaPredV_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;***********************************************************************
409WELS_EXTERN WelsIChromaPredPlane_sse2
410WelsIChromaPredPlane_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
484get_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
501ALIGN 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;***********************************************************************
514WelsI4x4LumaPredDDR_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
560ALIGN 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;***********************************************************************
573WelsI4x4LumaPredDc_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
609ALIGN 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
634WELS_EXTERN WelsIChromaPredH_mmx
635WelsIChromaPredH_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
671ALIGN 16
672;***********************************************************************
673; void __cdecl WelsI4x4LumaPredV_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride)
674; copy pixels from top 4 pixels
675;***********************************************************************
676WELS_EXTERN WelsI4x4LumaPredV_sse2
677WelsI4x4LumaPredV_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
689ALIGN 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;***********************************************************************
694WELS_EXTERN WelsIChromaPredV_sse2
695WelsIChromaPredV_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;***********************************************************************
741WELS_EXTERN WelsI4x4LumaPredHD_mmx
742WelsI4x4LumaPredHD_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
795ALIGN 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;***********************************************************************
822WELS_EXTERN WelsI4x4LumaPredHU_mmx
823WelsI4x4LumaPredHU_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
878ALIGN 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;***********************************************************************
907WELS_EXTERN WelsI4x4LumaPredVR_mmx
908WelsI4x4LumaPredVR_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
968ALIGN 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;***********************************************************************
995WELS_EXTERN WelsI4x4LumaPredDDL_mmx
996WelsI4x4LumaPredDDL_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
1035ALIGN 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;***********************************************************************
1065WELS_EXTERN WelsI4x4LumaPredVL_mmx
1066WelsI4x4LumaPredVL_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
1101ALIGN 16
1102;***********************************************************************
1103;
1104; void WelsIChromaPredDc_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride)
1105;***********************************************************************
1106WELS_EXTERN WelsIChromaPredDc_sse2
1107WelsIChromaPredDc_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
1195ALIGN 16
1196;***********************************************************************
1197;
1198; void WelsI16x16LumaPredDc_sse2(uint8_t *pred, uint8_t *pRef, int32_t stride)
1199;***********************************************************************
1200WELS_EXTERN WelsI16x16LumaPredDc_sse2
1201WelsI16x16LumaPredDc_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
1265WELS_EXTERN WelsSmpleSatdThree4x4_sse2
1266align 16
1267WelsSmpleSatdThree4x4_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
1443not_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
1488not_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
49and %1, 0x1f|(%3>>1)
50cmp %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;***********************************************************************
75SECTION .text
76
77WELS_EXTERN WelsSampleSad8x8_sse21
78WelsSampleSad8x8_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
334SECTION .text
335
336WELS_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;***********************************************************************
340ALIGN 16
341rc_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
381WELS_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;***********************************************************************
385ALIGN 16
386SampleVariance16x16_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
484WELS_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;*************************************************************************************************************
489ALIGN 16
490abs_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
506mb_width_loop_p:
507 mov edx, esi
508 add edx, eax ; end address
509gom_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
546WELS_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;*************************************************************************************************************
551ALIGN 16
552sum_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
568mb_width_loop_i:
569 mov edx, esi
570 add edx, eax ; end address
571gom_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
621WELS_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
628ALIGN 16
629VAACalcSad_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
652height_loop:
653 mov ecx, dword [iPicWidth]
654 push esi
655 push edi
656width_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
714WELS_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
721ALIGN 16
722VAACalcSadVar_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
752var_height_loop:
753 mov ecx, dword [iPicWidth]
754 mov [tmp_esi], esi
755 mov [tmp_edi], edi
756var_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
850WELS_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
857ALIGN 16
858VAACalcSadSsd_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
894sqdiff_height_loop:
895 mov ecx, dword [iPicWidth]
896 mov [tmp_esi], esi
897 mov [tmp_edi], edi
898sqdiff_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
1006WELS_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
1013ALIGN 16
1014VAACalcSadBgd_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
1044bgd_height_loop:
1045 mov ecx, dword [iPicWidth]
1046 mov [tmp_esi], esi
1047 mov [tmp_edi], edi
1048bgd_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
1185WELS_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
1193ALIGN 16
1194VAACalcSadSsdBgd_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
1228sqdiff_bgd_height_loop:
1229 mov ecx, dword [iPicWidth]
1230 mov [tmp_esi], esi
1231 mov [tmp_edi], edi
1232sqdiff_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
36WELSVP_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
54CBackgroundDetection::CBackgroundDetection (int32_t iCpuFlag) {
55 m_eMethod = METHOD_BACKGROUND_DETECTION;
56 WelsMemset (&m_BgdParam, 0, sizeof (m_BgdParam));
57 m_iLargestFrameSize = 0;
58}
59
60CBackgroundDetection::~CBackgroundDetection() {
61 FreeOUArrayMemory();
62}
63
64EResult 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
97EResult 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
110inline 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
116inline void CBackgroundDetection::FreeOUArrayMemory() {
117 _SafeFree (m_BgdParam.pOU_array);
118}
119
120void 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
162void 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}
194inline 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
205inline 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
238inline 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
268inline 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}
297inline 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
318inline void CBackgroundDetection::SetBackgroundMbFlag (int8_t* pBackgroundMbFlag, int32_t iPicWidthInMb,
319 int32_t iBackgroundMbFlag) {
320 *pBackgroundMbFlag = iBackgroundMbFlag;
321}
322
323inline 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
337void 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
381void 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
389WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51typedef 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
60class 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
104WELSVP_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
47EResult 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
56EResult 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
65WELSVP_NAMESPACE_BEGIN
66
67///////////////////////////////////////////////////////////////////////
68
69EResult 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
81EResult DestroySpecificVpInterface (IWelsVP* pCtx) {
82 _SafeDelete (pCtx);
83
84 return RET_SUCCESS;
85}
86
87///////////////////////////////////////////////////////////////////////////////
88
89CVpFrameWork::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
108CVpFrameWork::~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
119EResult 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
136EResult 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
151EResult CVpFrameWork::Flush (int32_t iType) {
152 EResult eReturn = RET_SUCCESS;
153
154 return eReturn;
155}
156
157EResult 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
182EResult 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
200EResult 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
218EResult CVpFrameWork::SpecialFeature (int32_t iType, void* pIn, void* pOut) {
219 EResult eReturn = RET_SUCCESS;
220
221 return eReturn;
222}
223
224bool_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
259exit:
260 return eReturn;
261}
262
263IStrategy* 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
301WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51EResult CreateSpecificVpInterface (IWelsVP** ppCtx);
52EResult DestroySpecificVpInterface (IWelsVP* pCtx);
53
54EResult CreateSpecificVpInterface (IWelsVPc** ppCtx);
55EResult DestroySpecificVpInterface (IWelsVPc* pCtx);
56
57#define MAX_STRATEGY_NUM (METHOD_MASK - 1)
58
59class 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
98class 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
128WELSVP_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
37WELSVP_NAMESPACE_BEGIN
38
39EResult Init (void* pCtx, int32_t iType, void* pCfg) {
40 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Init (iType, pCfg) : RET_INVALIDPARAM;
41}
42EResult Uninit (void* pCtx, int32_t iType) {
43 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Uninit (iType) : RET_INVALIDPARAM;
44}
45EResult Flush (void* pCtx, int32_t iType) {
46 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Flush (iType) : RET_INVALIDPARAM;
47}
48EResult Process (void* pCtx, int32_t iType, SPixMap* pSrc, SPixMap* dst) {
49 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Process (iType, pSrc, dst) : RET_INVALIDPARAM;
50}
51EResult Get (void* pCtx, int32_t iType, void* pParam) {
52 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Get (iType, pParam) : RET_INVALIDPARAM;
53}
54EResult Set (void* pCtx, int32_t iType, void* pParam) {
55 return pCtx ? WelsStaticCast (IWelsVP*, pCtx)->Set (iType, pParam) : RET_INVALIDPARAM;
56}
57EResult 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
63EResult 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
87EResult DestroySpecificVpInterface (IWelsVPc* pCtx) {
88 if (pCtx) {
89 DestroySpecificVpInterface (WelsStaticCast (IWelsVP*, pCtx->pCtx));
90 _SafeDelete (pCtx);
91 }
92
93 return RET_SUCCESS;
94}
95
96WELSVP_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
33LIBRARY welsvp.dll
34EXPORTS
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
20LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
21#pragma code_page(936)
22#endif //_WIN32
23
24#ifdef APSTUDIO_INVOKED
25/////////////////////////////////////////////////////////////////////////////
26//
27// TEXTINCLUDE
28//
29
301 TEXTINCLUDE
31BEGIN
32 "resource.h\0"
33END
34
352 TEXTINCLUDE
36BEGIN
37 "#include ""windows.h""\r\n"
38 "\0"
39END
40
413 TEXTINCLUDE
42BEGIN
43 "\r\n"
44 "\0"
45END
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
58LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
59#pragma code_page(1252)
60#endif //_WIN32
61
62/////////////////////////////////////////////////////////////////////////////
63//
64// Version
65//
66
67VS_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
79BEGIN
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
99END
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
43WELSVP_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
52uint32_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
185void 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
194WELSVP_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
45WELSVP_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
85WELSVP_EXTERN_C_BEGIN
86
87int32_t WelsCPUIdVerify();
88
89void WelsCPUId (uint32_t uiIndex, uint32_t* pFeatureA, uint32_t* pFeatureB, uint32_t* pFeatureC, uint32_t* pFeatureD);
90int32_t WelsCPUSupportAVX (uint32_t eax, uint32_t ecx);
91int32_t WelsCPUSupportFMA (uint32_t eax, uint32_t ecx);
92
93void WelsEmms();
94
95WELSVP_EXTERN_C_END
96#endif
97
98uint32_t WelsCPUFeatureDetect (int32_t* pNumberOfLogicProcessors);
99
100WELSVP_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
35WELSVP_NAMESPACE_BEGIN
36/////////////////////////////////////////////////////////////////////////////////
37
38void* 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
62void WelsFree (void* pPointer, str_t* pTag) {
63 if (pPointer) {
64 ::free (* (((void**) pPointer) - 1));
65 }
66}
67
68/////////////////////////////////////////////////////////////////////////////
69
70void* 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
94void* 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
117WELSVP_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
48WELSVP_NAMESPACE_BEGIN
49
50inline_t void* WelsMemset (void* pPointer, int32_t iValue, uint32_t uiSize) {
51 return ::memset (pPointer, iValue, uiSize);
52}
53
54inline_t void* WelsMemcpy (void* pDst, const void* kpSrc, uint32_t uiSize) {
55 return ::memcpy (pDst, kpSrc, uiSize);
56}
57
58inline_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*/
73void* 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*/
87void 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*/
103void* WelsRealloc (void* pPointer, uint32_t* pRealSize, const uint32_t kuiSize, str_t* pTag = NULL);
104
105//////////////////////////////////////////////////////////////////////////////////////
106WELSVP_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
42WELSVP_NAMESPACE_BEGIN
43
44#if defined(_WIN32)
45
46WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
47 InitializeCriticalSection (mutex);
48
49 return WELS_THREAD_ERROR_OK;
50}
51
52WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
53 EnterCriticalSection (mutex);
54
55 return WELS_THREAD_ERROR_OK;
56}
57
58WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
59 LeaveCriticalSection (mutex);
60
61 return WELS_THREAD_ERROR_OK;
62}
63
64WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
65 DeleteCriticalSection (mutex);
66
67 return WELS_THREAD_ERROR_OK;
68}
69
70#elif defined(__GNUC__)
71
72WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex) {
73 return pthread_mutex_init (mutex, NULL);
74}
75
76WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex) {
77 return pthread_mutex_lock (mutex);
78}
79
80WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex) {
81 return pthread_mutex_unlock (mutex);
82}
83
84WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex) {
85 return pthread_mutex_destroy (mutex);
86}
87
88#endif
89
90WELSVP_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
60WELSVP_NAMESPACE_BEGIN
61
62#if defined(_WIN32)
63
64typedef HANDLE WELS_THREAD_HANDLE;
65typedef CRITICAL_SECTION WELS_MUTEX;
66
67#elif defined(__GNUC__)
68
69typedef pthread_t WELS_THREAD_HANDLE;
70typedef pthread_mutex_t WELS_MUTEX;
71
72#endif
73
74typedef 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
82WELS_THREAD_ERROR_CODE WelsMutexInit (WELS_MUTEX* mutex);
83WELS_THREAD_ERROR_CODE WelsMutexLock (WELS_MUTEX* mutex);
84WELS_THREAD_ERROR_CODE WelsMutexUnlock (WELS_MUTEX* mutex);
85WELS_THREAD_ERROR_CODE WelsMutexDestroy (WELS_MUTEX* mutex);
86
87WELSVP_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
53WELSVP_NAMESPACE_BEGIN
54
55#if ( defined(_WIN32) || defined(_WIN32) ) && defined(_MSC_VER)
56
57typedef char int8_t ;
58typedef unsigned char uint8_t ;
59typedef short int16_t ;
60typedef unsigned short uint16_t ;
61typedef int int32_t ;
62typedef unsigned int uint32_t ;
63typedef __int64 int64_t ;
64typedef unsigned __int64 uint64_t ;
65#define inline_t _inline
66
67#else // GCC
68
69typedef signed char int8_t
70; // [comment]: some compilers may identify the type "char" as "unsigned char" as default, so declare it explicit
71typedef unsigned char uint8_t ;
72typedef signed short int16_t ;
73typedef unsigned short uint16_t ;
74typedef signed int int32_t ;
75typedef unsigned int uint32_t ;
76typedef long long int64_t ;
77typedef unsigned long long uint64_t ;
78#define inline_t inline
79
80#endif
81
82typedef char str_t ; // [comment]: specific use plain char only for character parameters
83typedef long long_t ;
84typedef int32_t bool_t ;
85
86#if defined(_WIN32) || defined(_MACH_PLATFORM) || defined(__GNUC__)
87typedef float float_t ;
88typedef double double_t ;
89#endif
90
91#ifndef NULL
92#define NULL 0
93#endif
94
95enum {
96 FALSE = 0,
97 TRUE = !FALSE
98};
99
100WELSVP_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
35WELSVP_NAMESPACE_BEGIN
36/////////////////////////////////////////////////////////////////////////////////
37
38
39int32_t WelsStrCmp (const str_t* kpStr1, const str_t* kpStr2) {
40 return ::strcmp (kpStr1, kpStr2);
41}
42
43
44/////////////////////////////////////////////////////////////////////////////////
45WELSVP_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
55WELSVP_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
87inline_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
99int32_t WelsStrCmp (const str_t* kpStr1, const str_t* kpStr2);
100
101
102//////////////////////////////////////////////////////////////////////////////////////
103WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////
40
41CComplexityAnalysis::CComplexityAnalysis (int32_t iCpuFlag) {
42 m_eMethod = METHOD_COMPLEXITY_ANALYSIS;
43 m_pfGomSad = NULL;
44 WelsMemset (&m_sComplexityAnalysisParam, 0, sizeof (m_sComplexityAnalysisParam));
45}
46
47CComplexityAnalysis::~CComplexityAnalysis() {
48}
49
50EResult 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
72EResult 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
82EResult 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///////////////////////////////////////////////////////////////////////////////////////////////
96void 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
107int32_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
143void InitGomSadFunc (PGOMSadFunc& pfGomSad, uint8_t iCalcBgd) {
144 pfGomSad = GomSampleSad;
145
146 if (iCalcBgd) {
147 pfGomSad = GomSampleSadExceptBackground;
148 }
149}
150
151void 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
159void 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
170void 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
242void 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
304WELSVP_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
50WELSVP_NAMESPACE_BEGIN
51
52typedef void (GOMSadFunc) (uint32_t* pGomSad, int32_t* pGomForegroundBlockNum, int32_t* pSad8x8,
53 uint8_t pBackgroundMbFlag);
54
55typedef GOMSadFunc* PGOMSadFunc;
56
57GOMSadFunc GomSampleSad;
58GOMSadFunc GomSampleSadExceptBackground;
59
60class 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
81WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38#define CALC_BI_STRIDE(iWidth, iBitcount) ((((iWidth) * (iBitcount) + 31) & ~31) >> 3)
39
40///////////////////////////////////////////////////////////////////////////////////////////////////////////////
41
42CDenoiser::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
53CDenoiser::~CDenoiser() {
54}
55
56void 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
67EResult 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
92void 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
107void 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
124WELSVP_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
63WELSVP_NAMESPACE_BEGIN
64
65void Gauss3x3Filter (uint8_t* pixels, int32_t stride);
66
67typedef void (DenoiseFilterFunc) (uint8_t* pixels, int32_t stride);
68
69typedef DenoiseFilterFunc* DenoiseFilterFuncPtr;
70
71DenoiseFilterFunc BilateralLumaFilter8_c;
72DenoiseFilterFunc WaverageChromaFilter8_c;
73
74#ifdef X86_ASM
75WELSVP_EXTERN_C_BEGIN
76DenoiseFilterFunc BilateralLumaFilter8_sse2 ;
77DenoiseFilterFunc WaverageChromaFilter8_sse2 ;
78WELSVP_EXTERN_C_END
79#endif
80
81typedef struct TagDenoiseFuncs {
82 DenoiseFilterFuncPtr pfBilateralLumaFilter8;//on 8 samples
83 DenoiseFilterFuncPtr pfWaverageChromaFilter8;//on 8 samples
84} SDenoiseFuncs;
85
86class 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
109WELSVP_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
42WELSVP_NAMESPACE_BEGIN
43
44void 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/***************************************************************************
805x5 filter:
811 1 2 1 1
821 2 4 2 1
832 4 20 4 2
841 2 4 2 1
851 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))
90void 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/***************************************************************************
110edge of y/uv use a 3x3 Gauss filter, radius = 1:
1111 2 1
1122 4 2
1131 2 1
114***************************************************************************/
115void 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
127WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////
40
41CDownsampling::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
48CDownsampling::~CDownsampling() {
49}
50
51void 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
80EResult 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
121int32_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
135WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51
52typedef 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
56typedef 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
60typedef HalveDownsampleFunc* PHalveDownsampleFunc;
61typedef GeneralDownsampleFunc* PGeneralDownsampleFunc;
62
63HalveDownsampleFunc DyadicBilinearDownsampler_c;
64GeneralDownsampleFunc GeneralBilinearFastDownsampler_c;
65GeneralDownsampleFunc GeneralBilinearAccurateDownsampler_c;
66
67typedef 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
76WELSVP_EXTERN_C_BEGIN
77// used for scr width is multipler of 8 pixels
78HalveDownsampleFunc DyadicBilinearDownsamplerWidthx8_sse;
79// iSrcWidth= x16 pixels
80HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_sse;
81// iSrcWidth= x32 pixels
82HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse;
83// used for scr width is multipler of 16 pixels
84HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_ssse3;
85// iSrcWidth= x32 pixels
86HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_ssse3;
87// iSrcWidth= x16 pixels
88HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_sse4;
89// iSrcWidth= x32 pixels
90HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse4;
91
92GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_sse2;
93GeneralDownsampleFunc GeneralBilinearAccurateDownsamplerWrap_sse2;
94
95void 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);
99void 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);
103WELSVP_EXTERN_C_END
104#endif
105
106
107
108
109class 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
126WELSVP_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
46WELSVP_NAMESPACE_BEGIN
47
48
49void 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
73void 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
142void 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
234WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38///////////////////////////////////////////////////////////////////////////////////////////////////////////////
39
40CImageRotating::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
47CImageRotating::~CImageRotating() {
48}
49
50void CImageRotating::InitImageRotateFuncs (SImageRotateFuncs& sImageRotateFuncs, int32_t iCpuFlag) {
51 sImageRotateFuncs.pfImageRotate90D = ImageRotate90D_c;
52 sImageRotateFuncs.pfImageRotate180D = ImageRotate180D_c;
53 sImageRotateFuncs.pfImageRotate270D = ImageRotate270D_c;
54}
55EResult 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
69EResult 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
93WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51typedef void (ImageRotateFunc) (uint8_t* pSrc, uint32_t uiBytesPerPixel, uint32_t iWidth, uint32_t iHeight,
52 uint8_t* pDst);
53
54typedef ImageRotateFunc* ImageRotateFuncPtr;
55
56ImageRotateFunc ImageRotate90D_c;
57ImageRotateFunc ImageRotate180D_c;
58ImageRotateFunc ImageRotate270D_c;
59
60typedef struct {
61 ImageRotateFuncPtr pfImageRotate90D;
62 ImageRotateFuncPtr pfImageRotate180D;
63 ImageRotateFuncPtr pfImageRotate270D;
64} SImageRotateFuncs;
65
66class 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
83WELSVP_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
40WELSVP_NAMESPACE_BEGIN
41
42void 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}
50void 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}
58void 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}
66WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38#define HIGH_MOTION_BLOCK_THRESHOLD 320
39#define SCENE_CHANGE_MOTION_RATIO 0.85f
40
41
42
43///////////////////////////////////////////////////////////////////////////////////////////////////////////////
44
45CSceneChangeDetection::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
53CSceneChangeDetection::~CSceneChangeDetection() {
54}
55
56EResult 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
113EResult 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
125void 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
136WELSVP_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
51WELSVP_NAMESPACE_BEGIN
52
53class 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
70WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38
39int32_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
60WELSVP_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
49WELSVP_NAMESPACE_BEGIN
50
51typedef int32_t (SadFunc) (uint8_t* pSrcY, int32_t iSrcStrideY, uint8_t* pRefY, int32_t iRefStrideY);
52
53typedef SadFunc* SadFuncPtr;
54
55SadFunc WelsSampleSad8x8_c;
56
57#ifdef X86_ASM
58WELSVP_EXTERN_C_BEGIN
59SadFunc WelsSampleSad8x8_sse21;
60WELSVP_EXTERN_C_END
61#endif
62
63WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38void 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}
149void 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
253void 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
336void 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
484void 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
595WELSVP_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
36WELSVP_NAMESPACE_BEGIN
37
38
39///////////////////////////////////////////////////////////////////////////////////////////////////////////////
40
41CVAACalculation::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
50CVAACalculation::~CVAACalculation() {
51}
52
53void 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
70EResult 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
112EResult 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
123WELSVP_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
50WELSVP_NAMESPACE_BEGIN
51
52typedef 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
56typedef 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
61typedef 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
65typedef 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
69typedef 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
74typedef VAACalcSadBgdFunc* PVAACalcSadBgdFunc;
75typedef VAACalcSadSsdBgdFunc* PVAACalcSadSsdBgdFunc;
76typedef VAACalcSadFunc* PVAACalcSadFunc;
77typedef VAACalcSadVarFunc* PVAACalcSadVarFunc;
78typedef VAACalcSadSsdFunc* PVAACalcSadSsdFunc;
79
80typedef struct TagVaaFuncs {
81 PVAACalcSadBgdFunc pfVAACalcSadBgd;
82 PVAACalcSadSsdBgdFunc pfVAACalcSadSsdBgd;
83 PVAACalcSadFunc pfVAACalcSad;
84 PVAACalcSadVarFunc pfVAACalcSadVar;
85 PVAACalcSadSsdFunc pfVAACalcSadSsd;
86} SVaaFuncs;
87
88
89VAACalcSadBgdFunc VAACalcSadBgd_c;
90VAACalcSadSsdBgdFunc VAACalcSadSsdBgd_c;
91VAACalcSadFunc VAACalcSad_c;
92VAACalcSadVarFunc VAACalcSadVar_c;
93VAACalcSadSsdFunc VAACalcSadSsd_c;
94
95
96#ifdef X86_ASM
97WELSVP_EXTERN_C_BEGIN
98VAACalcSadBgdFunc VAACalcSadBgd_sse2;
99VAACalcSadSsdBgdFunc VAACalcSadSsdBgd_sse2;
100VAACalcSadFunc VAACalcSad_sse2;
101VAACalcSadVarFunc VAACalcSadVar_sse2;
102VAACalcSadSsdFunc VAACalcSadSsd_sse2;
103WELSVP_EXTERN_C_END
104#endif
105
106class 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
123WELSVP_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