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 "mp4dec_lib.h"
20
21 #ifdef PV_ANNEX_IJKT_SUPPORT
22 #include "motion_comp.h"
23 #include "mbtype_mode.h"
24 const static int STRENGTH_tab[] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12};
25 #endif
26
27 #ifdef PV_POSTPROC_ON
28 /*----------------------------------------------------------------------------
29 ; FUNCTION CODE
30 ----------------------------------------------------------------------------*/
PostFilter(VideoDecData * video,int filter_type,uint8 * output)31 void PostFilter(
32 VideoDecData *video,
33 int filter_type,
34 uint8 *output)
35 {
36 /*----------------------------------------------------------------------------
37 ; Define all local variables
38 ----------------------------------------------------------------------------*/
39 uint8 *pp_mod;
40 int16 *QP_store;
41 int combined_with_deblock_filter;
42 int nTotalMB = video->nTotalMB;
43 int width, height;
44 int32 size;
45 int softDeblocking;
46 uint8 *decodedFrame = video->videoDecControls->outputFrame;
47 /*----------------------------------------------------------------------------
48 ; Function body here
49 ----------------------------------------------------------------------------*/
50 width = video->width;
51 height = video->height;
52 size = (int32)width * height;
53
54 oscl_memcpy(output, decodedFrame, size);
55 oscl_memcpy(output + size, decodedFrame + size, (size >> 2));
56 oscl_memcpy(output + size + (size >> 2), decodedFrame + size + (size >> 2), (size >> 2));
57
58 if (filter_type == 0)
59 return;
60
61 /* The softDecoding cutoff corresponds to ~93000 bps for QCIF 15fps clip */
62 if (PVGetDecBitrate(video->videoDecControls) > (100*video->frameRate*(size >> 12))) // MC_sofDeblock
63 softDeblocking = FALSE;
64 else
65 softDeblocking = TRUE;
66
67 combined_with_deblock_filter = filter_type & PV_DEBLOCK;
68 QP_store = video->QPMB;
69
70 /* Luma */
71 pp_mod = video->pstprcTypCur;
72
73 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
74 {
75 CombinedHorzVertRingFilter(output, width, height, QP_store, 0, pp_mod);
76 }
77 else
78 {
79 if (filter_type & PV_DEBLOCK)
80 {
81 if (softDeblocking)
82 {
83 CombinedHorzVertFilter(output, width, height,
84 QP_store, 0, pp_mod);
85 }
86 else
87 {
88 CombinedHorzVertFilter_NoSoftDeblocking(output, width, height,
89 QP_store, 0, pp_mod);
90 }
91 }
92 if (filter_type & PV_DERING)
93 {
94 Deringing_Luma(output, width, height, QP_store,
95 combined_with_deblock_filter, pp_mod);
96
97 }
98 }
99
100 /* Chroma */
101
102 pp_mod += (nTotalMB << 2);
103 output += size;
104
105 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
106 {
107 CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
108 }
109 else
110 {
111 if (filter_type & PV_DEBLOCK)
112 {
113 if (softDeblocking)
114 {
115 CombinedHorzVertFilter(output, (int)(width >> 1),
116 (int)(height >> 1), QP_store, (int) 1, pp_mod);
117 }
118 else
119 {
120 CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
121 (int)(height >> 1), QP_store, (int) 1, pp_mod);
122 }
123 }
124 if (filter_type & PV_DERING)
125 {
126 Deringing_Chroma(output, (int)(width >> 1),
127 (int)(height >> 1), QP_store,
128 combined_with_deblock_filter, pp_mod);
129 }
130 }
131
132 pp_mod += nTotalMB;
133 output += (size >> 2);
134
135 if ((filter_type & PV_DEBLOCK) && (filter_type & PV_DERING))
136 {
137 CombinedHorzVertRingFilter(output, (int)(width >> 1), (int)(height >> 1), QP_store, (int) 1, pp_mod);
138 }
139 else
140 {
141 if (filter_type & PV_DEBLOCK)
142 {
143 if (softDeblocking)
144 {
145 CombinedHorzVertFilter(output, (int)(width >> 1),
146 (int)(height >> 1), QP_store, (int) 1, pp_mod);
147 }
148 else
149 {
150 CombinedHorzVertFilter_NoSoftDeblocking(output, (int)(width >> 1),
151 (int)(height >> 1), QP_store, (int) 1, pp_mod);
152 }
153 }
154 if (filter_type & PV_DERING)
155 {
156 Deringing_Chroma(output, (int)(width >> 1),
157 (int)(height >> 1), QP_store,
158 combined_with_deblock_filter, pp_mod);
159 }
160 }
161
162 /* swap current pp_mod to prev_frame pp_mod */
163 pp_mod = video->pstprcTypCur;
164 video->pstprcTypCur = video->pstprcTypPrv;
165 video->pstprcTypPrv = pp_mod;
166
167 /*----------------------------------------------------------------------------
168 ; Return nothing or data or data pointer
169 ----------------------------------------------------------------------------*/
170 return;
171 }
172 #endif
173
174
175 #ifdef PV_ANNEX_IJKT_SUPPORT
H263_Deblock(uint8 * rec,int width,int height,int16 * QP_store,uint8 * mode,int chr,int annex_T)176 void H263_Deblock(uint8 *rec,
177 int width,
178 int height,
179 int16 *QP_store,
180 uint8 *mode,
181 int chr, int annex_T)
182 {
183 /*----------------------------------------------------------------------------
184 ; Define all local variables
185 ----------------------------------------------------------------------------*/
186 int i, j, k;
187 uint8 *rec_y;
188 int tmpvar;
189 int mbnum, strength, A_D, d1_2, d1, d2, A, B, C, D, b_size;
190 int d, offset, nMBPerRow, nMBPerCol, width2 = (width << 1);
191 /* MAKE SURE I-VOP INTRA MACROBLOCKS ARE SET TO NON-SKIPPED MODE*/
192 mbnum = 0;
193
194 if (chr)
195 {
196 nMBPerRow = width >> 3;
197 nMBPerCol = height >> 3;
198 b_size = 8;
199 }
200 else
201 {
202 nMBPerRow = width >> 4;
203 nMBPerCol = height >> 4;
204 b_size = 16;
205 }
206
207
208 /********************************* VERTICAL FILTERING ****************************/
209 /* vertical filtering of mid sections no need to check neighboring QP's etc */
210 if (!chr)
211 {
212 rec_y = rec + (width << 3);
213 for (i = 0; i < (height >> 4); i++)
214 {
215 for (j = 0; j < (width >> 4); j++)
216 {
217 if (mode[mbnum] != MODE_SKIPPED)
218 {
219 k = 16;
220 strength = STRENGTH_tab[QP_store[mbnum]];
221 while (k--)
222 {
223 A = *(rec_y - width2);
224 D = *(rec_y + width);
225 A_D = A - D;
226 C = *rec_y;
227 B = *(rec_y - width);
228 d = (((C - B) << 2) + A_D);
229
230 if (d < 0)
231 {
232 d1 = -(-d >> 3);
233 if (d1 < -(strength << 1))
234 {
235 d1 = 0;
236 }
237 else if (d1 < -strength)
238 {
239 d1 = -d1 - (strength << 1);
240 }
241 d1_2 = -d1 >> 1;
242 }
243 else
244 {
245 d1 = d >> 3;
246 if (d1 > (strength << 1))
247 {
248 d1 = 0;
249 }
250 else if (d1 > strength)
251 {
252 d1 = (strength << 1) - d1;
253 }
254 d1_2 = d1 >> 1;
255 }
256
257 if (A_D < 0)
258 {
259 d2 = -(-A_D >> 2);
260 if (d2 < -d1_2)
261 {
262 d2 = -d1_2;
263 }
264 }
265 else
266 {
267 d2 = A_D >> 2;
268 if (d2 > d1_2)
269 {
270 d2 = d1_2;
271 }
272 }
273
274 *(rec_y - width2) = A - d2;
275 tmpvar = B + d1;
276 CLIP_RESULT(tmpvar)
277 *(rec_y - width) = tmpvar;
278 tmpvar = C - d1;
279 CLIP_RESULT(tmpvar)
280 *rec_y = tmpvar;
281 *(rec_y + width) = D + d2;
282 rec_y++;
283 }
284 }
285 else
286 {
287 rec_y += b_size;
288 }
289 mbnum++;
290 }
291 rec_y += (15 * width);
292
293 }
294 }
295
296 /* VERTICAL boundary blocks */
297
298
299 rec_y = rec + width * b_size;
300
301 mbnum = nMBPerRow;
302 for (i = 0; i < nMBPerCol - 1; i++)
303 {
304 for (j = 0; j < nMBPerRow; j++)
305 {
306 if (mode[mbnum] != MODE_SKIPPED || mode[mbnum - nMBPerRow] != MODE_SKIPPED)
307 {
308 k = b_size;
309 if (mode[mbnum] != MODE_SKIPPED)
310 {
311 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
312 }
313 else
314 {
315 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - nMBPerRow]] : QP_store[mbnum - nMBPerRow])];
316 }
317
318 while (k--)
319 {
320 A = *(rec_y - width2);
321 D = *(rec_y + width);
322 A_D = A - D;
323 C = *rec_y;
324 B = *(rec_y - width);
325 d = (((C - B) << 2) + A_D);
326
327 if (d < 0)
328 {
329 d1 = -(-d >> 3);
330 if (d1 < -(strength << 1))
331 {
332 d1 = 0;
333 }
334 else if (d1 < -strength)
335 {
336 d1 = -d1 - (strength << 1);
337 }
338 d1_2 = -d1 >> 1;
339 }
340 else
341 {
342 d1 = d >> 3;
343 if (d1 > (strength << 1))
344 {
345 d1 = 0;
346 }
347 else if (d1 > strength)
348 {
349 d1 = (strength << 1) - d1;
350 }
351 d1_2 = d1 >> 1;
352 }
353
354 if (A_D < 0)
355 {
356 d2 = -(-A_D >> 2);
357 if (d2 < -d1_2)
358 {
359 d2 = -d1_2;
360 }
361 }
362 else
363 {
364 d2 = A_D >> 2;
365 if (d2 > d1_2)
366 {
367 d2 = d1_2;
368 }
369 }
370
371 *(rec_y - width2) = A - d2;
372 tmpvar = B + d1;
373 CLIP_RESULT(tmpvar)
374 *(rec_y - width) = tmpvar;
375 tmpvar = C - d1;
376 CLIP_RESULT(tmpvar)
377 *rec_y = tmpvar;
378 *(rec_y + width) = D + d2;
379 rec_y++;
380 }
381 }
382 else
383 {
384 rec_y += b_size;
385 }
386 mbnum++;
387 }
388 rec_y += ((b_size - 1) * width);
389
390 }
391
392
393 /***************************HORIZONTAL FILTERING ********************************************/
394 mbnum = 0;
395 /* HORIZONTAL INNER */
396 if (!chr)
397 {
398 rec_y = rec + 8;
399 offset = width * b_size - b_size;
400
401 for (i = 0; i < nMBPerCol; i++)
402 {
403 for (j = 0; j < nMBPerRow; j++)
404 {
405 if (mode[mbnum] != MODE_SKIPPED)
406 {
407 k = 16;
408 strength = STRENGTH_tab[QP_store[mbnum]];
409 while (k--)
410 {
411 A = *(rec_y - 2);
412 D = *(rec_y + 1);
413 A_D = A - D;
414 C = *rec_y;
415 B = *(rec_y - 1);
416 d = (((C - B) << 2) + A_D);
417
418 if (d < 0)
419 {
420 d1 = -(-d >> 3);
421 if (d1 < -(strength << 1))
422 {
423 d1 = 0;
424 }
425 else if (d1 < -strength)
426 {
427 d1 = -d1 - (strength << 1);
428 }
429 d1_2 = -d1 >> 1;
430 }
431 else
432 {
433 d1 = d >> 3;
434 if (d1 > (strength << 1))
435 {
436 d1 = 0;
437 }
438 else if (d1 > strength)
439 {
440 d1 = (strength << 1) - d1;
441 }
442 d1_2 = d1 >> 1;
443 }
444
445 if (A_D < 0)
446 {
447 d2 = -(-A_D >> 2);
448 if (d2 < -d1_2)
449 {
450 d2 = -d1_2;
451 }
452 }
453 else
454 {
455 d2 = A_D >> 2;
456 if (d2 > d1_2)
457 {
458 d2 = d1_2;
459 }
460 }
461
462 *(rec_y - 2) = A - d2;
463 tmpvar = B + d1;
464 CLIP_RESULT(tmpvar)
465 *(rec_y - 1) = tmpvar;
466 tmpvar = C - d1;
467 CLIP_RESULT(tmpvar)
468 *rec_y = tmpvar;
469 *(rec_y + 1) = D + d2;
470 rec_y += width;
471 }
472 rec_y -= offset;
473 }
474 else
475 {
476 rec_y += b_size;
477 }
478 mbnum++;
479 }
480 rec_y += (15 * width);
481
482 }
483 }
484
485
486
487 /* HORIZONTAL EDGE */
488 rec_y = rec + b_size;
489 offset = width * b_size - b_size;
490 mbnum = 1;
491 for (i = 0; i < nMBPerCol; i++)
492 {
493 for (j = 0; j < nMBPerRow - 1; j++)
494 {
495 if (mode[mbnum] != MODE_SKIPPED || mode[mbnum-1] != MODE_SKIPPED)
496 {
497 k = b_size;
498 if (mode[mbnum] != MODE_SKIPPED)
499 {
500 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum]] : QP_store[mbnum])];
501 }
502 else
503 {
504 strength = STRENGTH_tab[(annex_T ? MQ_chroma_QP_table[QP_store[mbnum - 1]] : QP_store[mbnum - 1])];
505 }
506
507 while (k--)
508 {
509 A = *(rec_y - 2);
510 D = *(rec_y + 1);
511 A_D = A - D;
512 C = *rec_y;
513 B = *(rec_y - 1);
514 d = (((C - B) << 2) + A_D);
515
516 if (d < 0)
517 {
518 d1 = -(-d >> 3);
519 if (d1 < -(strength << 1))
520 {
521 d1 = 0;
522 }
523 else if (d1 < -strength)
524 {
525 d1 = -d1 - (strength << 1);
526 }
527 d1_2 = -d1 >> 1;
528 }
529 else
530 {
531 d1 = d >> 3;
532 if (d1 > (strength << 1))
533 {
534 d1 = 0;
535 }
536 else if (d1 > strength)
537 {
538 d1 = (strength << 1) - d1;
539 }
540 d1_2 = d1 >> 1;
541 }
542
543 if (A_D < 0)
544 {
545 d2 = -(-A_D >> 2);
546 if (d2 < -d1_2)
547 {
548 d2 = -d1_2;
549 }
550 }
551 else
552 {
553 d2 = A_D >> 2;
554 if (d2 > d1_2)
555 {
556 d2 = d1_2;
557 }
558 }
559
560 *(rec_y - 2) = A - d2;
561 tmpvar = B + d1;
562 CLIP_RESULT(tmpvar)
563 *(rec_y - 1) = tmpvar;
564 tmpvar = C - d1;
565 CLIP_RESULT(tmpvar)
566 *rec_y = tmpvar;
567 *(rec_y + 1) = D + d2;
568 rec_y += width;
569 }
570 rec_y -= offset;
571 }
572 else
573 {
574 rec_y += b_size;
575 }
576 mbnum++;
577 }
578 rec_y += ((width * (b_size - 1)) + b_size);
579 mbnum++;
580 }
581
582 return;
583 }
584 #endif
585
586