History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

Showing the changes to codec/decoder/core/src/deblocking.cpp (1 of 308 files). Show all

Unified · Split

codec/decoder/core/src/deblocking.cpp+1013−0
@@ -0,0 +1,1013 @@
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+ * \file deblocking.c
33+ *
34+ * \brief Interfaces introduced in frame deblocking filtering
35+ *
36+ * \date 08/02/2010
37+ *
38+ *************************************************************************************
39+ */
40+
41+#include "deblocking.h"
42+#include "cpu_core.h"
43+#include "fmo.h"
44+
45+namespace WelsDec {
46+
47+#define NO_SUPPORTED_FILTER_IDX (-1)
48+#define LEFT_FLAG_BIT 0
49+#define TOP_FLAG_BIT 1
50+#define LEFT_FLAG_MASK 0x01
51+#define TOP_FLAG_MASK 0x02
52+
53+#define SAME_MB_DIFF_REFIDX
54+#define g_kuiAlphaTable(x) g_kuiAlphaTable[(x)+12]
55+#define g_kiBetaTable(x) g_kiBetaTable[(x)+12]
56+#define g_kiTc0Table(x) g_kiTc0Table[(x)+12]
57+
58+#define MB_BS_MV(iRefIndex, iMotionVector, iMbXy, iMbBn, iIndex, iNeighIndex) \
59+(\
60+ ( iRefIndex[iMbXy][iIndex] - iRefIndex[iMbBn][iNeighIndex] )||\
61+ ( WELS_ABS( iMotionVector[iMbXy][iIndex][0] - iMotionVector[iMbBn][iNeighIndex][0] ) >= 4 ) ||\
62+ ( WELS_ABS( iMotionVector[iMbXy][iIndex][1] - iMotionVector[iMbBn][iNeighIndex][1] ) >= 4 )\
63+)
64+
65+#if defined(SAME_MB_DIFF_REFIDX)
66+#define SMB_EDGE_MV(iRefIndex, iMotionVector, iIndex, iNeighIndex) \
67+(\
68+ ( iRefIndex[iIndex] - iRefIndex[iNeighIndex] )||(\
69+ ( WELS_ABS( iMotionVector[iIndex][0] - iMotionVector[iNeighIndex][0] ) &(~3) ) |\
70+ ( WELS_ABS( iMotionVector[iIndex][1] - iMotionVector[iNeighIndex][1] ) &(~3) ))\
71+)
72+#else
73+#define SMB_EDGE_MV(iRefIndex, iMotionVector, iIndex, iNeighIndex) \
74+(\
75+ !!(( WELS_ABS( iMotionVector[iIndex][0] - iMotionVector[iNeighIndex][0] ) &(~3) ) |( WELS_ABS( iMotionVector[iIndex][1] - iMotionVector[iNeighIndex][1] ) &(~3) ))\
76+)
77+#endif
78+
79+#define BS_EDGE(bsx1, iRefIndex, iMotionVector, iIndex, iNeighIndex) \
80+( (bsx1|SMB_EDGE_MV(iRefIndex, iMotionVector, iIndex, iNeighIndex))<<((uint8_t)(!!bsx1)))
81+
82+#define GET_ALPHA_BETA_FROM_QP(iQp, iAlphaOffset, iBetaOffset, iIndex, iAlpha, iBeta) \
83+{\
84+ iIndex = (iQp + iAlphaOffset);\
85+ iAlpha = g_kuiAlphaTable(iIndex);\
86+ iBeta = g_kiBetaTable((iQp + iBetaOffset));\
87+}
88+
89+static const uint8_t g_kuiAlphaTable[52+24] = { //this table refers to Table 8-16 in H.264/AVC standard
90+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
92+ 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,
93+ 7, 8, 9, 10, 12, 13, 15, 17, 20, 22,
94+ 25, 28, 32, 36, 40, 45, 50, 56, 63, 71,
95+ 80, 90,101,113,127,144,162,182,203,226,
96+ 255, 255
97+ ,255, 255,255, 255,255, 255,255, 255,255, 255,255, 255
98+};
99+
100+static const int8_t g_kiBetaTable[52+24] = { //this table refers to Table 8-16 in H.264/AVC standard
101+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103+ 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,
104+ 3, 3, 3, 4, 4, 4, 6, 6, 7, 7,
105+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
106+ 13, 13, 14, 14, 15, 15, 16, 16, 17, 17,
107+ 18, 18
108+ ,18, 18,18, 18,18, 18,18, 18,18, 18,18, 18
109+};
110+
111+static const int8_t g_kiTc0Table[52+24][4] = { //this table refers Table 8-17 in H.264/AVC standard
112+ { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 },
113+ { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 },
114+ { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 },
115+ { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 },
116+ { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 0 }, { -1, 0, 0, 1 },
117+ { -1, 0, 0, 1 }, { -1, 0, 0, 1 }, { -1, 0, 0, 1 }, { -1, 0, 1, 1 }, { -1, 0, 1, 1 }, { -1, 1, 1, 1 },
118+ { -1, 1, 1, 1 }, { -1, 1, 1, 1 }, { -1, 1, 1, 1 }, { -1, 1, 1, 2 }, { -1, 1, 1, 2 }, { -1, 1, 1, 2 },
119+ { -1, 1, 1, 2 }, { -1, 1, 2, 3 }, { -1, 1, 2, 3 }, { -1, 2, 2, 3 }, { -1, 2, 2, 4 }, { -1, 2, 3, 4 },
120+ { -1, 2, 3, 4 }, { -1, 3, 3, 5 }, { -1, 3, 4, 6 }, { -1, 3, 4, 6 }, { -1, 4, 5, 7 }, { -1, 4, 5, 8 },
121+ { -1, 4, 6, 9 }, { -1, 5, 7,10 }, { -1, 6, 8,11 }, { -1, 6, 8,13 }, { -1, 7,10,14 }, { -1, 8,11,16 },
122+ { -1, 9,12,18 }, { -1, 10,13,20 }, {-1,11,15,23 }, { -1,13,17,25 }
123+ ,{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 }
124+ ,{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 },{ -1,13,17,25 }
125+};
126+
127+static const uint8_t g_kuiTableBIdx[2][8] =
128+{
129+ {0, 4, 8, 12,
130+ 3, 7, 11, 15},
131+
132+ {0, 1, 2, 3 ,
133+ 12, 13, 14, 15},
134+};
135+
136+#define TC0_TBL_LOOKUP(tc, iIndexA, pBS, bChroma) \
137+{\
138+ tc[0] = g_kiTc0Table(iIndexA)[pBS[0]] + bChroma;\
139+ tc[1] = g_kiTc0Table(iIndexA)[pBS[1]] + bChroma;\
140+ tc[2] = g_kiTc0Table(iIndexA)[pBS[2]] + bChroma;\
141+ tc[3] = g_kiTc0Table(iIndexA)[pBS[3]] + bChroma;\
142+}
143+
144+void_t inline DeblockingBSInsideMBAvsbase( int8_t* pNnzTab, uint8_t nBS[2][4][4], int32_t iLShiftFactor )
145+{
146+ uint32_t uiNnz32b0, uiNnz32b1, uiNnz32b2, uiNnz32b3;
147+ FORCE_STACK_ALIGN_1D( uint8_t, uiBsx3, 4, 4 );
148+
149+ uiNnz32b0 = *(uint32_t *)(pNnzTab+0);
150+ uiNnz32b1 = *(uint32_t *)(pNnzTab+4);
151+ uiNnz32b2 = *(uint32_t *)(pNnzTab+8);
152+ uiNnz32b3 = *(uint32_t *)(pNnzTab+12);
153+
154+ *(uint32_t *)uiBsx3 = (uiNnz32b0|(uiNnz32b0>>8))<<iLShiftFactor;
155+ nBS[0][1][0] = uiBsx3[0];
156+ nBS[0][2][0] = uiBsx3[1];
157+ nBS[0][3][0] = uiBsx3[2];
158+
159+ *(uint32_t *)uiBsx3 = (uiNnz32b1|(uiNnz32b1>>8))<<iLShiftFactor;
160+ nBS[0][1][1] = uiBsx3[0];
161+ nBS[0][2][1] = uiBsx3[1];
162+ nBS[0][3][1] = uiBsx3[2];
163+ *(uint32_t *)nBS[1][1] = (uiNnz32b0|uiNnz32b1)<<iLShiftFactor;
164+
165+ *(uint32_t *)uiBsx3 = (uiNnz32b2|(uiNnz32b2>>8))<<iLShiftFactor;
166+ nBS[0][1][2] = uiBsx3[0];
167+ nBS[0][2][2] = uiBsx3[1];
168+ nBS[0][3][2] = uiBsx3[2];
169+ *(uint32_t *)nBS[1][2] = (uiNnz32b1|uiNnz32b2)<<iLShiftFactor;
170+
171+ *(uint32_t *)uiBsx3 = (uiNnz32b3|(uiNnz32b3>>8))<<iLShiftFactor;
172+ nBS[0][1][3] = uiBsx3[0];
173+ nBS[0][2][3] = uiBsx3[1];
174+ nBS[0][3][3] = uiBsx3[2];
175+ *(uint32_t *)nBS[1][3] = (uiNnz32b2|uiNnz32b3)<<iLShiftFactor;
176+
177+}
178+
179+void_t static inline DeblockingBSInsideMBNormal( PDqLayer pCurDqLayer, uint8_t nBS[2][4][4], int8_t* pNnzTab, int32_t iMbXy )
180+{
181+ uint32_t uiNnz32b0, uiNnz32b1, uiNnz32b2, uiNnz32b3;
182+ int8_t* iRefIndex = pCurDqLayer->pRefIndex[LIST_0][iMbXy];
183+ FORCE_STACK_ALIGN_1D( uint8_t, uiBsx4, 4, 4 );
184+
185+ uiNnz32b0 = *(uint32_t *)(pNnzTab+0);
186+ uiNnz32b1 = *(uint32_t *)(pNnzTab+4);
187+ uiNnz32b2 = *(uint32_t *)(pNnzTab+8);
188+ uiNnz32b3 = *(uint32_t *)(pNnzTab+12);
189+
190+ *(uint32_t *)uiBsx4 = (uiNnz32b0|(uiNnz32b0>>8));
191+ nBS[0][1][0] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 1, 0);
192+ nBS[0][2][0] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 2, 1);
193+ nBS[0][3][0] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 3, 2);
194+
195+ *(uint32_t *)uiBsx4 = (uiNnz32b1|(uiNnz32b1>>8));
196+ nBS[0][1][1] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 4);
197+ nBS[0][2][1] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 5);
198+ nBS[0][3][1] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 6);
199+
200+ *(uint32_t *)uiBsx4 = (uiNnz32b2|(uiNnz32b2>>8));
201+ nBS[0][1][2] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 8);
202+ nBS[0][2][2] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 10,9);
203+ nBS[0][3][2] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 11,10);
204+
205+ *(uint32_t *)uiBsx4 = (uiNnz32b3|(uiNnz32b3>>8));
206+ nBS[0][1][3] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 13,12);
207+ nBS[0][2][3] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 14,13);
208+ nBS[0][3][3] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 15,14);
209+
210+ // horizontal
211+ *(uint32_t *)uiBsx4 = (uiNnz32b0|uiNnz32b1);
212+ nBS[1][1][0] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 4, 0);
213+ nBS[1][1][1] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 1);
214+ nBS[1][1][2] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 2);
215+ nBS[1][1][3] = BS_EDGE(uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 3);
216+
217+ *(uint32_t *)uiBsx4 = (uiNnz32b1|uiNnz32b2);
218+ nBS[1][2][0] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 8, 4);
219+ nBS[1][2][1] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 5);
220+ nBS[1][2][2] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 10, 6);
221+ nBS[1][2][3] = BS_EDGE(uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 11, 7);
222+
223+ *(uint32_t *)uiBsx4 = (uiNnz32b2|uiNnz32b3);
224+ nBS[1][3][0] = BS_EDGE(uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 12, 8);
225+ nBS[1][3][1] = BS_EDGE(uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 13, 9);
226+ nBS[1][3][2] = BS_EDGE(uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 14, 10);
227+ nBS[1][3][3] = BS_EDGE(uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 15, 11);
228+}
229+
230+uint32_t DeblockingBsMarginalMBAvcbase( PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy)
231+{
232+ int32_t i;
233+ uint32_t uiBSx4;
234+ //uint8_t* bS = static_cast<uint8_t*>(&uiBSx4);
235+ uint8_t* pBS = (uint8_t*)(&uiBSx4);
236+ uint32_t uiBIdx = *(uint32_t *)(&g_kuiTableBIdx[iEdge][0]);
237+ uint32_t uiBnIdx = *(uint32_t *)(&g_kuiTableBIdx[iEdge][4]);
238+
239+ for( i = 0; i < 4; i++ )
240+ {
241+ if( pCurDqLayer->pNzc[iMbXy][uiBIdx&0xff] | pCurDqLayer->pNzc[iNeighMb][uiBnIdx&0xff] )
242+ {
243+ pBS[i] = 2;
244+ }
245+ else
246+ {
247+ pBS[i] = MB_BS_MV(pCurDqLayer->pRefIndex[LIST_0], pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, (uiBIdx&0xff), (uiBnIdx&0xff));
248+ }
249+ uiBIdx = uiBIdx >> 8;
250+ uiBnIdx = uiBnIdx >> 8;
251+ }
252+ return uiBSx4;
253+}
254+int32_t DeblockingAvailableNoInterlayer( PDqLayer pCurDqLayer, int32_t iFilterIdc )
255+{
256+ int32_t iMbY = pCurDqLayer->iMbY;
257+ int32_t iMbX = pCurDqLayer->iMbX;
258+ int32_t iMbXy = pCurDqLayer->iMbXyIndex;
259+ BOOL_T bLeftFlag = FALSE;
260+ BOOL_T bTopFlag = FALSE;
261+
262+ if ( 2 == iFilterIdc )
263+ {
264+ bLeftFlag = ( iMbX > 0 ) && ( pCurDqLayer->pSliceIdc[iMbXy] == pCurDqLayer->pSliceIdc[iMbXy-1] );
265+ bTopFlag = ( iMbY > 0 ) && ( pCurDqLayer->pSliceIdc[iMbXy] == pCurDqLayer->pSliceIdc[iMbXy-pCurDqLayer->iMbWidth] );
266+ }
267+ else //if ( 0 == iFilterIdc )
268+ {
269+ bLeftFlag = ( iMbX > 0 );
270+ bTopFlag = ( iMbY > 0 );
271+ }
272+ return (bLeftFlag<<LEFT_FLAG_BIT)|(bTopFlag<<TOP_FLAG_BIT);
273+}
274+
275+void_t FilteringEdgeLumaH(SDeblockingFilter* pFilter, uint8_t* pPix, int32_t iStride, uint8_t* pBS )
276+{
277+ int32_t iIndexA;
278+ int32_t iAlpha;
279+ int32_t iBeta;
280+ FORCE_STACK_ALIGN_1D( int8_t, tc, 4, 16 );
281+
282+ GET_ALPHA_BETA_FROM_QP(pFilter->iLumaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
283+
284+ if( iAlpha | iBeta )
285+ {
286+ TC0_TBL_LOOKUP(tc, iIndexA, pBS, 0);
287+ pFilter->pLoopf->pfLumaDeblockingLT4Ver(pPix, iStride, iAlpha, iBeta, tc);
288+ }
289+ return;
290+}
291+
292+
293+void_t FilteringEdgeLumaV(SDeblockingFilter* pFilter, uint8_t* pPix, int32_t iStride, uint8_t* pBS )
294+{
295+ int32_t iIndexA;
296+ int32_t iAlpha;
297+ int32_t iBeta;
298+ FORCE_STACK_ALIGN_1D( int8_t, tc, 4, 16 );
299+
300+ GET_ALPHA_BETA_FROM_QP(pFilter->iLumaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
301+
302+ if( iAlpha | iBeta )
303+ {
304+ TC0_TBL_LOOKUP(tc, iIndexA, pBS, 0);
305+ pFilter->pLoopf->pfLumaDeblockingLT4Hor(pPix, iStride, iAlpha, iBeta, tc);
306+ }
307+ return;
308+}
309+
310+
311+void_t FilteringEdgeLumaIntraH( SDeblockingFilter* pFilter, uint8_t* pPix, int32_t iStride, uint8_t* pBS )
312+{
313+ int32_t iIndexA;
314+ int32_t iAlpha;
315+ int32_t iBeta;
316+
317+ GET_ALPHA_BETA_FROM_QP(pFilter->iLumaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
318+
319+ if( iAlpha | iBeta )
320+ {
321+ pFilter->pLoopf->pfLumaDeblockingEQ4Ver(pPix, iStride, iAlpha, iBeta);
322+ }
323+ return;
324+}
325+
326+void_t FilteringEdgeLumaIntraV( SDeblockingFilter* pFilter, uint8_t* pPix, int32_t iStride, uint8_t* pBS )
327+{
328+ int32_t iIndexA;
329+ int32_t iAlpha;
330+ int32_t iBeta;
331+
332+ GET_ALPHA_BETA_FROM_QP(pFilter->iLumaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
333+
334+ if( iAlpha | iBeta )
335+ {
336+ pFilter->pLoopf->pfLumaDeblockingEQ4Hor(pPix, iStride, iAlpha, iBeta);
337+ }
338+ return;
339+}
340+void_t FilteringEdgeChromaH( SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, uint8_t* pBS )
341+{
342+ int32_t iIndexA;
343+ int32_t iAlpha;
344+ int32_t iBeta;
345+ FORCE_STACK_ALIGN_1D( int8_t, tc, 4, 16 );
346+
347+ GET_ALPHA_BETA_FROM_QP(pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
348+
349+ if( iAlpha | iBeta )
350+ {
351+ TC0_TBL_LOOKUP(tc, iIndexA, pBS, 1);
352+ pFilter->pLoopf->pfChromaDeblockingLT4Ver(pPixCb, pPixCr, iStride,iAlpha, iBeta, tc);
353+ }
354+ return;
355+}
356+void_t FilteringEdgeChromaV( SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, uint8_t* pBS )
357+{
358+ int32_t iIndexA;
359+ int32_t iAlpha;
360+ int32_t iBeta;
361+ FORCE_STACK_ALIGN_1D( int8_t, tc, 4, 16 );
362+
363+ GET_ALPHA_BETA_FROM_QP(pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
364+
365+ if( iAlpha | iBeta )
366+ {
367+ TC0_TBL_LOOKUP(tc, iIndexA, pBS, 1);
368+ pFilter->pLoopf->pfChromaDeblockingLT4Hor(pPixCb, pPixCr, iStride, iAlpha, iBeta, tc);
369+ }
370+ return;
371+}
372+
373+void_t FilteringEdgeChromaIntraH( SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, uint8_t* pBS )
374+{
375+ int32_t iIndexA;
376+ int32_t iAlpha;
377+ int32_t iBeta;
378+
379+ GET_ALPHA_BETA_FROM_QP(pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
380+
381+ if( iAlpha | iBeta )
382+ {
383+ pFilter->pLoopf->pfChromaDeblockingEQ4Ver(pPixCb, pPixCr, iStride, iAlpha, iBeta);
384+ }
385+ return;
386+}
387+
388+void_t FilteringEdgeChromaIntraV( SDeblockingFilter* pFilter, uint8_t* pPixCb, uint8_t* pPixCr, int32_t iStride, uint8_t* pBS )
389+{
390+ int32_t iIndexA;
391+ int32_t iAlpha;
392+ int32_t iBeta;
393+
394+ GET_ALPHA_BETA_FROM_QP(pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
395+
396+ if( iAlpha | iBeta )
397+ {
398+ pFilter->pLoopf->pfChromaDeblockinEQ4Hor(pPixCb, pPixCr, iStride, iAlpha, iBeta);
399+ }
400+ return;
401+}
402+
403+
404+void_t DeblockingInterMb( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, uint8_t nBS[2][4][4], int32_t iBoundryFlag )
405+{
406+ int32_t iMbXyIndex = pCurDqLayer->iMbXyIndex;
407+ int32_t iMbX = pCurDqLayer->iMbX;
408+ int32_t iMbY = pCurDqLayer->iMbY;
409+
410+ int32_t iCurLumaQp = pCurDqLayer->pLumaQp[iMbXyIndex];
411+ int32_t iCurChromaQp = pCurDqLayer->pChromaQp[iMbXyIndex];
412+ int32_t iLineSize = pFilter->iCsStride[0];
413+ int32_t iLineSizeUV = pFilter->iCsStride[1];
414+
415+ uint8_t * pDestY, * pDestCb, * pDestCr;
416+ pDestY = pFilter->pCsData[0] + ((iMbY * iLineSize + iMbX) << 4);
417+ pDestCb = pFilter->pCsData[1] + ((iMbY * iLineSizeUV + iMbX) << 3);
418+ pDestCr = pFilter->pCsData[2] + ((iMbY * iLineSizeUV + iMbX) << 3);
419+
420+ if( iBoundryFlag & LEFT_FLAG_MASK)
421+ {
422+ int32_t iLeftXyIndex = iMbXyIndex - 1;
423+ pFilter->iLumaQP = (iCurLumaQp + pCurDqLayer->pLumaQp[iLeftXyIndex] + 1) >> 1;
424+ pFilter->iChromaQP = (iCurChromaQp + pCurDqLayer->pChromaQp[iLeftXyIndex]+ 1) >> 1;
425+
426+ if( nBS[0][0][0] == 0x04 )
427+ {
428+ FilteringEdgeLumaIntraV( pFilter, pDestY, iLineSize, NULL );
429+ FilteringEdgeChromaIntraV( pFilter, pDestCb, pDestCr, iLineSizeUV, NULL );
430+ }
431+ else
432+ {
433+ if(*(uint32_t *)nBS[0][0] != 0)
434+ {
435+ FilteringEdgeLumaV( pFilter, pDestY, iLineSize, nBS[0][0] );
436+ FilteringEdgeChromaV( pFilter, pDestCb, pDestCr, iLineSizeUV, nBS[0][0] );
437+ }
438+ }
439+ }
440+
441+ pFilter->iLumaQP = iCurLumaQp;
442+ pFilter->iChromaQP = iCurChromaQp;
443+
444+ if(*(uint32_t *)nBS[0][1] != 0)
445+ {
446+ FilteringEdgeLumaV( pFilter, &pDestY[1<<2], iLineSize, nBS[0][1]);
447+ }
448+
449+ if(*(uint32_t *)nBS[0][2] != 0)
450+ {
451+ FilteringEdgeLumaV( pFilter, &pDestY[2<<2], iLineSize, nBS[0][2]);
452+ FilteringEdgeChromaV( pFilter, &pDestCb[2<<1], &pDestCr[2<<1], iLineSizeUV, nBS[0][2] );
453+ }
454+
455+ if(*(uint32_t *)nBS[0][3] != 0)
456+ {
457+ FilteringEdgeLumaV( pFilter, &pDestY[3<<2], iLineSize, nBS[0][3] );
458+ }
459+
460+ if( iBoundryFlag & TOP_FLAG_MASK)
461+ {
462+ int32_t iTopXyIndex = iMbXyIndex - pCurDqLayer->iMbWidth;
463+ pFilter->iLumaQP = (iCurLumaQp + pCurDqLayer->pLumaQp[iTopXyIndex] + 1) >> 1;
464+ pFilter->iChromaQP = (iCurChromaQp + pCurDqLayer->pChromaQp[iTopXyIndex] + 1) >> 1;
465+
466+ if( nBS[1][0][0] == 0x04)
467+ {
468+ FilteringEdgeLumaIntraH( pFilter, pDestY, iLineSize, NULL );
469+ FilteringEdgeChromaIntraH( pFilter, pDestCb, pDestCr, iLineSizeUV, NULL );
470+ }
471+ else
472+ {
473+ if(*(uint32_t *)nBS[1][0] != 0)
474+ {
475+ FilteringEdgeLumaH( pFilter, pDestY, iLineSize, nBS[1][0] );
476+ FilteringEdgeChromaH( pFilter, pDestCb, pDestCr, iLineSizeUV, nBS[1][0] );
477+ }
478+ }
479+ }
480+
481+ pFilter->iLumaQP = iCurLumaQp;
482+ pFilter->iChromaQP = iCurChromaQp;
483+
484+ if(*(uint32_t *)nBS[1][1] != 0)
485+ {
486+ FilteringEdgeLumaH( pFilter, &pDestY[(1<<2)*iLineSize], iLineSize, nBS[1][1] );
487+ }
488+
489+ if(*(uint32_t *)nBS[1][2] != 0)
490+ {
491+ FilteringEdgeLumaH( pFilter, &pDestY[(2<<2)*iLineSize], iLineSize, nBS[1][2] );
492+ FilteringEdgeChromaH( pFilter, &pDestCb[(2<<1)*iLineSizeUV], &pDestCr[(2<<1)*iLineSizeUV], iLineSizeUV, nBS[1][2] );
493+ }
494+
495+ if(*(uint32_t *)nBS[1][3] != 0)
496+ {
497+ FilteringEdgeLumaH( pFilter, &pDestY[(3<<2)*iLineSize], iLineSize, nBS[1][3] );
498+ }
499+}
500+
501+void_t /*__FASTCALL*/ FilteringEdgeLumaHV( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, int32_t iBoundryFlag )
502+{
503+ int32_t iMbXyIndex = pCurDqLayer->iMbXyIndex;
504+ int32_t iMbX = pCurDqLayer->iMbX;
505+ int32_t iMbY = pCurDqLayer->iMbY;
506+ int32_t iMbWidth = pCurDqLayer->iMbWidth;
507+ int32_t iLineSize = pFilter->iCsStride[0];
508+
509+ uint8_t *pDestY;
510+ int32_t iCurQp;
511+ int32_t iIndexA, iAlpha, iBeta;
512+
513+ FORCE_STACK_ALIGN_1D(int8_t, iTc, 4, 16 );
514+ FORCE_STACK_ALIGN_1D(uint8_t, uiBSx4, 4, 4 );
515+
516+ pDestY = pFilter->pCsData[0] + ((iMbY * iLineSize + iMbX) << 4);
517+ iCurQp = pCurDqLayer->pLumaQp[iMbXyIndex];
518+
519+ *(uint32_t*)uiBSx4 = 0x03030303;
520+
521+ // luma v
522+ if( iBoundryFlag & LEFT_FLAG_MASK)
523+ {
524+ pFilter->iLumaQP = ( iCurQp + pCurDqLayer->pLumaQp[iMbXyIndex-1] + 1 ) >> 1;
525+ FilteringEdgeLumaIntraV( pFilter, pDestY, iLineSize, NULL );
526+ }
527+
528+ pFilter->iLumaQP = iCurQp;
529+ GET_ALPHA_BETA_FROM_QP(pFilter->iLumaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
530+ if( iAlpha | iBeta )
531+ {
532+ TC0_TBL_LOOKUP(iTc, iIndexA, uiBSx4, 0);
533+ pFilter->pLoopf->pfLumaDeblockingLT4Hor( &pDestY[1 << 2],iLineSize,iAlpha,iBeta,iTc );
534+ pFilter->pLoopf->pfLumaDeblockingLT4Hor( &pDestY[2 << 2],iLineSize,iAlpha,iBeta,iTc );
535+ pFilter->pLoopf->pfLumaDeblockingLT4Hor( &pDestY[3 << 2],iLineSize,iAlpha,iBeta,iTc );
536+ }
537+
538+ // luma h
539+ if( iBoundryFlag & TOP_FLAG_MASK)
540+ {
541+ pFilter->iLumaQP = ( iCurQp + pCurDqLayer->pLumaQp[iMbXyIndex-iMbWidth] + 1 ) >> 1;
542+ FilteringEdgeLumaIntraH( pFilter, pDestY, iLineSize, NULL );
543+ }
544+
545+ pFilter->iLumaQP = iCurQp;
546+ if( iAlpha | iBeta )
547+ {
548+ pFilter->pLoopf->pfLumaDeblockingLT4Ver( &pDestY[(1<<2)*iLineSize],iLineSize,iAlpha,iBeta,iTc );
549+ pFilter->pLoopf->pfLumaDeblockingLT4Ver( &pDestY[(2<<2)*iLineSize],iLineSize,iAlpha,iBeta,iTc );
550+ pFilter->pLoopf->pfLumaDeblockingLT4Ver( &pDestY[(3<<2)*iLineSize],iLineSize,iAlpha,iBeta,iTc );
551+ }
552+}
553+void_t /*__FASTCALL*/ FilteringEdgeChromaHV( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, int32_t iBoundryFlag )
554+{
555+ int32_t iMbXyIndex = pCurDqLayer->iMbXyIndex;
556+ int32_t iMbX = pCurDqLayer->iMbX;
557+ int32_t iMbY = pCurDqLayer->iMbY;
558+ int32_t iMbWidth = pCurDqLayer->iMbWidth;
559+ int32_t iLineSize = pFilter->iCsStride[1];
560+
561+ uint8_t *pDestCb, *pDestCr;
562+ int32_t iCurQp;
563+ int32_t iIndexA, iAlpha, iBeta;
564+
565+ FORCE_STACK_ALIGN_1D( int8_t, iTc, 4, 16 );
566+ FORCE_STACK_ALIGN_1D( uint8_t, uiBSx4, 4, 4 );
567+
568+ pDestCb = pFilter->pCsData[1] + ((iMbY * iLineSize + iMbX) << 3);
569+ pDestCr = pFilter->pCsData[2] + ((iMbY * iLineSize + iMbX) << 3);
570+ iCurQp = pCurDqLayer->pChromaQp[iMbXyIndex];
571+ *(uint32_t*)uiBSx4 = 0x03030303;
572+
573+ // chroma v
574+ if( iBoundryFlag & LEFT_FLAG_MASK)
575+ {
576+ pFilter->iChromaQP = ( iCurQp + pCurDqLayer->pChromaQp[iMbXyIndex-1] + 1 ) >> 1;
577+ FilteringEdgeChromaIntraV( pFilter, pDestCb, pDestCr, iLineSize, NULL);
578+ }
579+
580+ pFilter->iChromaQP = iCurQp;
581+ GET_ALPHA_BETA_FROM_QP(pFilter->iChromaQP, pFilter->iSliceAlphaC0Offset, pFilter->iSliceBetaOffset, iIndexA, iAlpha, iBeta);
582+ if( iAlpha | iBeta )
583+ {
584+ TC0_TBL_LOOKUP(iTc, iIndexA, uiBSx4, 1);
585+ pFilter->pLoopf->pfChromaDeblockingLT4Hor( &pDestCb[2 << 1],&pDestCr[2 << 1],iLineSize,iAlpha,iBeta,iTc );
586+ }
587+
588+ // chroma h
589+ if( iBoundryFlag & TOP_FLAG_MASK)
590+ {
591+ pFilter->iChromaQP = ( iCurQp + pCurDqLayer->pChromaQp[iMbXyIndex-iMbWidth] + 1 ) >> 1;
592+ FilteringEdgeChromaIntraH( pFilter, pDestCb, pDestCr, iLineSize, NULL);
593+ }
594+
595+ pFilter->iChromaQP = iCurQp;
596+ if( iAlpha | iBeta )
597+ {
598+ pFilter->pLoopf->pfChromaDeblockingLT4Ver( &pDestCb[(2<<1)*iLineSize],&pDestCr[(2<<1)*iLineSize],iLineSize,iAlpha,iBeta,iTc );
599+ }
600+}
601+
602+// merge h&v lookup table operation to save performance
603+void_t DeblockingIntraMb( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, int32_t iBoundryFlag )
604+{
605+ FilteringEdgeLumaHV(pCurDqLayer, pFilter, iBoundryFlag);
606+ FilteringEdgeChromaHV(pCurDqLayer, pFilter, iBoundryFlag);
607+}
608+
609+void_t WelsDeblockingMb( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, int32_t iBoundryFlag )
610+{
611+ uint8_t nBS[2][4][4] = { 0 };
612+
613+ int32_t iMbXyIndex = pCurDqLayer->iMbXyIndex;
614+ int32_t iCurMbType = pCurDqLayer->pMbType[iMbXyIndex];
615+ int32_t iMbNb;
616+
617+ switch( iCurMbType )
618+ {
619+ case MB_TYPE_INTRA4x4:
620+ case MB_TYPE_INTRA16x16:
621+ case MB_TYPE_INTRA_PCM:
622+ DeblockingIntraMb( pCurDqLayer, pFilter, iBoundryFlag );
623+ break;
624+ default:
625+
626+ if(iBoundryFlag & LEFT_FLAG_MASK)
627+ {
628+ iMbNb = iMbXyIndex - 1;
629+ *(uint32_t*)nBS[0][0] = IS_INTRA(pCurDqLayer->pMbType[iMbNb])?0x04040404:DeblockingBsMarginalMBAvcbase( pCurDqLayer, 0, iMbNb, iMbXyIndex);
630+ }
631+ else
632+ {
633+ *(uint32_t*)nBS[0][0] = 0;
634+ }
635+ if(iBoundryFlag & TOP_FLAG_MASK)
636+ {
637+ iMbNb = iMbXyIndex - pCurDqLayer->iMbWidth;
638+ *(uint32_t*)nBS[1][0] = IS_INTRA(pCurDqLayer->pMbType[iMbNb])?0x04040404:DeblockingBsMarginalMBAvcbase( pCurDqLayer, 1, iMbNb, iMbXyIndex);
639+ }
640+ else
641+ {
642+ *(uint32_t*)nBS[1][0] = 0;
643+ }
644+ //SKIP MB_16x16 or others
645+ if( iCurMbType != MB_TYPE_SKIP )
646+ {
647+ if( iCurMbType == MB_TYPE_16x16 )
648+ {
649+ DeblockingBSInsideMBAvsbase( pCurDqLayer->pNzc[iMbXyIndex], nBS, 1 );
650+ }
651+ else
652+ {
653+ DeblockingBSInsideMBNormal(pCurDqLayer, nBS, pCurDqLayer->pNzc[iMbXyIndex], iMbXyIndex);
654+ }
655+ }
656+ else
657+ {
658+ *(uint32_t*)nBS[0][1] = *(uint32_t*)nBS[0][2] = *(uint32_t*)nBS[0][3] =
659+ *(uint32_t*)nBS[1][1] = *(uint32_t*)nBS[1][2] = *(uint32_t*)nBS[1][3] = 0;
660+ }
661+ DeblockingInterMb( pCurDqLayer, pFilter, nBS, iBoundryFlag );
662+ break;
663+ }
664+}
665+
666+// C code only
667+void_t DeblockLumaLt4_c( uint8_t *pPix, int32_t iStrideX,int32_t iStrideY, int32_t iAlpha, int32_t iBeta, int8_t *pTc )
668+{
669+ for( int32_t i = 0;i<16;i++)
670+ {
671+ int32_t iTc0 = pTc[i>>2];
672+ if(iTc0>=0)
673+ {
674+ int32_t p0 = pPix[-iStrideX];
675+ int32_t p1 = pPix[-2*iStrideX];
676+ int32_t p2 = pPix[-3*iStrideX];
677+ int32_t q0 = pPix[0];
678+ int32_t q1 = pPix[iStrideX];
679+ int32_t q2 = pPix[2*iStrideX];
680+ bool_t bDetaP0Q0= WELS_ABS( p0 - q0 )<iAlpha;
681+ bool_t bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
682+ bool_t bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
683+ int32_t iTc = iTc0;
684+ if ( bDetaP0Q0&& bDetaP1P0 && bDetaQ1Q0 )
685+ {
686+ bool_t bDetaP2P0 = WELS_ABS( p2 - p0 ) < iBeta;
687+ bool_t bDetaQ2Q0 = WELS_ABS( q2 - q0 ) < iBeta;
688+ if ( bDetaP2P0)
689+ {
690+ pPix[-2*iStrideX] = p1 + WELS_CLIP3( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -iTc0, iTc0 );
691+ iTc++;
692+ }
693+ if (bDetaQ2Q0)
694+ {
695+ pPix[iStrideX] = q1 + WELS_CLIP3( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -iTc0, iTc0 );
696+ iTc++;
697+ }
698+ int32_t iDeta = WELS_CLIP3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -iTc, iTc );
699+ pPix[-iStrideX] = WELS_CLIP1( p0 + iDeta ); /* p0' */
700+ pPix[0] = WELS_CLIP1( q0 - iDeta ); /* q0' */
701+ }
702+ }
703+ pPix +=iStrideY;
704+ }
705+}
706+void_t DeblockLumaEq4_c( uint8_t *pPix, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha, int32_t iBeta )
707+{
708+ int32_t p0,p1,p2,q0,q1,q2;
709+ int32_t iDetaP0Q0;
710+ bool_t bDetaP1P0,bDetaQ1Q0;
711+ for (int32_t i = 0;i<16;i++)
712+ {
713+ p0 = pPix[-iStrideX];
714+ p1 = pPix[-2*iStrideX];
715+ p2 = pPix[-3*iStrideX];
716+ q0 = pPix[0];
717+ q1 = pPix[iStrideX];
718+ q2 = pPix[2*iStrideX];
719+ iDetaP0Q0 = WELS_ABS( p0 - q0 );
720+ bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
721+ bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
722+ if ((iDetaP0Q0<iAlpha) && bDetaP1P0 &&bDetaQ1Q0)
723+ {
724+ if (iDetaP0Q0< (( iAlpha >> 2 ) + 2 ) )
725+ {
726+ bool_t bDetaP2P0 = WELS_ABS( p2 - p0 ) < iBeta;
727+ bool_t bDetaQ2Q0 = WELS_ABS( q2 - q0 ) < iBeta;
728+ if(bDetaP2P0)
729+ {
730+ const int32_t p3 = pPix[-4*iStrideX];
731+ pPix[-iStrideX] = ( p2 + (p1 << 1) + (p0 << 1) + (q0 << 1) + q1 + 4 ) >> 3; //p0
732+ pPix[-2*iStrideX] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; //p1
733+ pPix[-3*iStrideX] = ( (p3 << 1) + p2 + (p2 << 1) + p1 + p0 + q0 + 4 ) >> 3;//p2
734+ }
735+ else
736+ {
737+ pPix[-1*iStrideX] = ( (p1 << 1) + p0 + q1 + 2 ) >> 2; //p0
738+ }
739+ if (bDetaQ2Q0)
740+ {
741+ const int32_t q3 = pPix[3*iStrideX];
742+ pPix[0] = ( p1 + (p0 << 1) + (q0 << 1) + (q1 << 1) + q2 + 4 ) >> 3; //q0
743+ pPix[iStrideX] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; //q1
744+ pPix[2*iStrideX] = ( (q3 << 1) + q2 + (q2 << 1) + q1 + q0 + p0 + 4 ) >> 3;//q2
745+ }
746+ else
747+ {
748+ pPix[0] = ( (q1 << 1) + q0 + p1 + 2 ) >> 2; //q0
749+ }
750+ }
751+ else
752+ {
753+ pPix[-iStrideX] = ( (p1 << 1) + p0 + q1 + 2 ) >> 2; //p0
754+ pPix[ 0] = ( (q1 << 1) + q0 + p1 + 2 ) >> 2; //q0
755+ }
756+ }
757+ pPix += iStrideY;
758+ }
759+}
760+void_t DeblockLumaLt4V_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t *tc )
761+{
762+ DeblockLumaLt4_c( pPix, iStride, 1, iAlpha, iBeta, tc );
763+}
764+void_t DeblockLumaLt4H_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t *tc )
765+{
766+ DeblockLumaLt4_c( pPix, 1, iStride, iAlpha, iBeta, tc );
767+}
768+void_t DeblockLumaEq4V_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta )
769+{
770+ DeblockLumaEq4_c( pPix, iStride, 1, iAlpha, iBeta);
771+}
772+void_t DeblockLumaEq4H_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta )
773+{
774+ DeblockLumaEq4_c( pPix, 1, iStride, iAlpha, iBeta );
775+}
776+void_t DeblockChromaLt4_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha, int32_t iBeta, int8_t *pTc )
777+{
778+ int32_t p0, p1, q0, q1,iDeta;
779+ bool_t bDetaP0Q0,bDetaP1P0,bDetaQ1Q0;
780+
781+ for(int32_t i = 0;i<8;i++)
782+ {
783+ int32_t iTc0 = pTc[i>>1];
784+ if(iTc0 >0)
785+ {
786+ p0 = pPixCb[-iStrideX];
787+ p1 = pPixCb[-2*iStrideX];
788+ q0 = pPixCb[0];
789+ q1 = pPixCb[iStrideX];
790+
791+ bDetaP0Q0 = WELS_ABS( p0 - q0 ) < iAlpha;
792+ bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
793+ bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
794+ if( bDetaP0Q0&&bDetaP1P0 && bDetaQ1Q0)
795+ {
796+ iDeta = WELS_CLIP3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -iTc0, iTc0 );
797+ pPixCb[-iStrideX] = WELS_CLIP1( p0 + iDeta ); /* p0' */
798+ pPixCb[0] = WELS_CLIP1( q0 - iDeta ); /* q0' */
799+ }
800+
801+
802+ p0 = pPixCr[-iStrideX];
803+ p1 = pPixCr[-2*iStrideX];
804+ q0 = pPixCr[0];
805+ q1 = pPixCr[iStrideX];
806+
807+ bDetaP0Q0 = WELS_ABS( p0 - q0 ) < iAlpha;
808+ bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
809+ bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
810+
811+ if( bDetaP0Q0&&bDetaP1P0 && bDetaQ1Q0)
812+ {
813+ iDeta = WELS_CLIP3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -iTc0, iTc0 );
814+ pPixCr[-iStrideX] = WELS_CLIP1( p0 + iDeta ); /* p0' */
815+ pPixCr[0] = WELS_CLIP1( q0 - iDeta ); /* q0' */
816+ }
817+ }
818+ pPixCb += iStrideY;
819+ pPixCr += iStrideY;
820+ }
821+}
822+void_t DeblockChromaEq4_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStrideX, int32_t iStrideY, int32_t iAlpha, int32_t iBeta )
823+{
824+ int32_t i = 0, d = 0;
825+ int32_t p0, p1, q0, q1;
826+ bool_t bDetaP0Q0,bDetaP1P0,bDetaQ1Q0;
827+ for(int32_t i =0;i<8;i++)
828+ {
829+ //cb
830+ p0 = pPixCb[-iStrideX];
831+ p1 = pPixCb[-2*iStrideX];
832+ q0 = pPixCb[0];
833+ q1 = pPixCb[iStrideX];
834+ bDetaP0Q0 = WELS_ABS( p0 - q0 ) < iAlpha;
835+ bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
836+ bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
837+ if(bDetaP0Q0&&bDetaP1P0&&bDetaQ1Q0)
838+ {
839+ pPixCb[-iStrideX] = ( (p1 << 1) + p0 + q1 + 2 ) >> 2; /* p0' */
840+ pPixCb[0] = ( (q1 << 1) + q0 + p1 + 2 ) >> 2; /* q0' */
841+ }
842+
843+ //cr
844+ p0 = pPixCr[-iStrideX];
845+ p1 = pPixCr[-2*iStrideX];
846+ q0 = pPixCr[0];
847+ q1 = pPixCr[iStrideX];
848+ bDetaP0Q0 = WELS_ABS( p0 - q0 ) < iAlpha;
849+ bDetaP1P0 = WELS_ABS( p1 - p0 ) < iBeta;
850+ bDetaQ1Q0 = WELS_ABS( q1 - q0 ) < iBeta;
851+ if(bDetaP0Q0&&bDetaP1P0&&bDetaQ1Q0)
852+ {
853+ pPixCr[-iStrideX] = ( (p1 << 1) + p0 + q1 + 2 ) >> 2; /* p0' */
854+ pPixCr[0] = ( (q1 << 1) + q0 + p1 + 2 ) >> 2; /* q0' */
855+ }
856+ pPixCr += iStrideY;
857+ pPixCb += iStrideY;
858+ }
859+}
860+void_t DeblockChromaLt4V_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t *tc )
861+{
862+ DeblockChromaLt4_c( pPixCb, pPixCr, iStride, 1, iAlpha, iBeta, tc );
863+}
864+void_t DeblockChromaLt4H_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t *tc )
865+{
866+ DeblockChromaLt4_c( pPixCb, pPixCr, 1, iStride, iAlpha, iBeta, tc );
867+}
868+void_t DeblockChromaEq4V_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta )
869+{
870+ DeblockChromaEq4_c( pPixCb, pPixCr, iStride, 1, iAlpha, iBeta );
871+}
872+void_t DeblockChromaEq4H_c( uint8_t *pPixCb, uint8_t *pPixCr, int32_t iStride, int32_t iAlpha, int32_t iBeta )
873+{
874+ DeblockChromaEq4_c( pPixCb, pPixCr, 1, iStride, iAlpha, iBeta );
875+}
876+
877+#ifdef X86_ASM
878+extern "C" {
879+void DeblockLumaLt4H_sse2(uint8_t *pPixY, int32_t iStride, int32_t iAlpha, int32_t iBeta, int8_t *pTc)
880+{
881+ FORCE_STACK_ALIGN_1D(uint8_t, uiBuf, 16*8, 16);
882+
883+ DeblockLumaTransposeH2V_sse2(pPixY - 4, iStride, &uiBuf[0]);
884+ DeblockLumaLt4V_sse2(&uiBuf[4*16], 16, iAlpha, iBeta, pTc);
885+ DeblockLumaTransposeV2H_sse2(pPixY - 4, iStride, &uiBuf[0]);
886+}
887+
888+void DeblockLumaEq4H_sse2(uint8_t *pPixY, int32_t iStride, int32_t iAlpha, int32_t iBeta)
889+{
890+ FORCE_STACK_ALIGN_1D(uint8_t, uiBuf, 16*8, 16);
891+
892+ DeblockLumaTransposeH2V_sse2(pPixY - 4, iStride, &uiBuf[0]);
893+ DeblockLumaEq4V_sse2(&uiBuf[4*16], 16, iAlpha, iBeta);
894+ DeblockLumaTransposeV2H_sse2(pPixY - 4, iStride, &uiBuf[0]);
895+}
896+
897+}
898+
899+#endif
900+/*!
901+ * \brief AVC slice deblocking filtering target layer
902+ *
903+ * \param dec Wels avc decoder context
904+ *
905+ * \return NONE
906+ */
907+void_t WelsDeblockingFilterSlice( PWelsDecoderContext pCtx, PDeblockingFilterMbFunc pDeblockMb )
908+{
909+ PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
910+ PSliceHeaderExt pSliceHeaderExt = &pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;
911+ int32_t iMbWidth = pCurDqLayer->iMbWidth;
912+ int32_t iTotalMbCount = pSliceHeaderExt->sSliceHeader.pSps->uiTotalMbCount;
913+
914+ SDeblockingFilter pFilter = {0};
915+
916+ PFmo pFmo = pCtx->pFmo;
917+ int32_t iNextMbXyIndex = 0;
918+ int32_t iTotalNumMb = pCurDqLayer->sLayerInfo.sSliceInLayer.iTotalMbInCurSlice;
919+ int32_t iCountNumMb = 0;
920+ int32_t iBoundryFlag;
921+ int32_t iFilterIdc = pCurDqLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.uiDisableDeblockingFilterIdc;
922+
923+ /* Step1: parameters set */
924+ pFilter.pCsData[0] = pCtx->pDec->pData[0];
925+ pFilter.pCsData[1] = pCtx->pDec->pData[1];
926+ pFilter.pCsData[2] = pCtx->pDec->pData[2];
927+
928+ pFilter.iCsStride[0] = pCtx->pDec->iLinesize[0];
929+ pFilter.iCsStride[1] = pCtx->pDec->iLinesize[1];
930+
931+ pFilter.eSliceType = (ESliceType) pCurDqLayer->sLayerInfo.sSliceInLayer.eSliceType;
932+
933+ pFilter.iSliceAlphaC0Offset = pSliceHeaderExt->sSliceHeader.iSliceAlphaC0Offset;
934+ pFilter.iSliceBetaOffset = pSliceHeaderExt->sSliceHeader.iSliceBetaOffset;
935+
936+ pFilter.pLoopf = &pCtx->sDeblockingFunc;
937+
938+ /* Step2: macroblock deblocking */
939+ if( 0 == iFilterIdc || 2 == iFilterIdc )
940+ {
941+ iNextMbXyIndex = pSliceHeaderExt->sSliceHeader.iFirstMbInSlice;
942+ pCurDqLayer->iMbX = iNextMbXyIndex % iMbWidth;
943+ pCurDqLayer->iMbY = iNextMbXyIndex / iMbWidth;
944+ pCurDqLayer->iMbXyIndex = iNextMbXyIndex;
945+
946+ do
947+ {
948+ iBoundryFlag = DeblockingAvailableNoInterlayer(pCurDqLayer, iFilterIdc);
949+
950+ pDeblockMb( pCurDqLayer, &pFilter, iBoundryFlag );
951+
952+ ++iCountNumMb;
953+ if ( iCountNumMb >= iTotalNumMb )
954+ {
955+ break;
956+ }
957+
958+ if ( pSliceHeaderExt->sSliceHeader.pPps->uiNumSliceGroups > 1 )
959+ {
960+ iNextMbXyIndex = FmoNextMb( pFmo, iNextMbXyIndex );
961+ }
962+ else
963+ {
964+ ++iNextMbXyIndex;
965+ }
966+ if ( -1 == iNextMbXyIndex || iNextMbXyIndex >= iTotalMbCount ) // slice group boundary or end of a frame
967+ {
968+ break;
969+ }
970+
971+ pCurDqLayer->iMbX = iNextMbXyIndex % iMbWidth;
972+ pCurDqLayer->iMbY = iNextMbXyIndex / iMbWidth;
973+ pCurDqLayer->iMbXyIndex = iNextMbXyIndex;
974+ } while ( 1 );
975+ }
976+}
977+/*!
978+ * \brief deblocking module initialize
979+ *
980+ * \param pf
981+ * cpu
982+ *
983+ * \return NONE
984+ */
985+
986+void_t DeblockingInit( SDeblockingFunc *pFunc, int32_t iCpu )
987+{
988+ pFunc->pfLumaDeblockingLT4Ver = DeblockLumaLt4V_c;
989+ pFunc->pfLumaDeblockingEQ4Ver = DeblockLumaEq4V_c;
990+ pFunc->pfLumaDeblockingLT4Hor = DeblockLumaLt4H_c;
991+ pFunc->pfLumaDeblockingEQ4Hor = DeblockLumaEq4H_c;
992+
993+ pFunc->pfChromaDeblockingLT4Ver = DeblockChromaLt4V_c;
994+ pFunc->pfChromaDeblockingEQ4Ver = DeblockChromaEq4V_c;
995+ pFunc->pfChromaDeblockingLT4Hor = DeblockChromaLt4H_c;
996+ pFunc->pfChromaDeblockinEQ4Hor = DeblockChromaEq4H_c;
997+
998+#ifdef X86_ASM
999+ if( iCpu & WELS_CPU_SSE2 ){
1000+ pFunc->pfLumaDeblockingLT4Ver = DeblockLumaLt4V_sse2;
1001+ pFunc->pfLumaDeblockingEQ4Ver = DeblockLumaEq4V_sse2;
1002+ pFunc->pfLumaDeblockingLT4Hor = DeblockLumaLt4H_sse2;
1003+ pFunc->pfLumaDeblockingEQ4Hor = DeblockLumaEq4H_sse2;
1004+ pFunc->pfChromaDeblockingLT4Ver = DeblockChromaLt4V_sse2;
1005+ pFunc->pfChromaDeblockingEQ4Ver = DeblockChromaEq4V_sse2;
1006+ pFunc->pfChromaDeblockingLT4Hor = DeblockChromaLt4H_sse2;
1007+ pFunc->pfChromaDeblockinEQ4Hor = DeblockChromaEq4H_sse2;
1008+ }
1009+#endif
1010+
1011+}
1012+
1013+} // namespace WelsDec

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