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/downsample/downsample.cpp (1 of 2 files). Show all

Unified · Split

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

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