History

[Processing] Pick dyadic downsample function based on stride

Assume that data can be written into the padding area following each line. This enables the use of faster routines for more cases. Align downsample buffer stride to a multiple of 32. With this all strides used should be a multiple of 16, which means that use of narrower downsample routines can be dropped altogether.

Sindre Aamås committed 10 years ago

Commit 7cbb75e1 parent 770e48a2 files · +45 −57Browse files

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

Unified · Split

2 files
  1. codec/processing/src/downsample/downsample.cpp +41 −54
  2. codec/processing/src/downsample/downsample.h +4 −3
codec/processing/src/downsample/downsample.cpp+41−54
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232
3333 #include "downsample.h"
3434 #include "cpu.h"
35+#include <cassert>
3536
3637 WELSVP_NAMESPACE_BEGIN
3738 #define MAX_SAMPLE_WIDTH 1920
@@ -75,20 +76,18 @@ void CDownsampling::FreeSampleBuffer() { · 37 unmodified lines
7576 WelsFree (m_pSampleBuffer[i][2]);
7677 }
7778 }
79+
7880 void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag) {
79− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsampler_c;
80− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsampler_c;
81− sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsampler_c;
82− sDownsampleFunc.pfHalfAverage[3] = DyadicBilinearDownsampler_c;
81+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsampler_c;
82+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsampler_c;
8383 sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_c;
8484 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_c;
8585 sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsampler_c;
8686 sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsampler_c;
8787 #if defined(X86_ASM)
8888 if (iCpuFlag & WELS_CPU_SSE) {
89− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_sse;
90− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_sse;
91− sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsamplerWidthx8_sse;
89+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_sse;
90+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsamplerWidthx16_sse;
9291 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_sse;
9392 }
9493 if (iCpuFlag & WELS_CPU_SSE2) {
@@ -96,15 +95,15 @@ void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int · 1 unmodified line
9695 sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_sse2;
9796 }
9897 if (iCpuFlag & WELS_CPU_SSSE3) {
99− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_ssse3;
100− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_ssse3;
98+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_ssse3;
99+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsamplerWidthx16_ssse3;
101100 sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_ssse3;
102101 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_ssse3;
103102 sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_ssse3;
104103 }
105104 if (iCpuFlag & WELS_CPU_SSE41) {
106− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_sse4;
107− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsamplerWidthx16_sse4;
105+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_sse4;
106+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsamplerWidthx16_sse4;
108107 sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_sse4;
109108 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_sse4;
110109 sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_sse41;
@@ -117,10 +116,8 @@ void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int · 6 unmodified lines
117116
118117 #if defined(HAVE_NEON)
119118 if (iCpuFlag & WELS_CPU_NEON) {
120− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_neon;
121− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsampler_neon;
122− sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsampler_neon;
123− sDownsampleFunc.pfHalfAverage[3] = DyadicBilinearDownsampler_neon;
119+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_neon;
120+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsampler_neon;
124121 sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_neon;
125122 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_neon;
126123 sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_neon;
@@ -130,10 +127,8 @@ void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int · 3 unmodified lines
130127
131128 #if defined(HAVE_NEON_AARCH64)
132129 if (iCpuFlag & WELS_CPU_NEON) {
133− sDownsampleFunc.pfHalfAverage[0] = DyadicBilinearDownsamplerWidthx32_AArch64_neon;
134− sDownsampleFunc.pfHalfAverage[1] = DyadicBilinearDownsampler_AArch64_neon;
135− sDownsampleFunc.pfHalfAverage[2] = DyadicBilinearDownsampler_AArch64_neon;
136− sDownsampleFunc.pfHalfAverage[3] = DyadicBilinearDownsampler_AArch64_neon;
130+ sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_AArch64_neon;
131+ sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsampler_AArch64_neon;
137132 sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_AArch64_neon;
138133 sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_AArch64_neon;
139134 sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_AArch64_neon;
@@ -159,14 +154,11 @@ EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDs · 19 unmodified lines
159154 if (iSrcWidthY > MAX_SAMPLE_WIDTH || iSrcHeightY > MAX_SAMPLE_HEIGHT || m_bNoSampleBuffer) {
160155 if ((iSrcWidthY >> 1) == iDstWidthY && (iSrcHeightY >> 1) == iDstHeightY) {
161156 // use half average functions
162− uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
163− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
157+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
164158 (uint8_t*)pSrcPixMap->pPixel[0], pSrcPixMap->iStride[0], iSrcWidthY, iSrcHeightY);
165−
166− iAlignIndex = GetAlignedIndex (iSrcWidthUV);
167− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
159+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
168160 (uint8_t*)pSrcPixMap->pPixel[1], pSrcPixMap->iStride[1], iSrcWidthUV, iSrcHeightUV);
169− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
161+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
170162 (uint8_t*)pSrcPixMap->pPixel[2], pSrcPixMap->iStride[2], iSrcWidthUV, iSrcHeightUV);
171163 } else if ((iSrcWidthY >> 2) == iDstWidthY && (iSrcHeightY >> 2) == iDstHeightY) {
172164
@@ -223,29 +215,23 @@ EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDs · 50 unmodified lines
223215 do {
224216 if ((iHalfSrcWidth == iDstWidthY) && (iHalfSrcHeight == iDstHeightY)) { //end
225217 // use half average functions
226− uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
227− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
218+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[0], pDstPixMap->iStride[0],
228219 (uint8_t*)pSrcY, iSrcStrideY, iSrcWidthY, iSrcHeightY);
229−
230− iAlignIndex = GetAlignedIndex (iSrcWidthUV);
231− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
220+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[1], pDstPixMap->iStride[1],
232221 (uint8_t*)pSrcU, iSrcStrideU, iSrcWidthUV, iSrcHeightUV);
233− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
222+ DownsampleHalfAverage ((uint8_t*)pDstPixMap->pPixel[2], pDstPixMap->iStride[2],
234223 (uint8_t*)pSrcV, iSrcStrideV, iSrcWidthUV, iSrcHeightUV);
235224 break;
236225 } else if (((iHalfSrcWidth >> 1) >= iDstWidthY) && ((iHalfSrcHeight >> 1) >= iDstHeightY)) {
237226 // use half average functions
238− iDstStrideY = iHalfSrcWidth;
239− iDstStrideU = iHalfSrcWidth >> 1;
240− iDstStrideV = iHalfSrcWidth >> 1;
241− uint8_t iAlignIndex = GetAlignedIndex (iSrcWidthY);
242− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstY, iDstStrideY,
227+ iDstStrideY = WELS_ALIGN (iHalfSrcWidth, 32);
228+ iDstStrideU = WELS_ALIGN (iHalfSrcWidth >> 1, 32);
229+ iDstStrideV = WELS_ALIGN (iHalfSrcWidth >> 1, 32);
230+ DownsampleHalfAverage ((uint8_t*)pDstY, iDstStrideY,
243231 (uint8_t*)pSrcY, iSrcStrideY, iSrcWidthY, iSrcHeightY);
244−
245− iAlignIndex = GetAlignedIndex (iSrcWidthUV);
246− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstU, iDstStrideU,
232+ DownsampleHalfAverage ((uint8_t*)pDstU, iDstStrideU,
247233 (uint8_t*)pSrcU, iSrcStrideU, iSrcWidthUV, iSrcHeightUV);
248− m_pfDownsample.pfHalfAverage[iAlignIndex] ((uint8_t*)pDstV, iDstStrideV,
234+ DownsampleHalfAverage ((uint8_t*)pDstV, iDstStrideV,
249235 (uint8_t*)pSrcV, iSrcStrideV, iSrcWidthUV, iSrcHeightUV);
250236
251237 pSrcY = (uint8_t*)pDstY;
@@ -258,9 +244,9 @@ EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDs · 6 unmodified lines
258244 iSrcHeightY = iHalfSrcHeight;
259245 iSrcHeightUV = iHalfSrcHeight >> 1;
260246
261− iSrcStrideY = iSrcWidthY;
262− iSrcStrideU = iSrcWidthUV;
263− iSrcStrideV = iSrcWidthUV;
247+ iSrcStrideY = iDstStrideY;
248+ iSrcStrideU = iDstStrideU;
249+ iSrcStrideV = iDstStrideV;
264250
265251 iHalfSrcWidth >>= 1;
266252 iHalfSrcHeight >>= 1;
@@ -286,17 +272,18 @@ EResult CDownsampling::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pDs · 19 unmodified lines
286272 return RET_SUCCESS;
287273 }
288274
289−int32_t CDownsampling::GetAlignedIndex (const int32_t kiSrcWidth) {
290− int32_t iAlignIndex;
291− if ((kiSrcWidth & 0x1f) == 0) // x32
292− iAlignIndex = 0;
293− else if ((kiSrcWidth & 0x0f) == 0) // x16
294− iAlignIndex = 1;
295− else if ((kiSrcWidth & 0x07) == 0) // x8
296− iAlignIndex = 2;
297− else
298− iAlignIndex = 3;
299− return iAlignIndex;
275+void CDownsampling::DownsampleHalfAverage (uint8_t* pDst, int32_t iDstStride,
276+ uint8_t* pSrc, int32_t iSrcStride, int32_t iSrcWidth, int32_t iSrcHeight) {
277+ if ((iSrcStride & 31) == 0) {
278+ assert ((iDstStride & 15) == 0);
279+ m_pfDownsample.pfHalfAverageWidthx32 (pDst, iDstStride,
280+ pSrc, iSrcStride, WELS_ALIGN (iSrcWidth, 32), iSrcHeight);
281+ } else {
282+ assert ((iSrcStride & 15) == 0);
283+ assert ((iDstStride & 7) == 0);
284+ m_pfDownsample.pfHalfAverageWidthx16 (pDst, iDstStride,
285+ pSrc, iSrcStride, WELS_ALIGN (iSrcWidth, 16), iSrcHeight);
286+ }
300287 }
301288
302289
codec/processing/src/downsample/downsample.h+4−3
@@ -73,8 +73,8 @@ SpecificDownsampleFunc DyadicBilinearOneThirdDownsampler_c; · 72 unmodified lines
7373 SpecificDownsampleFunc DyadicBilinearQuarterDownsampler_c;
7474
7575 typedef struct {
76− // align_index: 0 = x32; 1 = x16; 2 = x8; 3 = common case left;
77− PHalveDownsampleFunc pfHalfAverage[4];
76+ PHalveDownsampleFunc pfHalfAverageWidthx32;
77+ PHalveDownsampleFunc pfHalfAverageWidthx16;
7878 PSpecificDownsampleFunc pfOneThirdDownsampler;
7979 PSpecificDownsampleFunc pfQuarterDownsampler;
8080 PGeneralDownsampleFunc pfGeneralRatioLuma;
@@ -185,7 +185,8 @@ class CDownsampling : public IStrategy { · 104 unmodified lines
185185 private:
186186 void InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int32_t iCpuFlag);
187187
188− int32_t GetAlignedIndex (const int32_t kiSrcWidth);
188+ void DownsampleHalfAverage (uint8_t* pDst, int32_t iDstStride,
189+ uint8_t* pSrc, int32_t iSrcStride, int32_t iSrcWidth, int32_t iSrcHeight);
189190 bool AllocateSampleBuffer();
190191 void FreeSampleBuffer();
191192 private:

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