History

Initial Commit

Ethan Hugg committed 12 years ago

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

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

Unified · Split

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

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