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
46namespace 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
74static 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
84static 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
94static 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
108static 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
117static 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};
129static 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
150void 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
185void 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
235uint32_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
263void 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}
279void 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
296void 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
311void 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}
325void 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}
341void 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
358void 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
373void 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
388void 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
489void 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}
548void 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
604void DeblockingIntraMb( DeblockingFunc* pfDeblocking, SMB* pCurMb, SDeblockingFilter* pFilter )
605{
606 FilteringEdgeLumaHV( pfDeblocking, pCurMb, pFilter);
607 FilteringEdgeChromaHV(pfDeblocking, pCurMb, pFilter);
608}
609
610void 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
677void 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
718void 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}
772void 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}
776void 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}
780void DeblockLumaEq4V_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta )
781{
782 DeblockLumaEq4_c( pPix, iStride, 1, iAlpha, iBeta);
783}
784void DeblockLumaEq4H_c( uint8_t *pPix, int32_t iStride, int32_t iAlpha, int32_t iBeta )
785{
786 DeblockLumaEq4_c( pPix, 1, iStride, iAlpha, iBeta );
787}
788void 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}
834void 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}
872void 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}
876void 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}
880void 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}
884void 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
890void 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
928void 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
977void 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
1020void 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}
1030void WelsBlockFuncInit( PSetNoneZeroCountZeroFunc *pfSetNZCZero, int32_t iCpu )
1031{
1032 *pfSetNZCZero = WelsNonZeroCount_c;
1033}
1034
1035
1036#ifdef X86_ASM
1037
1038extern "C" {
1039void 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
1048void 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
1062void 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