Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * This file is part of FFmpeg. | |
3 | * | |
4 | * FFmpeg is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU Lesser General Public | |
6 | * License as published by the Free Software Foundation; either | |
7 | * version 2.1 of the License, or (at your option) any later version. | |
8 | * | |
9 | * FFmpeg is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | * Lesser General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU Lesser General Public | |
15 | * License along with FFmpeg; if not, write to the Free Software | |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
17 | */ | |
18 | ||
19 | #include <stdint.h> | |
20 | ||
21 | #include "libavutil/attributes.h" | |
22 | #include "libavutil/common.h" | |
23 | #include "config.h" | |
24 | #include "h263dsp.h" | |
25 | ||
26 | const uint8_t ff_h263_loop_filter_strength[32] = { | |
27 | 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, | |
28 | 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12 | |
29 | }; | |
30 | ||
31 | static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale) | |
32 | { | |
33 | int y; | |
34 | const int strength = ff_h263_loop_filter_strength[qscale]; | |
35 | ||
36 | for (y = 0; y < 8; y++) { | |
37 | int d1, d2, ad1; | |
38 | int p0 = src[y * stride - 2]; | |
39 | int p1 = src[y * stride - 1]; | |
40 | int p2 = src[y * stride + 0]; | |
41 | int p3 = src[y * stride + 1]; | |
42 | int d = (p0 - p3 + 4 * (p2 - p1)) / 8; | |
43 | ||
44 | if (d < -2 * strength) | |
45 | d1 = 0; | |
46 | else if (d < -strength) | |
47 | d1 = -2 * strength - d; | |
48 | else if (d < strength) | |
49 | d1 = d; | |
50 | else if (d < 2 * strength) | |
51 | d1 = 2 * strength - d; | |
52 | else | |
53 | d1 = 0; | |
54 | ||
55 | p1 += d1; | |
56 | p2 -= d1; | |
57 | if (p1 & 256) | |
58 | p1 = ~(p1 >> 31); | |
59 | if (p2 & 256) | |
60 | p2 = ~(p2 >> 31); | |
61 | ||
62 | src[y * stride - 1] = p1; | |
63 | src[y * stride + 0] = p2; | |
64 | ||
65 | ad1 = FFABS(d1) >> 1; | |
66 | ||
67 | d2 = av_clip((p0 - p3) / 4, -ad1, ad1); | |
68 | ||
69 | src[y * stride - 2] = p0 - d2; | |
70 | src[y * stride + 1] = p3 + d2; | |
71 | } | |
72 | } | |
73 | ||
74 | static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale) | |
75 | { | |
76 | int x; | |
77 | const int strength = ff_h263_loop_filter_strength[qscale]; | |
78 | ||
79 | for (x = 0; x < 8; x++) { | |
80 | int d1, d2, ad1; | |
81 | int p0 = src[x - 2 * stride]; | |
82 | int p1 = src[x - 1 * stride]; | |
83 | int p2 = src[x + 0 * stride]; | |
84 | int p3 = src[x + 1 * stride]; | |
85 | int d = (p0 - p3 + 4 * (p2 - p1)) / 8; | |
86 | ||
87 | if (d < -2 * strength) | |
88 | d1 = 0; | |
89 | else if (d < -strength) | |
90 | d1 = -2 * strength - d; | |
91 | else if (d < strength) | |
92 | d1 = d; | |
93 | else if (d < 2 * strength) | |
94 | d1 = 2 * strength - d; | |
95 | else | |
96 | d1 = 0; | |
97 | ||
98 | p1 += d1; | |
99 | p2 -= d1; | |
100 | if (p1 & 256) | |
101 | p1 = ~(p1 >> 31); | |
102 | if (p2 & 256) | |
103 | p2 = ~(p2 >> 31); | |
104 | ||
105 | src[x - 1 * stride] = p1; | |
106 | src[x + 0 * stride] = p2; | |
107 | ||
108 | ad1 = FFABS(d1) >> 1; | |
109 | ||
110 | d2 = av_clip((p0 - p3) / 4, -ad1, ad1); | |
111 | ||
112 | src[x - 2 * stride] = p0 - d2; | |
113 | src[x + stride] = p3 + d2; | |
114 | } | |
115 | } | |
116 | ||
117 | av_cold void ff_h263dsp_init(H263DSPContext *ctx) | |
118 | { | |
119 | ctx->h263_h_loop_filter = h263_h_loop_filter_c; | |
120 | ctx->h263_v_loop_filter = h263_v_loop_filter_c; | |
121 | ||
122 | if (ARCH_X86) | |
123 | ff_h263dsp_init_x86(ctx); | |
124 | } |