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