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
45namespace 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
89static 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
100static 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
111static 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
127static 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
144void_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
179void_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
230uint32_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}
254int32_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
275void_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
293void_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
311void_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
326void_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}
340void_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}
356void_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
373void_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
388void_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
404void_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
501void_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}
553void_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
603void_t DeblockingIntraMb( PDqLayer pCurDqLayer, PDeblockingFilter pFilter, int32_t iBoundryFlag )
604{
605 FilteringEdgeLumaHV(pCurDqLayer, pFilter, iBoundryFlag);
606 FilteringEdgeChromaHV(pCurDqLayer, pFilter, iBoundryFlag);
607}
608
609void_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
667void_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}
706void_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}
760void_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}
764void_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}
768void_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}
772void_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}
776void_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}
822void_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}
860void_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}
864void_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}
868void_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}
872void_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
878extern "C" {
879void 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
888void 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 */
907void_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
986void_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