1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 #include <string.h>
20
21 #include "avclib_common.h"
22
23 #define MAX_QP 51
24 #define MB_BLOCK_SIZE 16
25
26 // NOTE: these 3 tables are for funtion GetStrength() only
27 const static int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303};
28
29
30 // NOTE: these 3 tables are for funtion EdgeLoop() only
31 // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values
32
33 const static int ALPHA_TABLE[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 15, 17, 20, 22, 25, 28, 32, 36, 40, 45, 50, 56, 63, 71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, 255, 255} ;
34 const static int BETA_TABLE[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18} ;
35 const static int CLIP_TAB[52][5] =
36 {
37 { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
38 { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
39 { 0, 0, 0, 0, 0}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 1, 1, 1, 1},
40 { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 2, 3, 3},
41 { 0, 1, 2, 3, 3}, { 0, 2, 2, 3, 3}, { 0, 2, 2, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 3, 3, 5, 5}, { 0, 3, 4, 6, 6}, { 0, 3, 4, 6, 6},
42 { 0, 4, 5, 7, 7}, { 0, 4, 5, 8, 8}, { 0, 4, 6, 9, 9}, { 0, 5, 7, 10, 10}, { 0, 6, 8, 11, 11}, { 0, 6, 8, 13, 13}, { 0, 7, 10, 14, 14}, { 0, 8, 11, 16, 16},
43 { 0, 9, 12, 18, 18}, { 0, 10, 13, 20, 20}, { 0, 11, 15, 23, 23}, { 0, 13, 17, 25, 25}
44 };
45
46 // NOTE: this table is only QP clipping, index = QP + video->FilterOffsetA/B, clipped to [0, 51]
47 // video->FilterOffsetA/B is in {-12, 12]
48 const static int QP_CLIP_TAB[76] =
49 {
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // [-12, 0]
51 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
52 13, 14, 15, 16, 17, 18, 19, 20, 21,
53 22, 23, 24, 25, 26, 27, 28, 29, 30,
54 31, 32, 33, 34, 35, 36, 37, 38, 39,
55 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // [1, 51]
56 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 // [52,63]
57 };
58
59 static void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV);
60 //static void GetStrength(AVCCommonObj *video, uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir, int edge);
61 static void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir);
62 static void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ);
63 static void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ);
64 static void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
65 static void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
66 static void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
67 static void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
68
69 /*
70 *****************************************************************************************
71 * \brief Filter all macroblocks in order of increasing macroblock address.
72 *****************************************************************************************
73 */
74
DeblockPicture(AVCCommonObj * video)75 OSCL_EXPORT_REF AVCStatus DeblockPicture(AVCCommonObj *video)
76 {
77 uint i, j;
78 int pitch = video->currPic->pitch, pitch_c, width;
79 uint8 *SrcY, *SrcU, *SrcV;
80
81 SrcY = video->currPic->Sl; // pointers to source
82 SrcU = video->currPic->Scb;
83 SrcV = video->currPic->Scr;
84 pitch_c = pitch >> 1;
85 width = video->currPic->width;
86
87 for (i = 0; i < video->PicHeightInMbs; i++)
88 {
89 for (j = 0; j < video->PicWidthInMbs; j++)
90 {
91 DeblockMb(video, j, i, SrcY, SrcU, SrcV);
92 // update SrcY, SrcU, SrcV
93 SrcY += MB_BLOCK_SIZE;
94 SrcU += (MB_BLOCK_SIZE >> 1);
95 SrcV += (MB_BLOCK_SIZE >> 1);
96 }
97
98 SrcY += ((pitch << 4) - width);
99 SrcU += ((pitch_c << 3) - (width >> 1));
100 SrcV += ((pitch_c << 3) - (width >> 1));
101 }
102
103 return AVC_SUCCESS;
104 }
105
106 #ifdef MB_BASED_DEBLOCK
107 /*
108 *****************************************************************************************
109 * \brief Filter one macroblocks in a fast macroblock memory and copy it to frame
110 *****************************************************************************************
111 */
MBInLoopDeblock(AVCCommonObj * video)112 void MBInLoopDeblock(AVCCommonObj *video)
113 {
114 AVCPictureData *currPic = video->currPic;
115 #ifdef USE_PRED_BLOCK
116 uint8 *predCb, *predCr, *pred_block;
117 int i, j, dst_width, dst_height, dst_widthc, dst_heightc;
118 #endif
119 int pitch = currPic->pitch;
120 int x_pos = video->mb_x;
121 int y_pos = video->mb_y;
122 uint8 *curL, *curCb, *curCr;
123 int offset;
124
125 offset = (y_pos << 4) * pitch;
126
127 curL = currPic->Sl + offset + (x_pos << 4);
128
129 offset >>= 2;
130 offset += (x_pos << 3);
131
132 curCb = currPic->Scb + offset;
133 curCr = currPic->Scr + offset;
134
135 #ifdef USE_PRED_BLOCK
136 pred_block = video->pred;
137
138 /* 1. copy neighboring pixels from frame to the video->pred_block */
139 if (y_pos) /* not the 0th row */
140 {
141 /* copy to the top 4 lines of the macroblock */
142 curL -= (pitch << 2); /* go back 4 lines */
143
144 memcpy(pred_block + 4, curL, 16);
145 curL += pitch;
146 memcpy(pred_block + 24, curL, 16);
147 curL += pitch;
148 memcpy(pred_block + 44, curL, 16);
149 curL += pitch;
150 memcpy(pred_block + 64, curL, 16);
151 curL += pitch;
152
153 curCb -= (pitch << 1); /* go back 4 lines chroma */
154 curCr -= (pitch << 1);
155
156 pred_block += 400;
157
158 memcpy(pred_block + 4, curCb, 8);
159 curCb += (pitch >> 1);
160 memcpy(pred_block + 16, curCb, 8);
161 curCb += (pitch >> 1);
162 memcpy(pred_block + 28, curCb, 8);
163 curCb += (pitch >> 1);
164 memcpy(pred_block + 40, curCb, 8);
165 curCb += (pitch >> 1);
166
167 pred_block += 144;
168 memcpy(pred_block + 4, curCr, 8);
169 curCr += (pitch >> 1);
170 memcpy(pred_block + 16, curCr, 8);
171 curCr += (pitch >> 1);
172 memcpy(pred_block + 28, curCr, 8);
173 curCr += (pitch >> 1);
174 memcpy(pred_block + 40, curCr, 8);
175 curCr += (pitch >> 1);
176
177 pred_block = video->pred;
178 }
179
180 /* 2. perform deblocking. */
181 DeblockMb(video, x_pos, y_pos, pred_block + 84, pred_block + 452, pred_block + 596);
182
183 /* 3. copy it back to the frame and update pred_block */
184 predCb = pred_block + 400;
185 predCr = predCb + 144;
186
187 /* find the range of the block inside pred_block to be copied back */
188 if (y_pos) /* the first row */
189 {
190 curL -= (pitch << 2);
191 curCb -= (pitch << 1);
192 curCr -= (pitch << 1);
193
194 dst_height = 20;
195 dst_heightc = 12;
196 }
197 else
198 {
199 pred_block += 80;
200 predCb += 48;
201 predCr += 48;
202 dst_height = 16;
203 dst_heightc = 8;
204 }
205
206 if (x_pos) /* find the width */
207 {
208 curL -= 4;
209 curCb -= 4;
210 curCr -= 4;
211 if (x_pos == (int)(video->PicWidthInMbs - 1))
212 {
213 dst_width = 20;
214 dst_widthc = 12;
215 }
216 else
217 {
218 dst_width = 16;
219 dst_widthc = 8;
220 }
221 }
222 else
223 {
224 pred_block += 4;
225 predCb += 4;
226 predCr += 4;
227 dst_width = 12;
228 dst_widthc = 4;
229 }
230
231 /* perform copy */
232 for (j = 0; j < dst_height; j++)
233 {
234 memcpy(curL, pred_block, dst_width);
235 curL += pitch;
236 pred_block += 20;
237 }
238 for (j = 0; j < dst_heightc; j++)
239 {
240 memcpy(curCb, predCb, dst_widthc);
241 memcpy(curCr, predCr, dst_widthc);
242 curCb += (pitch >> 1);
243 curCr += (pitch >> 1);
244 predCb += 12;
245 predCr += 12;
246 }
247
248 if (x_pos != (int)(video->PicWidthInMbs - 1)) /* now copy from the right-most 4 columns to the left-most 4 columns */
249 {
250 pred_block = video->pred;
251 for (i = 0; i < 20; i += 4)
252 {
253 *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
254 pred_block += 20;
255 *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
256 pred_block += 20;
257 *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
258 pred_block += 20;
259 *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
260 pred_block += 20;
261 }
262
263 for (i = 0; i < 24; i += 4)
264 {
265 *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
266 pred_block += 12;
267 *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
268 pred_block += 12;
269 *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
270 pred_block += 12;
271 *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
272 pred_block += 12;
273 }
274
275 }
276 #else
277 DeblockMb(video, x_pos, y_pos, curL, curCb, curCr);
278 #endif
279
280 return ;
281 }
282 #endif
283
284 /*
285 *****************************************************************************************
286 * \brief Deblocking filter for one macroblock.
287 *****************************************************************************************
288 */
289
DeblockMb(AVCCommonObj * video,int mb_x,int mb_y,uint8 * SrcY,uint8 * SrcU,uint8 * SrcV)290 void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV)
291 {
292 AVCMacroblock *MbP, *MbQ;
293 int edge, QP, QPC;
294 int filterLeftMbEdgeFlag = (mb_x != 0);
295 int filterTopMbEdgeFlag = (mb_y != 0);
296 int pitch = video->currPic->pitch;
297 int indexA, indexB;
298 int *tmp;
299 int Alpha, Beta, Alpha_c, Beta_c;
300 int mbNum = mb_y * video->PicWidthInMbs + mb_x;
301 int *clipTable, *clipTable_c, *qp_clip_tab;
302 uint8 Strength[16];
303 void* str;
304
305 MbQ = &(video->mblock[mbNum]); // current Mb
306
307
308 // If filter is disabled, return
309 if (video->sliceHdr->disable_deblocking_filter_idc == 1) return;
310
311 if (video->sliceHdr->disable_deblocking_filter_idc == 2)
312 {
313 // don't filter at slice boundaries
314 filterLeftMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - 1, mbNum);
315 filterTopMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - video->PicWidthInMbs, mbNum);
316 }
317
318 /* NOTE: edge=0 and edge=1~3 are separate cases because of the difference of MbP, index A and indexB calculation */
319 /* for edge = 1~3, MbP, indexA and indexB remain the same, and thus there is no need to re-calculate them for each edge */
320
321 qp_clip_tab = (int *)QP_CLIP_TAB + 12;
322
323 /* 1.VERTICAL EDGE + MB BOUNDARY (edge = 0) */
324 if (filterLeftMbEdgeFlag)
325 {
326 MbP = MbQ - 1;
327 //GetStrength(video, Strength, MbP, MbQ, 0, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
328 GetStrength_Edge0(Strength, MbP, MbQ, 0);
329
330 str = (void*)Strength; //de-ref type-punned pointer fix
331 if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0
332 {
333 QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
334 indexA = QP + video->FilterOffsetA;
335 indexB = QP + video->FilterOffsetB;
336 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
337 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
338
339 Alpha = ALPHA_TABLE[indexA];
340 Beta = BETA_TABLE[indexB];
341 clipTable = (int *) CLIP_TAB[indexA];
342
343 if (Alpha > 0 && Beta > 0)
344 #ifdef USE_PRED_BLOCK
345 EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, 20);
346 #else
347 EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, pitch);
348 #endif
349
350 QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
351 indexA = QPC + video->FilterOffsetA;
352 indexB = QPC + video->FilterOffsetB;
353 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
354 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
355
356 Alpha = ALPHA_TABLE[indexA];
357 Beta = BETA_TABLE[indexB];
358 clipTable = (int *) CLIP_TAB[indexA];
359 if (Alpha > 0 && Beta > 0)
360 {
361 #ifdef USE_PRED_BLOCK
362 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, 12);
363 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, 12);
364 #else
365 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
366 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
367 #endif
368 }
369 }
370
371 } /* end of: if(filterLeftMbEdgeFlag) */
372
373 /* 2.VERTICAL EDGE (no boundary), the edges are all inside a MB */
374 /* First calculate the necesary parameters all at once, outside the loop */
375 MbP = MbQ;
376
377 indexA = MbQ->QPy + video->FilterOffsetA;
378 indexB = MbQ->QPy + video->FilterOffsetB;
379 // index
380 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
381 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
382
383 Alpha = ALPHA_TABLE[indexA];
384 Beta = BETA_TABLE[indexB];
385 clipTable = (int *)CLIP_TAB[indexA];
386
387 /* Save Alpha, Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */
388 filterLeftMbEdgeFlag = Alpha;
389 mbNum = Beta;
390 tmp = clipTable;
391
392 indexA = MbQ->QPc + video->FilterOffsetA;
393 indexB = MbQ->QPc + video->FilterOffsetB;
394 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
395 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
396
397 Alpha_c = ALPHA_TABLE[indexA];
398 Beta_c = BETA_TABLE[indexB];
399 clipTable_c = (int *)CLIP_TAB[indexA];
400
401 GetStrength_VerticalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
402
403 for (edge = 1; edge < 4; edge++) // 4 vertical strips of 16 pel
404 {
405 //GetStrength_VerticalEdges(video, Strength, MbP, MbQ, 0, edge); // Strength for 4 blks in 1 stripe, 0 => vertical edge
406 if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
407 {
408 if (Alpha > 0 && Beta > 0)
409 #ifdef USE_PRED_BLOCK
410 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, 20);
411 #else
412 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, pitch);
413 #endif
414
415 if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
416 {
417 #ifdef USE_PRED_BLOCK
418 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
419 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
420 #else
421 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
422 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
423 #endif
424 }
425 }
426
427 } //end edge
428
429
430
431 /* 3.HORIZONTAL EDGE + MB BOUNDARY (edge = 0) */
432 if (filterTopMbEdgeFlag)
433 {
434 MbP = MbQ - video->PicWidthInMbs;
435 //GetStrength(video, Strength, MbP, MbQ, 1, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
436 GetStrength_Edge0(Strength, MbP, MbQ, 1);
437 str = (void*)Strength; //de-ref type-punned pointer fix
438 if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0
439 {
440 QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
441 indexA = QP + video->FilterOffsetA;
442 indexB = QP + video->FilterOffsetB;
443 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
444 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
445
446 Alpha = ALPHA_TABLE[indexA];
447 Beta = BETA_TABLE[indexB];
448 clipTable = (int *)CLIP_TAB[indexA];
449
450 if (Alpha > 0 && Beta > 0)
451 {
452 #ifdef USE_PRED_BLOCK
453 EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, 20);
454 #else
455 EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, pitch);
456 #endif
457 }
458
459 QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
460 indexA = QPC + video->FilterOffsetA;
461 indexB = QPC + video->FilterOffsetB;
462 indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
463 indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
464
465 Alpha = ALPHA_TABLE[indexA];
466 Beta = BETA_TABLE[indexB];
467 clipTable = (int *)CLIP_TAB[indexA];
468 if (Alpha > 0 && Beta > 0)
469 {
470 #ifdef USE_PRED_BLOCK
471 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, 12);
472 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, 12);
473 #else
474 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
475 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
476 #endif
477 }
478 }
479
480 } /* end of: if(filterTopMbEdgeFlag) */
481
482
483 /* 4.HORIZONTAL EDGE (no boundary), the edges are inside a MB */
484 MbP = MbQ;
485
486 /* Recover Alpha, Beta and clipTable for edge!=0 with the variables filterLeftMbEdgeFlag, mbNum and tmp */
487 /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */
488 Alpha = filterLeftMbEdgeFlag;
489 Beta = mbNum;
490 clipTable = tmp;
491
492 GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
493
494 for (edge = 1; edge < 4; edge++) // 4 horicontal strips of 16 pel
495 {
496 //GetStrength(video, Strength, MbP, MbQ, 1, edge); // Strength for 4 blks in 1 stripe 1 => horizontal edge
497 if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
498 {
499 if (Alpha > 0 && Beta > 0)
500 {
501 #ifdef USE_PRED_BLOCK
502 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*20, Strength + (edge << 2), Alpha, Beta, clipTable, 20);
503 #else
504 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*pitch, Strength + (edge << 2), Alpha, Beta, clipTable, pitch);
505 #endif
506 }
507
508 if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
509 {
510 #ifdef USE_PRED_BLOCK
511 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
512 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
513 #else
514 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
515 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
516 #endif
517 }
518 }
519
520 } //end edge
521
522 return;
523 }
524
525 /*
526 *****************************************************************************************************
527 * \brief returns a buffer of 4 Strength values for one stripe in a mb (for different Frame types)
528 *****************************************************************************************************
529 */
530
GetStrength_Edge0(uint8 * Strength,AVCMacroblock * MbP,AVCMacroblock * MbQ,int dir)531 void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir)
532 {
533 int tmp;
534 int16 *ptrQ, *ptrP;
535 void* vptr;
536 uint8 *pStrength;
537 void* refIdx;
538
539 if (MbP->mbMode == AVC_I4 || MbP->mbMode == AVC_I16 ||
540 MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
541 {
542
543 *((int*)Strength) = ININT_STRENGTH[0]; // Start with Strength=3. or Strength=4 for Mb-edge
544
545 }
546 else // if not intra or SP-frame
547 {
548 *((int*)Strength) = 0;
549
550 if (dir == 0) // Vertical Edge 0
551 {
552
553 //1. Check the ref_frame_id
554 refIdx = (void*) MbQ->RefIdx; //de-ref type-punned pointer fix
555 ptrQ = (int16*)refIdx;
556 refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer fix
557 ptrP = (int16*)refIdx;
558 pStrength = Strength;
559 if (ptrQ[0] != ptrP[1]) pStrength[0] = 1;
560 if (ptrQ[2] != ptrP[3]) pStrength[2] = 1;
561 pStrength[1] = pStrength[0];
562 pStrength[3] = pStrength[2];
563
564 //2. Check the non-zero coeff blocks (4x4)
565 if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[3] != 0) pStrength[0] = 2;
566 if (MbQ->nz_coeff[4] != 0 || MbP->nz_coeff[7] != 0) pStrength[1] = 2;
567 if (MbQ->nz_coeff[8] != 0 || MbP->nz_coeff[11] != 0) pStrength[2] = 2;
568 if (MbQ->nz_coeff[12] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
569
570 //3. Only need to check the mv difference
571 vptr = (void*)MbQ->mvL0; // for deref type-punned pointer
572 ptrQ = (int16*)vptr;
573 ptrP = (int16*)(MbP->mvL0 + 3); // points to 4x4 block #3 (the 4th column)
574
575 // 1st blk
576 if (*pStrength == 0)
577 {
578 // check |mv difference| >= 4
579 tmp = *ptrQ++ - *ptrP++;
580 if (tmp < 0) tmp = -tmp;
581 if (tmp >= 4) *pStrength = 1;
582
583 tmp = *ptrQ-- - *ptrP--;
584 if (tmp < 0) tmp = -tmp;
585 if (tmp >= 4) *pStrength = 1;
586 }
587
588 pStrength++;
589 ptrQ += 8;
590 ptrP += 8;
591
592 // 2nd blk
593 if (*pStrength == 0)
594 {
595 // check |mv difference| >= 4
596 tmp = *ptrQ++ - *ptrP++;
597 if (tmp < 0) tmp = -tmp;
598 if (tmp >= 4) *pStrength = 1;
599
600 tmp = *ptrQ-- - *ptrP--;
601 if (tmp < 0) tmp = -tmp;
602 if (tmp >= 4) *pStrength = 1;
603 }
604
605 pStrength++;
606 ptrQ += 8;
607 ptrP += 8;
608
609 // 3rd blk
610 if (*pStrength == 0)
611 {
612 // check |mv difference| >= 4
613 tmp = *ptrQ++ - *ptrP++;
614 if (tmp < 0) tmp = -tmp;
615 if (tmp >= 4) *pStrength = 1;
616
617 tmp = *ptrQ-- - *ptrP--;
618 if (tmp < 0) tmp = -tmp;
619 if (tmp >= 4) *pStrength = 1;
620 }
621
622 pStrength++;
623 ptrQ += 8;
624 ptrP += 8;
625
626 // 4th blk
627 if (*pStrength == 0)
628 {
629 // check |mv difference| >= 4
630 tmp = *ptrQ++ - *ptrP++;
631 if (tmp < 0) tmp = -tmp;
632 if (tmp >= 4) *pStrength = 1;
633
634 tmp = *ptrQ-- - *ptrP--;
635 if (tmp < 0) tmp = -tmp;
636 if (tmp >= 4) *pStrength = 1;
637 }
638 }
639 else // Horizontal Edge 0
640 {
641
642 //1. Check the ref_frame_id
643 refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer
644 ptrQ = (int16*)refIdx;
645 refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer
646 ptrP = (int16*)refIdx;
647 pStrength = Strength;
648 if (ptrQ[0] != ptrP[2]) pStrength[0] = 1;
649 if (ptrQ[1] != ptrP[3]) pStrength[2] = 1;
650 pStrength[1] = pStrength[0];
651 pStrength[3] = pStrength[2];
652
653 //2. Check the non-zero coeff blocks (4x4)
654 if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[12] != 0) pStrength[0] = 2;
655 if (MbQ->nz_coeff[1] != 0 || MbP->nz_coeff[13] != 0) pStrength[1] = 2;
656 if (MbQ->nz_coeff[2] != 0 || MbP->nz_coeff[14] != 0) pStrength[2] = 2;
657 if (MbQ->nz_coeff[3] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
658
659 //3. Only need to check the mv difference
660 vptr = (void*)MbQ->mvL0;
661 ptrQ = (int16*)vptr;
662 ptrP = (int16*)(MbP->mvL0 + 12); // points to 4x4 block #12 (the 4th row)
663
664 // 1st blk
665 if (*pStrength == 0)
666 {
667 // check |mv difference| >= 4
668 tmp = *ptrQ++ - *ptrP++;
669 if (tmp < 0) tmp = -tmp;
670 if (tmp >= 4) *pStrength = 1;
671
672 tmp = *ptrQ-- - *ptrP--;
673 if (tmp < 0) tmp = -tmp;
674 if (tmp >= 4) *pStrength = 1;
675 }
676
677 pStrength++;
678 ptrQ += 2;
679 ptrP += 2;
680
681 // 2nd blk
682 if (*pStrength == 0)
683 {
684 // check |mv difference| >= 4
685 tmp = *ptrQ++ - *ptrP++;
686 if (tmp < 0) tmp = -tmp;
687 if (tmp >= 4) *pStrength = 1;
688
689 tmp = *ptrQ-- - *ptrP--;
690 if (tmp < 0) tmp = -tmp;
691 if (tmp >= 4) *pStrength = 1;
692 }
693
694 pStrength++;
695 ptrQ += 2;
696 ptrP += 2;
697
698 // 3rd blk
699 if (*pStrength == 0)
700 {
701 // check |mv difference| >= 4
702 tmp = *ptrQ++ - *ptrP++;
703 if (tmp < 0) tmp = -tmp;
704 if (tmp >= 4) *pStrength = 1;
705
706 tmp = *ptrQ-- - *ptrP--;
707 if (tmp < 0) tmp = -tmp;
708 if (tmp >= 4) *pStrength = 1;
709 }
710
711 pStrength++;
712 ptrQ += 2;
713 ptrP += 2;
714
715 // 4th blk
716 if (*pStrength == 0)
717 {
718 // check |mv difference| >= 4
719 tmp = *ptrQ++ - *ptrP++;
720 if (tmp < 0) tmp = -tmp;
721 if (tmp >= 4) *pStrength = 1;
722
723 tmp = *ptrQ-- - *ptrP--;
724 if (tmp < 0) tmp = -tmp;
725 if (tmp >= 4) *pStrength = 1;
726 }
727
728 } /* end of: else if(dir == 0) */
729
730 } /* end of: if( !(MbP->mbMode == AVC_I4 ...) */
731 }
732
733
GetStrength_VerticalEdges(uint8 * Strength,AVCMacroblock * MbQ)734 void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ)
735 {
736 int idx, tmp;
737 int16 *ptr, *pmvx, *pmvy;
738 uint8 *pnz;
739 uint8 *pStrength, *pStr;
740 void* refIdx;
741
742 if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
743 {
744 *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge
745 *((int*)(Strength + 4)) = ININT_STRENGTH[2];
746 *((int*)(Strength + 8)) = ININT_STRENGTH[3];
747 }
748 else // Not intra or SP-frame
749 {
750
751 *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2.
752 *((int*)(Strength + 4)) = 0;
753 *((int*)(Strength + 8)) = 0;
754
755 //1. Check the ref_frame_id
756 refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer fix
757 ptr = (int16*)refIdx;
758 pStrength = Strength;
759 if (ptr[0] != ptr[1]) pStrength[4] = 1;
760 if (ptr[2] != ptr[3]) pStrength[6] = 1;
761 pStrength[5] = pStrength[4];
762 pStrength[7] = pStrength[6];
763
764 //2. Check the nz_coeff block and mv difference
765 pmvx = (int16*)(MbQ->mvL0 + 1); // points to 4x4 block #1,not #0
766 pmvy = pmvx + 1;
767 for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
768 {
769 // first/third row : 1,2,3 or 9,10,12
770 // Strength = 2 for a whole row
771 pnz = MbQ->nz_coeff + (idx << 2);
772 if (*pnz++ != 0) *pStrength = 2;
773 if (*pnz++ != 0)
774 {
775 *pStrength = 2;
776 *(pStrength + 4) = 2;
777 }
778 if (*pnz++ != 0)
779 {
780 *(pStrength + 4) = 2;
781 *(pStrength + 8) = 2;
782 }
783 if (*pnz != 0) *(pStrength + 8) = 2;
784
785 // Then Strength = 1
786 if (*pStrength == 0)
787 {
788 //within the same 8x8 block, no need to check the reference id
789 //only need to check the |mv difference| >= 4
790 tmp = *pmvx - *(pmvx - 2);
791 if (tmp < 0) tmp = -tmp;
792 if (tmp >= 4) *pStrength = 1;
793
794 tmp = *pmvy - *(pmvy - 2);
795 if (tmp < 0) tmp = -tmp;
796 if (tmp >= 4) *pStrength = 1;
797 }
798
799 pmvx += 2;
800 pmvy += 2;
801 pStr = pStrength + 4;
802
803 if (*pStr == 0)
804 {
805 //check the |mv difference| >= 4
806 tmp = *pmvx - *(pmvx - 2);
807 if (tmp < 0) tmp = -tmp;
808 if (tmp >= 4) *pStr = 1;
809
810 tmp = *pmvy - *(pmvy - 2);
811 if (tmp < 0) tmp = -tmp;
812 if (tmp >= 4) *pStr = 1;
813 }
814
815 pmvx += 2;
816 pmvy += 2;
817 pStr = pStrength + 8;
818
819 if (*pStr == 0)
820 {
821 //within the same 8x8 block, no need to check the reference id
822 //only need to check the |mv difference| >= 4
823 tmp = *pmvx - *(pmvx - 2);
824 if (tmp < 0) tmp = -tmp;
825 if (tmp >= 4) *pStr = 1;
826
827 tmp = *pmvy - *(pmvy - 2);
828 if (tmp < 0) tmp = -tmp;
829 if (tmp >= 4) *pStr = 1;
830 }
831
832 // Second/fourth row: 5,6,7 or 14,15,16
833 // Strength = 2 for a whole row
834 pnz = MbQ->nz_coeff + ((idx + 1) << 2);
835 if (*pnz++ != 0) *(pStrength + 1) = 2;
836 if (*pnz++ != 0)
837 {
838 *(pStrength + 1) = 2;
839 *(pStrength + 5) = 2;
840 }
841 if (*pnz++ != 0)
842 {
843 *(pStrength + 5) = 2;
844 *(pStrength + 9) = 2;
845 }
846 if (*pnz != 0) *(pStrength + 9) = 2;
847
848 // Then Strength = 1
849 pmvx += 4;
850 pmvy += 4;
851 pStr = pStrength + 1;
852 if (*pStr == 0)
853 {
854 //within the same 8x8 block, no need to check the reference id
855 //only need to check the |mv difference| >= 4
856 tmp = *pmvx - *(pmvx - 2);
857 if (tmp < 0) tmp = -tmp;
858 if (tmp >= 4) *pStr = 1;
859
860 tmp = *pmvy - *(pmvy - 2);
861 if (tmp < 0) tmp = -tmp;
862 if (tmp >= 4) *pStr = 1;
863 }
864
865 pmvx += 2;
866 pmvy += 2;
867 pStr = pStrength + 5;
868
869 if (*pStr == 0)
870 {
871 //check the |mv difference| >= 4
872 tmp = *pmvx - *(pmvx - 2);
873 if (tmp < 0) tmp = -tmp;
874 if (tmp >= 4) *pStr = 1;
875
876 tmp = *pmvy - *(pmvy - 2);
877 if (tmp < 0) tmp = -tmp;
878 if (tmp >= 4) *pStr = 1;
879 }
880
881 pmvx += 2;
882 pmvy += 2;
883 pStr = pStrength + 9;
884
885 if (*pStr == 0)
886 {
887 //within the same 8x8 block, no need to check the reference id
888 //only need to check the |mv difference| >= 4
889 tmp = *pmvx - *(pmvx - 2);
890 if (tmp < 0) tmp = -tmp;
891 if (tmp >= 4) *pStr = 1;
892
893 tmp = *pmvy - *(pmvy - 2);
894 if (tmp < 0) tmp = -tmp;
895 if (tmp >= 4) *pStr = 1;
896 }
897
898 // update some variables for the next two rows
899 pmvx += 4;
900 pmvy += 4;
901 pStrength += 2;
902
903 } /* end of: for(idx=0; idx<2; idx++) */
904
905 } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
906 }
907
908
GetStrength_HorizontalEdges(uint8 Strength[12],AVCMacroblock * MbQ)909 void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ)
910 {
911 int idx, tmp;
912 int16 *ptr, *pmvx, *pmvy;
913 uint8 *pStrength, *pStr;
914 void* refIdx;
915
916 if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
917 {
918 *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge
919 *((int*)(Strength + 4)) = ININT_STRENGTH[2];
920 *((int*)(Strength + 8)) = ININT_STRENGTH[3];
921 }
922 else // Not intra or SP-frame
923 {
924
925 *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2.
926 *((int*)(Strength + 4)) = 0; // for non-intra MB, strength = 0, 1 or 2.
927 *((int*)(Strength + 8)) = 0; // for non-intra MB, strength = 0, 1 or 2.
928
929
930 //1. Check the ref_frame_id
931 refIdx = (void*) MbQ->RefIdx; // de-ref type-punned fix
932 ptr = (int16*) refIdx;
933 pStrength = Strength;
934 if (ptr[0] != ptr[2]) pStrength[4] = 1;
935 if (ptr[1] != ptr[3]) pStrength[6] = 1;
936 pStrength[5] = pStrength[4];
937 pStrength[7] = pStrength[6];
938
939 //2. Check the nz_coeff block and mv difference
940 pmvx = (int16*)(MbQ->mvL0 + 4); // points to 4x4 block #4,not #0
941 pmvy = pmvx + 1;
942 for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
943 {
944 // first/third row : 1,2,3 or 9,10,12
945 // Strength = 2 for a whole row
946 if (MbQ->nz_coeff[idx] != 0) *pStrength = 2;
947 if (MbQ->nz_coeff[4+idx] != 0)
948 {
949 *pStrength = 2;
950 *(pStrength + 4) = 2;
951 }
952 if (MbQ->nz_coeff[8+idx] != 0)
953 {
954 *(pStrength + 4) = 2;
955 *(pStrength + 8) = 2;
956 }
957 if (MbQ->nz_coeff[12+idx] != 0) *(pStrength + 8) = 2;
958
959 // Then Strength = 1
960 if (*pStrength == 0)
961 {
962 //within the same 8x8 block, no need to check the reference id
963 //only need to check the |mv difference| >= 4
964 tmp = *pmvx - *(pmvx - 8);
965 if (tmp < 0) tmp = -tmp;
966 if (tmp >= 4) *pStrength = 1;
967
968 tmp = *pmvy - *(pmvy - 8);
969 if (tmp < 0) tmp = -tmp;
970 if (tmp >= 4) *pStrength = 1;
971 }
972
973 pmvx += 8;
974 pmvy += 8;
975 pStr = pStrength + 4;
976
977 if (*pStr == 0)
978 {
979 //check the |mv difference| >= 4
980 tmp = *pmvx - *(pmvx - 8);
981 if (tmp < 0) tmp = -tmp;
982 if (tmp >= 4) *pStr = 1;
983
984 tmp = *pmvy - *(pmvy - 8);
985 if (tmp < 0) tmp = -tmp;
986 if (tmp >= 4) *pStr = 1;
987 }
988
989 pmvx += 8;
990 pmvy += 8;
991 pStr = pStrength + 8;
992
993 if (*pStr == 0)
994 {
995 //within the same 8x8 block, no need to check the reference id
996 //only need to check the |mv difference| >= 4
997 tmp = *pmvx - *(pmvx - 8);
998 if (tmp < 0) tmp = -tmp;
999 if (tmp >= 4) *pStr = 1;
1000
1001 tmp = *pmvy - *(pmvy - 8);
1002 if (tmp < 0) tmp = -tmp;
1003 if (tmp >= 4) *pStr = 1;
1004 }
1005
1006 // Second/fourth row: 5,6,7 or 14,15,16
1007 // Strength = 2 for a whole row
1008 if (MbQ->nz_coeff[idx+1] != 0) *(pStrength + 1) = 2;
1009 if (MbQ->nz_coeff[4+idx+1] != 0)
1010 {
1011 *(pStrength + 1) = 2;
1012 *(pStrength + 5) = 2;
1013 }
1014 if (MbQ->nz_coeff[8+idx+1] != 0)
1015 {
1016 *(pStrength + 5) = 2;
1017 *(pStrength + 9) = 2;
1018 }
1019 if (MbQ->nz_coeff[12+idx+1] != 0) *(pStrength + 9) = 2;
1020
1021 // Then Strength = 1
1022 pmvx -= 14;
1023 pmvy -= 14; // -14 = -16 + 2
1024 pStr = pStrength + 1;
1025 if (*pStr == 0)
1026 {
1027 //within the same 8x8 block, no need to check the reference id
1028 //only need to check the |mv difference| >= 4
1029 tmp = *pmvx - *(pmvx - 8);
1030 if (tmp < 0) tmp = -tmp;
1031 if (tmp >= 4) *pStr = 1;
1032
1033 tmp = *pmvy - *(pmvy - 8);
1034 if (tmp < 0) tmp = -tmp;
1035 if (tmp >= 4) *pStr = 1;
1036 }
1037
1038 pmvx += 8;
1039 pmvy += 8;
1040 pStr = pStrength + 5;
1041
1042 if (*pStr == 0)
1043 {
1044 //check the |mv difference| >= 4
1045 tmp = *pmvx - *(pmvx - 8);
1046 if (tmp < 0) tmp = -tmp;
1047 if (tmp >= 4) *pStr = 1;
1048
1049 tmp = *pmvy - *(pmvy - 8);
1050 if (tmp < 0) tmp = -tmp;
1051 if (tmp >= 4) *pStr = 1;
1052 }
1053
1054 pmvx += 8;
1055 pmvy += 8;
1056 pStr = pStrength + 9;
1057
1058 if (*pStr == 0)
1059 {
1060 //within the same 8x8 block, no need to check the reference id
1061 //only need to check the |mv difference| >= 4
1062 tmp = *pmvx - *(pmvx - 8);
1063 if (tmp < 0) tmp = -tmp;
1064 if (tmp >= 4) *pStr = 1;
1065
1066 tmp = *pmvy - *(pmvy - 8);
1067 if (tmp < 0) tmp = -tmp;
1068 if (tmp >= 4) *pStr = 1;
1069 }
1070
1071 // update some variables for the next two rows
1072 pmvx -= 14;
1073 pmvy -= 14; // -14 = -16 + 2
1074 pStrength += 2;
1075
1076 } /* end of: for(idx=0; idx<2; idx++) */
1077
1078 } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
1079 }
1080
1081 /*
1082 *****************************************************************************************
1083 * \brief Filters one edge of 16 (luma) or 8 (chroma) pel
1084 *****************************************************************************************
1085 */
1086
EdgeLoop_Luma_horizontal(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1087 void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1088 {
1089 int pel, ap = 0, aq = 0, Strng;
1090 int C0, c0, dif, AbsDelta, tmp, tmp1;
1091 int L2 = 0, L1, L0, R0, R1, R2 = 0, RL0;
1092
1093
1094 if (Strength[0] == 4) /* INTRA strong filtering */
1095 {
1096 for (pel = 0; pel < 16; pel++)
1097 {
1098 R0 = SrcPtr[0];
1099 R1 = SrcPtr[pitch];
1100 L0 = SrcPtr[-pitch];
1101 L1 = SrcPtr[-(pitch<<1)];
1102
1103 // |R0 - R1| < Beta
1104 tmp1 = R0 - R1;
1105 if (tmp1 < 0) tmp1 = -tmp1;
1106 tmp = (tmp1 - Beta);
1107
1108 //|L0 - L1| < Beta
1109 tmp1 = L0 - L1;
1110 if (tmp1 < 0) tmp1 = -tmp1;
1111 tmp &= (tmp1 - Beta);
1112
1113 //|R0 - L0| < Alpha
1114 AbsDelta = R0 - L0;
1115 if (AbsDelta < 0) AbsDelta = -AbsDelta;
1116 tmp &= (AbsDelta - Alpha);
1117
1118 if (tmp < 0)
1119 {
1120 AbsDelta -= ((Alpha >> 2) + 2);
1121 R2 = SrcPtr[pitch<<1]; //inc2
1122 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
1123
1124 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1125 tmp = R0 - R2;
1126 if (tmp < 0) tmp = -tmp;
1127 aq = AbsDelta & (tmp - Beta);
1128
1129 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1130 tmp = L0 - L2;
1131 if (tmp < 0) tmp = -tmp;
1132 ap = AbsDelta & (tmp - Beta);
1133
1134 if (aq < 0)
1135 {
1136 tmp = R1 + R0 + L0;
1137 SrcPtr[0] = (L1 + (tmp << 1) + R2 + 4) >> 3;
1138 tmp += R2;
1139 SrcPtr[pitch] = (tmp + 2) >> 2;
1140 SrcPtr[pitch<<1] = (((SrcPtr[(pitch+(pitch<<1))] + R2) << 1) + tmp + 4) >> 3;
1141 }
1142 else
1143 SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
1144
1145 if (ap < 0)
1146 {
1147 tmp = L1 + R0 + L0;
1148 SrcPtr[-pitch] = (R1 + (tmp << 1) + L2 + 4) >> 3;
1149 tmp += L2;
1150 SrcPtr[-(pitch<<1)] = (tmp + 2) >> 2;
1151 SrcPtr[-(pitch+(pitch<<1))] = (((SrcPtr[-(pitch<<2)] + L2) << 1) + tmp + 4) >> 3;
1152 }
1153 else
1154 SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
1155
1156 } /* if(tmp < 0) */
1157
1158 SrcPtr ++; // Increment to next set of pixel
1159
1160 } /* end of: for(pel=0; pel<16; pel++) */
1161
1162 } /* if(Strength[0] == 4) */
1163
1164 else /* Normal filtering */
1165 {
1166 for (pel = 0; pel < 16; pel++)
1167 {
1168 Strng = Strength[pel >> 2];
1169 if (Strng)
1170 {
1171 R0 = SrcPtr[0];
1172 R1 = SrcPtr[pitch];
1173 L0 = SrcPtr[-pitch];
1174 L1 = SrcPtr[-(pitch<<1)]; // inc2
1175
1176 //|R0 - L0| < Alpha
1177 tmp1 = R0 - L0;
1178 if (tmp1 < 0) tmp1 = -tmp1;
1179 tmp = (tmp1 - Alpha);
1180
1181 // |R0 - R1| < Beta
1182 tmp1 = R0 - R1;
1183 if (tmp1 < 0) tmp1 = -tmp1;
1184 tmp &= (tmp1 - Beta);
1185
1186 //|L0 - L1| < Beta
1187 tmp1 = L0 - L1;
1188 if (tmp1 < 0) tmp1 = -tmp1;
1189 tmp &= (tmp1 - Beta);
1190
1191 if (tmp < 0)
1192 {
1193 R2 = SrcPtr[pitch<<1]; //inc2
1194 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
1195
1196 // |R0 - R2| < Beta
1197 tmp = R0 - R2;
1198 if (tmp < 0) tmp = -tmp;
1199 aq = tmp - Beta;
1200
1201 // |L0 - L2| < Beta
1202 tmp = L0 - L2;
1203 if (tmp < 0) tmp = -tmp;
1204 ap = tmp - Beta;
1205
1206
1207 c0 = C0 = clipTable[Strng];
1208 if (ap < 0) c0++;
1209 if (aq < 0) c0++;
1210
1211 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1212 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1213 tmp = dif + c0;
1214 if ((uint)tmp > (uint)c0 << 1)
1215 {
1216 tmp = ~(tmp >> 31);
1217 dif = (tmp & (c0 << 1)) - c0;
1218 }
1219
1220 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
1221 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1222 RL0 = R0 + L0;
1223 R0 -= dif;
1224 L0 += dif;
1225 if ((uint)R0 > 255)
1226 {
1227 tmp = ~(R0 >> 31);
1228 R0 = tmp & 255;
1229 }
1230 if ((uint)L0 > 255)
1231 {
1232 tmp = ~(L0 >> 31);
1233 L0 = tmp & 255;
1234 }
1235 SrcPtr[-pitch] = L0;
1236 SrcPtr[0] = R0;
1237
1238 if (C0 != 0) /* Multiple zeros in the clip tables */
1239 {
1240 if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
1241 {
1242 R2 = (R2 + ((RL0 + 1) >> 1) - (R1 << 1)) >> 1;
1243 tmp = R2 + C0;
1244 if ((uint)tmp > (uint)C0 << 1)
1245 {
1246 tmp = ~(tmp >> 31);
1247 R2 = (tmp & (C0 << 1)) - C0;
1248 }
1249 SrcPtr[pitch] += R2;
1250 }
1251
1252 if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
1253 {
1254 L2 = (L2 + ((RL0 + 1) >> 1) - (L1 << 1)) >> 1;
1255 tmp = L2 + C0;
1256 if ((uint)tmp > (uint)C0 << 1)
1257 {
1258 tmp = ~(tmp >> 31);
1259 L2 = (tmp & (C0 << 1)) - C0;
1260 }
1261 SrcPtr[-(pitch<<1)] += L2;
1262 }
1263 }
1264
1265 } /* if(tmp < 0) */
1266
1267 } /* end of: if((Strng = Strength[pel >> 2])) */
1268
1269 SrcPtr ++; // Increment to next set of pixel
1270
1271 } /* for(pel=0; pel<16; pel++) */
1272
1273 } /* else if(Strength[0] == 4) */
1274 }
1275
EdgeLoop_Luma_vertical(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1276 void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1277 {
1278 int pel, ap = 1, aq = 1;
1279 int C0, c0, dif, AbsDelta, Strng, tmp, tmp1;
1280 int L2 = 0, L1, L0, R0, R1, R2 = 0;
1281 uint8 *ptr, *ptr1;
1282 uint R_in, L_in;
1283 uint R_out, L_out;
1284
1285
1286 if (Strength[0] == 4) /* INTRA strong filtering */
1287 {
1288
1289 for (pel = 0; pel < 16; pel++)
1290 {
1291
1292 // Read 8 pels
1293 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
1294 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1295 R1 = (R_in >> 8) & 0xff;
1296 R0 = R_in & 0xff;
1297 L0 = L_in >> 24;
1298 L1 = (L_in >> 16) & 0xff;
1299
1300 // |R0 - R1| < Beta
1301 tmp1 = (R_in & 0xff) - R1;
1302 if (tmp1 < 0) tmp1 = -tmp1;
1303 tmp = (tmp1 - Beta);
1304
1305
1306 //|L0 - L1| < Beta
1307 tmp1 = (L_in >> 24) - L1;
1308 if (tmp1 < 0) tmp1 = -tmp1;
1309 tmp &= (tmp1 - Beta);
1310
1311 //|R0 - L0| < Alpha
1312 AbsDelta = (R_in & 0xff) - (L_in >> 24);
1313 if (AbsDelta < 0) AbsDelta = -AbsDelta;
1314 tmp &= (AbsDelta - Alpha);
1315
1316 if (tmp < 0)
1317 {
1318 AbsDelta -= ((Alpha >> 2) + 2);
1319 R2 = (R_in >> 16) & 0xff;
1320 L2 = (L_in >> 8) & 0xff;
1321
1322 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1323 tmp1 = (R_in & 0xff) - R2;
1324 if (tmp1 < 0) tmp1 = -tmp1;
1325 aq = AbsDelta & (tmp1 - Beta);
1326
1327 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
1328 tmp1 = (L_in >> 24) - L2;
1329 if (tmp1 < 0) tmp1 = -tmp1;
1330 ap = AbsDelta & (tmp1 - Beta);
1331
1332
1333 ptr = SrcPtr;
1334 if (aq < 0)
1335 {
1336 R_out = (R_in >> 24) << 24; // Keep R3 at the fourth byte
1337
1338 tmp = R0 + L0 + R1;
1339 R_out |= (((tmp << 1) + L1 + R2 + 4) >> 3);
1340 tmp += R2;
1341 R_out |= (((tmp + 2) >> 2) << 8);
1342 tmp1 = ((R_in >> 24) + R2) << 1;
1343 R_out |= (((tmp1 + tmp + 4) >> 3) << 16);
1344
1345 *((uint *)SrcPtr) = R_out;
1346 }
1347 else
1348 *ptr = ((R1 << 1) + R0 + L1 + 2) >> 2;
1349
1350
1351 if (ap < 0)
1352 {
1353 L_out = (L_in << 24) >> 24; // Keep L3 at the first byte
1354
1355 tmp = R0 + L0 + L1;
1356 L_out |= ((((tmp << 1) + R1 + L2 + 4) >> 3) << 24);
1357 tmp += L2;
1358 L_out |= (((tmp + 2) >> 2) << 16);
1359 tmp1 = ((L_in & 0xff) + L2) << 1;
1360 L_out |= (((tmp1 + tmp + 4) >> 3) << 8);
1361
1362 *((uint *)(SrcPtr - 4)) = L_out;
1363 }
1364 else
1365 *(--ptr) = ((L1 << 1) + L0 + R1 + 2) >> 2;
1366
1367 } /* if(tmp < 0) */
1368
1369 SrcPtr += pitch; // Increment to next set of pixel
1370
1371 } /* end of: for(pel=0; pel<16; pel++) */
1372
1373 } /* if(Strength[0] == 4) */
1374
1375 else /* Normal filtering */
1376 {
1377
1378 for (pel = 0; pel < 16; pel++)
1379 {
1380 Strng = Strength[pel >> 2];
1381 if (Strng)
1382 {
1383 // Read 8 pels
1384 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
1385 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1386 R1 = (R_in >> 8) & 0xff;
1387 R0 = R_in & 0xff;
1388 L0 = L_in >> 24;
1389 L1 = (L_in >> 16) & 0xff;
1390
1391 //|R0 - L0| < Alpha
1392 tmp = R0 - L0;
1393 if (tmp < 0) tmp = -tmp;
1394 tmp -= Alpha;
1395
1396 // |R0 - R1| < Beta
1397 tmp1 = R0 - R1;
1398 if (tmp1 < 0) tmp1 = -tmp1;
1399 tmp &= (tmp1 - Beta);
1400
1401 //|L0 - L1| < Beta
1402 tmp1 = L0 - L1;
1403 if (tmp1 < 0) tmp1 = -tmp1;
1404 tmp &= (tmp1 - Beta);
1405
1406 if (tmp < 0)
1407 {
1408 L2 = SrcPtr[-3];
1409 R2 = SrcPtr[2];
1410
1411 // |R0 - R2| < Beta
1412 tmp = R0 - R2;
1413 if (tmp < 0) tmp = -tmp;
1414 aq = tmp - Beta;
1415
1416 // |L0 - L2| < Beta
1417 tmp = L0 - L2;
1418 if (tmp < 0) tmp = -tmp;
1419 ap = tmp - Beta;
1420
1421
1422 c0 = C0 = clipTable[Strng];
1423 if (ap < 0) c0++;
1424 if (aq < 0) c0++;
1425
1426 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1427 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1428 tmp = dif + c0;
1429 if ((uint)tmp > (uint)c0 << 1)
1430 {
1431 tmp = ~(tmp >> 31);
1432 dif = (tmp & (c0 << 1)) - c0;
1433 }
1434
1435 ptr = SrcPtr;
1436 ptr1 = SrcPtr - 1;
1437 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
1438 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1439 R_in = R0 - dif;
1440 L_in = L0 + dif; /* cannot re-use R0 and L0 here */
1441 if ((uint)R_in > 255)
1442 {
1443 tmp = ~((int)R_in >> 31);
1444 R_in = tmp & 255;
1445 }
1446 if ((uint)L_in > 255)
1447 {
1448 tmp = ~((int)L_in >> 31);
1449 L_in = tmp & 255;
1450 }
1451 *ptr1-- = L_in;
1452 *ptr++ = R_in;
1453
1454 if (C0 != 0) // Multiple zeros in the clip tables
1455 {
1456 if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
1457 {
1458 L2 = (L2 + ((R0 + L0 + 1) >> 1) - (L1 << 1)) >> 1;
1459 tmp = L2 + C0;
1460 if ((uint)tmp > (uint)C0 << 1)
1461 {
1462 tmp = ~(tmp >> 31);
1463 L2 = (tmp & (C0 << 1)) - C0;
1464 }
1465 *ptr1 += L2;
1466 }
1467
1468 if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
1469 {
1470 R2 = (R2 + ((R0 + L0 + 1) >> 1) - (R1 << 1)) >> 1;
1471 tmp = R2 + C0;
1472 if ((uint)tmp > (uint)C0 << 1)
1473 {
1474 tmp = ~(tmp >> 31);
1475 R2 = (tmp & (C0 << 1)) - C0;
1476 }
1477 *ptr += R2;
1478 }
1479 }
1480
1481 } /* if(tmp < 0) */
1482
1483 } /* end of: if((Strng = Strength[pel >> 2])) */
1484
1485 SrcPtr += pitch; // Increment to next set of pixel
1486
1487 } /* for(pel=0; pel<16; pel++) */
1488
1489 } /* else if(Strength[0] == 4) */
1490
1491 }
1492
EdgeLoop_Chroma_vertical(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1493 void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1494 {
1495 int pel, Strng;
1496 int c0, dif;
1497 int L1, L0, R0, R1, tmp, tmp1;
1498 uint8 *ptr;
1499 uint R_in, L_in;
1500
1501
1502 for (pel = 0; pel < 16; pel++)
1503 {
1504 Strng = Strength[pel>>2];
1505 if (Strng)
1506 {
1507 // Read 8 pels
1508 R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
1509 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
1510 R1 = (R_in >> 8) & 0xff;
1511 R0 = R_in & 0xff;
1512 L0 = L_in >> 24;
1513 L1 = (L_in >> 16) & 0xff;
1514
1515 // |R0 - R1| < Beta
1516 tmp1 = R0 - R1;
1517 if (tmp1 < 0) tmp1 = -tmp1;
1518 tmp = (tmp1 - Beta);
1519
1520 //|L0 - L1| < Beta
1521 tmp1 = L0 - L1;
1522 if (tmp1 < 0) tmp1 = -tmp1;
1523 tmp &= (tmp1 - Beta);
1524
1525 //|R0 - L0| < Alpha
1526 tmp1 = R0 - L0;
1527 if (tmp1 < 0) tmp1 = -tmp1;
1528 tmp &= (tmp1 - Alpha);
1529
1530 if (tmp < 0)
1531 {
1532 ptr = SrcPtr;
1533 if (Strng == 4) /* INTRA strong filtering */
1534 {
1535 *ptr-- = ((R1 << 1) + R0 + L1 + 2) >> 2;
1536 *ptr = ((L1 << 1) + L0 + R1 + 2) >> 2;
1537 }
1538 else /* normal filtering */
1539 {
1540 c0 = clipTable[Strng] + 1;
1541 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1542 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1543 tmp = dif + c0;
1544 if ((uint)tmp > (uint)c0 << 1)
1545 {
1546 tmp = ~(tmp >> 31);
1547 dif = (tmp & (c0 << 1)) - c0;
1548 }
1549
1550 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
1551 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1552 L0 += dif;
1553 R0 -= dif;
1554 if ((uint)L0 > 255)
1555 {
1556 tmp = ~(L0 >> 31);
1557 L0 = tmp & 255;
1558 }
1559 if ((uint)R0 > 255)
1560 {
1561 tmp = ~(R0 >> 31);
1562 R0 = tmp & 255;
1563 }
1564
1565 *ptr-- = R0;
1566 *ptr = L0;
1567 }
1568 }
1569 pel ++;
1570 SrcPtr += pitch; // Increment to next set of pixel
1571
1572 } /* end of: if((Strng = Strength[pel >> 2])) */
1573 else
1574 {
1575 pel += 3;
1576 SrcPtr += (pitch << 1); //PtrInc << 1;
1577 }
1578
1579 } /* end of: for(pel=0; pel<16; pel++) */
1580 }
1581
1582
EdgeLoop_Chroma_horizontal(uint8 * SrcPtr,uint8 * Strength,int Alpha,int Beta,int * clipTable,int pitch)1583 void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
1584 {
1585 int pel, Strng;
1586 int c0, dif;
1587 int L1, L0, R0, R1, tmp, tmp1;
1588
1589 for (pel = 0; pel < 16; pel++)
1590 {
1591 Strng = Strength[pel>>2];
1592 if (Strng)
1593 {
1594 R0 = SrcPtr[0];
1595 L0 = SrcPtr[-pitch];
1596 L1 = SrcPtr[-(pitch<<1)]; //inc2
1597 R1 = SrcPtr[pitch];
1598
1599 // |R0 - R1| < Beta
1600 tmp1 = R0 - R1;
1601 if (tmp1 < 0) tmp1 = -tmp1;
1602 tmp = (tmp1 - Beta);
1603
1604 //|L0 - L1| < Beta
1605 tmp1 = L0 - L1;
1606 if (tmp1 < 0) tmp1 = -tmp1;
1607 tmp &= (tmp1 - Beta);
1608
1609 //|R0 - L0| < Alpha
1610 tmp1 = R0 - L0;
1611 if (tmp1 < 0) tmp1 = -tmp1;
1612 tmp &= (tmp1 - Alpha);
1613
1614 if (tmp < 0)
1615 {
1616 if (Strng == 4) /* INTRA strong filtering */
1617 {
1618 SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
1619 SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
1620 }
1621 else /* normal filtering */
1622 {
1623 c0 = clipTable[Strng] + 1;
1624 //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
1625 dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
1626 tmp = dif + c0;
1627 if ((uint)tmp > (uint)c0 << 1)
1628 {
1629 tmp = ~(tmp >> 31);
1630 dif = (tmp & (c0 << 1)) - c0;
1631 }
1632
1633 //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
1634 //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
1635 L0 += dif;
1636 R0 -= dif;
1637 if ((uint)L0 > 255)
1638 {
1639 tmp = ~(L0 >> 31);
1640 L0 = tmp & 255;
1641 }
1642 if ((uint)R0 > 255)
1643 {
1644 tmp = ~(R0 >> 31);
1645 R0 = tmp & 255;
1646 }
1647 SrcPtr[0] = R0;
1648 SrcPtr[-pitch] = L0;
1649 }
1650 }
1651
1652 pel ++;
1653 SrcPtr ++; // Increment to next set of pixel
1654
1655 } /* end of: if((Strng = Strength[pel >> 2])) */
1656 else
1657 {
1658 pel += 3;
1659 SrcPtr += 2;
1660 }
1661
1662 } /* end of: for(pel=0; pel<16; pel++) */
1663 }
1664
1665
1666
1667
1668