Mercurial > libavcodec.hg
annotate rv40.c @ 10952:ea8f891d997d libavcodec
H264 DXVA2 implementation
It allows VLD H264 decoding using DXVA2 (GPU assisted decoding API under
VISTA and Windows 7).
It is implemented by using AVHWAccel API. It has been tested successfully
for some time in VLC using an nvidia card on Windows 7.
To compile it, you need to have the system header dxva2api.h (either from
microsoft or using http://downloads.videolan.org/pub/videolan/testing/contrib/dxva2api.h)
The generated libavcodec.dll does not depend directly on any new lib as
the necessary objects are given by the application using FFmpeg.
author | fenrir |
---|---|
date | Wed, 20 Jan 2010 18:54:51 +0000 |
parents | d0f2f4e4436c |
children | 8a4984c5cacc |
rev | line source |
---|---|
5983 | 1 /* |
2 * RV40 decoder | |
3 * Copyright (c) 2007 Konstantin Shishkov | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8693
diff
changeset
|
23 * @file libavcodec/rv40.c |
5983 | 24 * RV40 decoder |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 #include "dsputil.h" | |
29 #include "mpegvideo.h" | |
5995 | 30 #include "golomb.h" |
5983 | 31 |
32 #include "rv34.h" | |
33 #include "rv40vlc2.h" | |
34 #include "rv40data.h" | |
35 | |
36 static VLC aic_top_vlc; | |
37 static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; | |
38 static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; | |
39 | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
40 static const int16_t mode2_offs[] = { |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
41 0, 614, 1222, 1794, 2410, 3014, 3586, 4202, 4792, 5382, 5966, 6542, |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
42 7138, 7716, 8292, 8864, 9444, 10030, 10642, 11212, 11814 |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
43 }; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
44 |
5983 | 45 /** |
46 * Initialize all tables. | |
47 */ | |
8693
18737839ed27
Add missing void keyword to parameterless function declarations.
diego
parents:
8369
diff
changeset
|
48 static av_cold void rv40_init_tables(void) |
5983 | 49 { |
50 int i; | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
51 static VLC_TYPE aic_table[1 << AIC_TOP_BITS][2]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
52 static VLC_TYPE aic_mode1_table[AIC_MODE1_NUM << AIC_MODE1_BITS][2]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
53 static VLC_TYPE aic_mode2_table[11814][2]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
54 static VLC_TYPE ptype_table[NUM_PTYPE_VLCS << PTYPE_VLC_BITS][2]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
55 static VLC_TYPE btype_table[NUM_BTYPE_VLCS << BTYPE_VLC_BITS][2]; |
5983 | 56 |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
57 aic_top_vlc.table = aic_table; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
58 aic_top_vlc.table_allocated = 1 << AIC_TOP_BITS; |
5983 | 59 init_vlc(&aic_top_vlc, AIC_TOP_BITS, AIC_TOP_SIZE, |
60 rv40_aic_top_vlc_bits, 1, 1, | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
61 rv40_aic_top_vlc_codes, 1, 1, INIT_VLC_USE_NEW_STATIC); |
5983 | 62 for(i = 0; i < AIC_MODE1_NUM; i++){ |
63 // Every tenth VLC table is empty | |
64 if((i % 10) == 9) continue; | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
65 aic_mode1_vlc[i].table = &aic_mode1_table[i << AIC_MODE1_BITS]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
66 aic_mode1_vlc[i].table_allocated = 1 << AIC_MODE1_BITS; |
5983 | 67 init_vlc(&aic_mode1_vlc[i], AIC_MODE1_BITS, AIC_MODE1_SIZE, |
68 aic_mode1_vlc_bits[i], 1, 1, | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
69 aic_mode1_vlc_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); |
5983 | 70 } |
71 for(i = 0; i < AIC_MODE2_NUM; i++){ | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
72 aic_mode2_vlc[i].table = &aic_mode2_table[mode2_offs[i]]; |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
73 aic_mode2_vlc[i].table_allocated = mode2_offs[i + 1] - mode2_offs[i]; |
5983 | 74 init_vlc(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, |
75 aic_mode2_vlc_bits[i], 1, 1, | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
76 aic_mode2_vlc_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); |
5983 | 77 } |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
78 for(i = 0; i < NUM_PTYPE_VLCS; i++){ |
9550 | 79 ptype_vlc[i].table = &ptype_table[i << PTYPE_VLC_BITS]; |
80 ptype_vlc[i].table_allocated = 1 << PTYPE_VLC_BITS; | |
81 init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, | |
5983 | 82 ptype_vlc_bits[i], 1, 1, |
83 ptype_vlc_codes[i], 1, 1, | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
84 ptype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
85 } |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
86 for(i = 0; i < NUM_BTYPE_VLCS; i++){ |
9550 | 87 btype_vlc[i].table = &btype_table[i << BTYPE_VLC_BITS]; |
88 btype_vlc[i].table_allocated = 1 << BTYPE_VLC_BITS; | |
89 init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, | |
5983 | 90 btype_vlc_bits[i], 1, 1, |
91 btype_vlc_codes[i], 1, 1, | |
9518
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
92 btype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); |
b293cd788af3
Make rv40 decoder use new static VLC initialization method
kostya
parents:
9028
diff
changeset
|
93 } |
5983 | 94 } |
95 | |
96 /** | |
97 * Get stored dimension from bitstream. | |
98 * | |
99 * If the width/height is the standard one then it's coded as a 3-bit index. | |
100 * Otherwise it is coded as escaped 8-bit portions. | |
101 */ | |
102 static int get_dimension(GetBitContext *gb, const int *dim) | |
103 { | |
104 int t = get_bits(gb, 3); | |
105 int val = dim[t]; | |
106 if(val < 0) | |
107 val = dim[get_bits1(gb) - val]; | |
108 if(!val){ | |
109 do{ | |
110 t = get_bits(gb, 8); | |
111 val += t << 2; | |
112 }while(t == 0xFF); | |
113 } | |
114 return val; | |
115 } | |
116 | |
117 /** | |
118 * Get encoded picture size - usually this is called from rv40_parse_slice_header. | |
119 */ | |
120 static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) | |
121 { | |
122 *w = get_dimension(gb, rv40_standard_widths); | |
123 *h = get_dimension(gb, rv40_standard_heights); | |
124 } | |
125 | |
126 static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) | |
127 { | |
6714
05c3a4b419e9
Calculate motion vector information based on PTS provided in slice header
kostya
parents:
6712
diff
changeset
|
128 int mb_bits; |
5983 | 129 int w = r->s.width, h = r->s.height; |
130 int mb_size; | |
131 | |
132 memset(si, 0, sizeof(SliceInfo)); | |
133 if(get_bits1(gb)) | |
134 return -1; | |
135 si->type = get_bits(gb, 2); | |
136 if(si->type == 1) si->type = 0; | |
137 si->quant = get_bits(gb, 5); | |
138 if(get_bits(gb, 2)) | |
139 return -1; | |
140 si->vlc_set = get_bits(gb, 2); | |
141 skip_bits1(gb); | |
6714
05c3a4b419e9
Calculate motion vector information based on PTS provided in slice header
kostya
parents:
6712
diff
changeset
|
142 si->pts = get_bits(gb, 13); |
5983 | 143 if(!si->type || !get_bits1(gb)) |
144 rv40_parse_picture_size(gb, &w, &h); | |
5994 | 145 if(avcodec_check_dimensions(r->s.avctx, w, h) < 0) |
146 return -1; | |
5983 | 147 si->width = w; |
148 si->height = h; | |
149 mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); | |
150 mb_bits = ff_rv34_get_start_offset(gb, mb_size); | |
151 si->start = get_bits(gb, mb_bits); | |
152 | |
153 return 0; | |
154 } | |
155 | |
156 /** | |
157 * Decode 4x4 intra types array. | |
158 */ | |
5993 | 159 static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) |
5983 | 160 { |
161 MpegEncContext *s = &r->s; | |
162 int i, j, k, v; | |
163 int A, B, C; | |
164 int pattern; | |
5993 | 165 int8_t *ptr; |
5983 | 166 |
9903
305536ce781f
RV3/4 intra types array causes alignment issues (at least on ARM5), thus change
kostya
parents:
9550
diff
changeset
|
167 for(i = 0; i < 4; i++, dst += r->intra_types_stride){ |
5983 | 168 if(!i && s->first_slice_line){ |
169 pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); | |
170 dst[0] = (pattern >> 2) & 2; | |
171 dst[1] = (pattern >> 1) & 2; | |
172 dst[2] = pattern & 2; | |
173 dst[3] = (pattern << 1) & 2; | |
174 continue; | |
175 } | |
176 ptr = dst; | |
177 for(j = 0; j < 4; j++){ | |
178 /* Coefficients are read using VLC chosen by the prediction pattern | |
179 * The first one (used for retrieving a pair of coefficients) is | |
180 * constructed from the top, top right and left coefficients | |
181 * The second one (used for retrieving only one coefficient) is | |
182 * top + 10 * left. | |
183 */ | |
9903
305536ce781f
RV3/4 intra types array causes alignment issues (at least on ARM5), thus change
kostya
parents:
9550
diff
changeset
|
184 A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row |
305536ce781f
RV3/4 intra types array causes alignment issues (at least on ARM5), thus change
kostya
parents:
9550
diff
changeset
|
185 B = ptr[-r->intra_types_stride]; |
5983 | 186 C = ptr[-1]; |
187 pattern = A + (B << 4) + (C << 8); | |
188 for(k = 0; k < MODE2_PATTERNS_NUM; k++) | |
189 if(pattern == rv40_aic_table_index[k]) | |
190 break; | |
191 if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients | |
192 v = get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2); | |
193 *ptr++ = v/9; | |
194 *ptr++ = v%9; | |
195 j++; | |
196 }else{ | |
197 if(B != -1 && C != -1) | |
198 v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); | |
199 else{ // tricky decoding | |
200 v = 0; | |
201 switch(C){ | |
202 case -1: // code 0 -> 1, 1 -> 0 | |
203 if(B < 2) | |
204 v = get_bits1(gb) ^ 1; | |
205 break; | |
206 case 0: | |
207 case 2: // code 0 -> 2, 1 -> 0 | |
208 v = (get_bits1(gb) ^ 1) << 1; | |
209 break; | |
210 } | |
211 } | |
212 *ptr++ = v; | |
213 } | |
214 } | |
215 } | |
216 return 0; | |
217 } | |
218 | |
219 /** | |
220 * Decode macroblock information. | |
221 */ | |
222 static int rv40_decode_mb_info(RV34DecContext *r) | |
223 { | |
224 MpegEncContext *s = &r->s; | |
225 GetBitContext *gb = &s->gb; | |
226 int q, i; | |
227 int prev_type = 0; | |
228 int mb_pos = s->mb_x + s->mb_y * s->mb_stride; | |
229 int blocks[RV34_MB_TYPES] = {0}; | |
230 int count = 0; | |
231 | |
232 if(!r->s.mb_skip_run) | |
5995 | 233 r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; |
5983 | 234 |
235 if(--r->s.mb_skip_run) | |
236 return RV34_MB_SKIP; | |
237 | |
10117
d0f2f4e4436c
Adjust r->avail_cache[] indexes to avoid alignment issues when zeroing block
kostya
parents:
9903
diff
changeset
|
238 if(r->avail_cache[6-1]) |
5983 | 239 blocks[r->mb_type[mb_pos - 1]]++; |
10117
d0f2f4e4436c
Adjust r->avail_cache[] indexes to avoid alignment issues when zeroing block
kostya
parents:
9903
diff
changeset
|
240 if(r->avail_cache[6-4]){ |
5983 | 241 blocks[r->mb_type[mb_pos - s->mb_stride]]++; |
10117
d0f2f4e4436c
Adjust r->avail_cache[] indexes to avoid alignment issues when zeroing block
kostya
parents:
9903
diff
changeset
|
242 if(r->avail_cache[6-2]) |
5983 | 243 blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; |
10117
d0f2f4e4436c
Adjust r->avail_cache[] indexes to avoid alignment issues when zeroing block
kostya
parents:
9903
diff
changeset
|
244 if(r->avail_cache[6-5]) |
5983 | 245 blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; |
246 } | |
247 | |
248 for(i = 0; i < RV34_MB_TYPES; i++){ | |
249 if(blocks[i] > count){ | |
250 count = blocks[i]; | |
251 prev_type = i; | |
252 } | |
253 } | |
6481 | 254 if(s->pict_type == FF_P_TYPE){ |
5983 | 255 prev_type = block_num_to_ptype_vlc_num[prev_type]; |
256 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); | |
257 if(q < PBTYPE_ESCAPE) | |
258 return q; | |
259 q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); | |
260 av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); | |
261 }else{ | |
262 prev_type = block_num_to_btype_vlc_num[prev_type]; | |
263 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); | |
264 if(q < PBTYPE_ESCAPE) | |
265 return q; | |
266 q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); | |
267 av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); | |
268 } | |
269 return 0; | |
270 } | |
271 | |
8146
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
272 #define CLIP_SYMM(a, b) av_clip(a, -(b), b) |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
273 /** |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
274 * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1 |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
275 */ |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
276 static inline void rv40_weak_loop_filter(uint8_t *src, const int step, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
277 const int filter_p1, const int filter_q1, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
278 const int alpha, const int beta, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
279 const int lim_p0q0, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
280 const int lim_q1, const int lim_p1, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
281 const int diff_p1p0, const int diff_q1q0, |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
282 const int diff_p1p2, const int diff_q1q2) |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
283 { |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
284 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
285 int t, u, diff; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
286 |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
287 t = src[0*step] - src[-1*step]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
288 if(!t) |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
289 return; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
290 u = (alpha * FFABS(t)) >> 7; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
291 if(u > 3 - (filter_p1 && filter_q1)) |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
292 return; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
293 |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
294 t <<= 2; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
295 if(filter_p1 && filter_q1) |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
296 t += src[-2*step] - src[1*step]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
297 diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0); |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
298 src[-1*step] = cm[src[-1*step] + diff]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
299 src[ 0*step] = cm[src[ 0*step] - diff]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
300 if(FFABS(diff_p1p2) <= beta && filter_p1){ |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
301 t = (diff_p1p0 + diff_p1p2 - diff) >> 1; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
302 src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
303 } |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
304 if(FFABS(diff_q1q2) <= beta && filter_q1){ |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
305 t = (diff_q1q0 + diff_q1q2 + diff) >> 1; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
306 src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)]; |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
307 } |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
308 } |
4a92ea42a8bc
Weak deblock filter function for future RV40 loop filter
kostya
parents:
7040
diff
changeset
|
309 |
8198
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
310 static inline void rv40_adaptive_loop_filter(uint8_t *src, const int step, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
311 const int stride, const int dmode, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
312 const int lim_q1, const int lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
313 const int alpha, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
314 const int beta, const int beta2, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
315 const int chroma, const int edge) |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
316 { |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
317 int diff_p1p0[4], diff_q1q0[4], diff_p1p2[4], diff_q1q2[4]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
318 int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
319 uint8_t *ptr; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
320 int flag_strong0 = 1, flag_strong1 = 1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
321 int filter_p1, filter_q1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
322 int i; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
323 int lims; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
324 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
325 for(i = 0, ptr = src; i < 4; i++, ptr += stride){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
326 diff_p1p0[i] = ptr[-2*step] - ptr[-1*step]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
327 diff_q1q0[i] = ptr[ 1*step] - ptr[ 0*step]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
328 sum_p1p0 += diff_p1p0[i]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
329 sum_q1q0 += diff_q1q0[i]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
330 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
331 filter_p1 = FFABS(sum_p1p0) < (beta<<2); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
332 filter_q1 = FFABS(sum_q1q0) < (beta<<2); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
333 if(!filter_p1 && !filter_q1) |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
334 return; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
335 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
336 for(i = 0, ptr = src; i < 4; i++, ptr += stride){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
337 diff_p1p2[i] = ptr[-2*step] - ptr[-3*step]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
338 diff_q1q2[i] = ptr[ 1*step] - ptr[ 2*step]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
339 sum_p1p2 += diff_p1p2[i]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
340 sum_q1q2 += diff_q1q2[i]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
341 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
342 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
343 if(edge){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
344 flag_strong0 = filter_p1 && (FFABS(sum_p1p2) < beta2); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
345 flag_strong1 = filter_q1 && (FFABS(sum_q1q2) < beta2); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
346 }else{ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
347 flag_strong0 = flag_strong1 = 0; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
348 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
349 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
350 lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
351 if(flag_strong0 && flag_strong1){ /* strong filtering */ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
352 for(i = 0; i < 4; i++, src += stride){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
353 int sflag, p0, q0, p1, q1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
354 int t = src[0*step] - src[-1*step]; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
355 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
356 if(!t) continue; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
357 sflag = (alpha * FFABS(t)) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
358 if(sflag > 1) continue; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
359 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
360 p0 = (25*src[-3*step] + 26*src[-2*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
361 + 26*src[-1*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
362 + 26*src[ 0*step] + 25*src[ 1*step] + rv40_dither_l[dmode + i]) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
363 q0 = (25*src[-2*step] + 26*src[-1*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
364 + 26*src[ 0*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
365 + 26*src[ 1*step] + 25*src[ 2*step] + rv40_dither_r[dmode + i]) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
366 if(sflag){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
367 p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
368 q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
369 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
370 p1 = (25*src[-4*step] + 26*src[-3*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
371 + 26*src[-2*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
372 + 26*p0 + 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
373 q1 = (25*src[-1*step] + 26*q0 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
374 + 26*src[ 1*step] |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
375 + 26*src[ 2*step] + 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
376 if(sflag){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
377 p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
378 q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
379 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
380 src[-2*step] = p1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
381 src[-1*step] = p0; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
382 src[ 0*step] = q0; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
383 src[ 1*step] = q1; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
384 if(!chroma){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
385 src[-3*step] = (25*src[-1*step] + 26*src[-2*step] + 51*src[-3*step] + 26*src[-4*step] + 64) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
386 src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] + 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7; |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
387 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
388 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
389 }else if(filter_p1 && filter_q1){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
390 for(i = 0; i < 4; i++, src += stride) |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
391 rv40_weak_loop_filter(src, step, 1, 1, alpha, beta, lims, lim_q1, lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
392 diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
393 }else{ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
394 for(i = 0; i < 4; i++, src += stride) |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
395 rv40_weak_loop_filter(src, step, filter_p1, filter_q1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
396 alpha, beta, lims>>1, lim_q1>>1, lim_p1>>1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
397 diff_p1p0[i], diff_q1q0[i], diff_p1p2[i], diff_q1q2[i]); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
398 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
399 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
400 |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
401 static void rv40_v_loop_filter(uint8_t *src, int stride, int dmode, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
402 int lim_q1, int lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
403 int alpha, int beta, int beta2, int chroma, int edge){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
404 rv40_adaptive_loop_filter(src, 1, stride, dmode, lim_q1, lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
405 alpha, beta, beta2, chroma, edge); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
406 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
407 static void rv40_h_loop_filter(uint8_t *src, int stride, int dmode, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
408 int lim_q1, int lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
409 int alpha, int beta, int beta2, int chroma, int edge){ |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
410 rv40_adaptive_loop_filter(src, stride, 1, dmode, lim_q1, lim_p1, |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
411 alpha, beta, beta2, chroma, edge); |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
412 } |
de344498875e
Strong filtering function for future RV40 loop filter
kostya
parents:
8146
diff
changeset
|
413 |
8225 | 414 enum RV40BlockPos{ |
415 POS_CUR, | |
416 POS_TOP, | |
417 POS_LEFT, | |
418 POS_BOTTOM, | |
419 }; | |
420 | |
421 #define MASK_CUR 0x0001 | |
422 #define MASK_RIGHT 0x0008 | |
423 #define MASK_BOTTOM 0x0010 | |
424 #define MASK_TOP 0x1000 | |
425 #define MASK_Y_TOP_ROW 0x000F | |
426 #define MASK_Y_LAST_ROW 0xF000 | |
427 #define MASK_Y_LEFT_COL 0x1111 | |
428 #define MASK_Y_RIGHT_COL 0x8888 | |
429 #define MASK_C_TOP_ROW 0x0003 | |
430 #define MASK_C_LAST_ROW 0x000C | |
431 #define MASK_C_LEFT_COL 0x0005 | |
432 #define MASK_C_RIGHT_COL 0x000A | |
433 | |
434 static const int neighbour_offs_x[4] = { 0, 0, -1, 0 }; | |
435 static const int neighbour_offs_y[4] = { 0, -1, 0, 1 }; | |
436 | |
437 /** | |
438 * RV40 loop filtering function | |
439 */ | |
440 static void rv40_loop_filter(RV34DecContext *r, int row) | |
441 { | |
442 MpegEncContext *s = &r->s; | |
443 int mb_pos, mb_x; | |
444 int i, j, k; | |
445 uint8_t *Y, *C; | |
446 int alpha, beta, betaY, betaC; | |
447 int q; | |
448 int mbtype[4]; ///< current macroblock and its neighbours types | |
449 /** | |
450 * flags indicating that macroblock can be filtered with strong filter | |
451 * it is set only for intra coded MB and MB with DCs coded separately | |
452 */ | |
453 int mb_strong[4]; | |
454 int clip[4]; ///< MB filter clipping value calculated from filtering strength | |
455 /** | |
456 * coded block patterns for luma part of current macroblock and its neighbours | |
457 * Format: | |
458 * LSB corresponds to the top left block, | |
459 * each nibble represents one row of subblocks. | |
460 */ | |
461 int cbp[4]; | |
462 /** | |
463 * coded block patterns for chroma part of current macroblock and its neighbours | |
464 * Format is the same as for luma with two subblocks in a row. | |
465 */ | |
466 int uvcbp[4][2]; | |
467 /** | |
468 * This mask represents the pattern of luma subblocks that should be filtered | |
469 * in addition to the coded ones because because they lie at the edge of | |
470 * 8x8 block with different enough motion vectors | |
471 */ | |
472 int mvmasks[4]; | |
473 | |
474 mb_pos = row * s->mb_stride; | |
475 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
476 int mbtype = s->current_picture_ptr->mb_type[mb_pos]; | |
477 if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) | |
8369
45c3780b1a96
Merge deblocking pattern with CBP for RV30/40 loop filtering
kostya
parents:
8225
diff
changeset
|
478 r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF; |
8225 | 479 if(IS_INTRA(mbtype)) |
480 r->cbp_chroma[mb_pos] = 0xFF; | |
481 } | |
482 mb_pos = row * s->mb_stride; | |
483 for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ | |
484 int y_h_deblock, y_v_deblock; | |
485 int c_v_deblock[2], c_h_deblock[2]; | |
486 int clip_left; | |
487 int avail[4]; | |
488 int y_to_deblock, c_to_deblock[2]; | |
489 | |
490 q = s->current_picture_ptr->qscale_table[mb_pos]; | |
491 alpha = rv40_alpha_tab[q]; | |
492 beta = rv40_beta_tab [q]; | |
493 betaY = betaC = beta * 3; | |
494 if(s->width * s->height <= 176*144) | |
495 betaY += beta; | |
496 | |
497 avail[0] = 1; | |
498 avail[1] = row; | |
499 avail[2] = mb_x; | |
500 avail[3] = row < s->mb_height - 1; | |
501 for(i = 0; i < 4; i++){ | |
502 if(avail[i]){ | |
503 int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride; | |
504 mvmasks[i] = r->deblock_coefs[pos]; | |
505 mbtype [i] = s->current_picture_ptr->mb_type[pos]; | |
506 cbp [i] = r->cbp_luma[pos]; | |
507 uvcbp[i][0] = r->cbp_chroma[pos] & 0xF; | |
508 uvcbp[i][1] = r->cbp_chroma[pos] >> 4; | |
509 }else{ | |
510 mvmasks[i] = 0; | |
511 mbtype [i] = mbtype[0]; | |
512 cbp [i] = 0; | |
513 uvcbp[i][0] = uvcbp[i][1] = 0; | |
514 } | |
515 mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]); | |
516 clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q]; | |
517 } | |
8369
45c3780b1a96
Merge deblocking pattern with CBP for RV30/40 loop filtering
kostya
parents:
8225
diff
changeset
|
518 y_to_deblock = mvmasks[POS_CUR] |
8225 | 519 | (mvmasks[POS_BOTTOM] << 16); |
520 /* This pattern contains bits signalling that horizontal edges of | |
521 * the current block can be filtered. | |
522 * That happens when either of adjacent subblocks is coded or lies on | |
523 * the edge of 8x8 blocks with motion vectors differing by more than | |
524 * 3/4 pel in any component (any edge orientation for some reason). | |
525 */ | |
526 y_h_deblock = y_to_deblock | |
527 | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW) | |
528 | ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12); | |
529 /* This pattern contains bits signalling that vertical edges of | |
530 * the current block can be filtered. | |
531 * That happens when either of adjacent subblocks is coded or lies on | |
532 * the edge of 8x8 blocks with motion vectors differing by more than | |
533 * 3/4 pel in any component (any edge orientation for some reason). | |
534 */ | |
535 y_v_deblock = y_to_deblock | |
536 | ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL) | |
537 | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3); | |
538 if(!mb_x) | |
539 y_v_deblock &= ~MASK_Y_LEFT_COL; | |
540 if(!row) | |
541 y_h_deblock &= ~MASK_Y_TOP_ROW; | |
542 if(row == s->mb_height - 1 || (mb_strong[POS_CUR] || mb_strong[POS_BOTTOM])) | |
543 y_h_deblock &= ~(MASK_Y_TOP_ROW << 16); | |
544 /* Calculating chroma patterns is similar and easier since there is | |
545 * no motion vector pattern for them. | |
546 */ | |
547 for(i = 0; i < 2; i++){ | |
548 c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i]; | |
549 c_v_deblock[i] = c_to_deblock[i] | |
550 | ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL) | |
551 | ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1); | |
552 c_h_deblock[i] = c_to_deblock[i] | |
553 | ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2) | |
554 | (uvcbp[POS_CUR][i] << 2); | |
555 if(!mb_x) | |
556 c_v_deblock[i] &= ~MASK_C_LEFT_COL; | |
557 if(!row) | |
558 c_h_deblock[i] &= ~MASK_C_TOP_ROW; | |
559 if(row == s->mb_height - 1 || mb_strong[POS_CUR] || mb_strong[POS_BOTTOM]) | |
560 c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4); | |
561 } | |
562 | |
563 for(j = 0; j < 16; j += 4){ | |
564 Y = s->current_picture_ptr->data[0] + mb_x*16 + (row*16 + j) * s->linesize; | |
565 for(i = 0; i < 4; i++, Y += 4){ | |
566 int ij = i + j; | |
567 int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0; | |
568 int dither = j ? ij : i*4; | |
569 | |
570 // if bottom block is coded then we can filter its top edge | |
571 // (or bottom edge of this block, which is the same) | |
572 if(y_h_deblock & (MASK_BOTTOM << ij)){ | |
573 rv40_h_loop_filter(Y+4*s->linesize, s->linesize, dither, | |
574 y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0, | |
575 clip_cur, | |
576 alpha, beta, betaY, 0, 0); | |
577 } | |
578 // filter left block edge in ordinary mode (with low filtering strength) | |
579 if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ | |
580 if(!i) | |
8369
45c3780b1a96
Merge deblocking pattern with CBP for RV30/40 loop filtering
kostya
parents:
8225
diff
changeset
|
581 clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; |
8225 | 582 else |
583 clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; | |
584 rv40_v_loop_filter(Y, s->linesize, dither, | |
585 clip_cur, | |
586 clip_left, | |
587 alpha, beta, betaY, 0, 0); | |
588 } | |
589 // filter top edge of the current macroblock when filtering strength is high | |
590 if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ | |
591 rv40_h_loop_filter(Y, s->linesize, dither, | |
592 clip_cur, | |
8369
45c3780b1a96
Merge deblocking pattern with CBP for RV30/40 loop filtering
kostya
parents:
8225
diff
changeset
|
593 mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0, |
8225 | 594 alpha, beta, betaY, 0, 1); |
595 } | |
596 // filter left block edge in edge mode (with high filtering strength) | |
597 if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ | |
8369
45c3780b1a96
Merge deblocking pattern with CBP for RV30/40 loop filtering
kostya
parents:
8225
diff
changeset
|
598 clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; |
8225 | 599 rv40_v_loop_filter(Y, s->linesize, dither, |
600 clip_cur, | |
601 clip_left, | |
602 alpha, beta, betaY, 0, 1); | |
603 } | |
604 } | |
605 } | |
606 for(k = 0; k < 2; k++){ | |
607 for(j = 0; j < 2; j++){ | |
608 C = s->current_picture_ptr->data[k+1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize; | |
609 for(i = 0; i < 2; i++, C += 4){ | |
610 int ij = i + j*2; | |
611 int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0; | |
612 if(c_h_deblock[k] & (MASK_CUR << (ij+2))){ | |
613 int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0; | |
614 rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8, | |
615 clip_bot, | |
616 clip_cur, | |
617 alpha, beta, betaC, 1, 0); | |
618 } | |
619 if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){ | |
620 if(!i) | |
621 clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; | |
622 else | |
623 clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; | |
624 rv40_v_loop_filter(C, s->uvlinesize, j*8, | |
625 clip_cur, | |
626 clip_left, | |
627 alpha, beta, betaC, 1, 0); | |
628 } | |
629 if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){ | |
630 int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0; | |
631 rv40_h_loop_filter(C, s->uvlinesize, i*8, | |
632 clip_cur, | |
633 clip_top, | |
634 alpha, beta, betaC, 1, 1); | |
635 } | |
636 if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){ | |
637 clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; | |
638 rv40_v_loop_filter(C, s->uvlinesize, j*8, | |
639 clip_cur, | |
640 clip_left, | |
641 alpha, beta, betaC, 1, 1); | |
642 } | |
643 } | |
644 } | |
645 } | |
646 } | |
647 } | |
648 | |
5983 | 649 /** |
650 * Initialize decoder. | |
651 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6481
diff
changeset
|
652 static av_cold int rv40_decode_init(AVCodecContext *avctx) |
5983 | 653 { |
654 RV34DecContext *r = avctx->priv_data; | |
655 | |
656 r->rv30 = 0; | |
657 ff_rv34_decode_init(avctx); | |
658 if(!aic_top_vlc.bits) | |
659 rv40_init_tables(); | |
660 r->parse_slice_header = rv40_parse_slice_header; | |
661 r->decode_intra_types = rv40_decode_intra_types; | |
662 r->decode_mb_info = rv40_decode_mb_info; | |
8225 | 663 r->loop_filter = rv40_loop_filter; |
5983 | 664 r->luma_dc_quant_i = rv40_luma_dc_quant[0]; |
665 r->luma_dc_quant_p = rv40_luma_dc_quant[1]; | |
666 return 0; | |
667 } | |
668 | |
669 AVCodec rv40_decoder = { | |
670 "rv40", | |
671 CODEC_TYPE_VIDEO, | |
672 CODEC_ID_RV40, | |
673 sizeof(RV34DecContext), | |
674 rv40_decode_init, | |
675 NULL, | |
676 ff_rv34_decode_end, | |
677 ff_rv34_decode_frame, | |
5992 | 678 CODEC_CAP_DR1 | CODEC_CAP_DELAY, |
8753 | 679 .flush = ff_mpeg_flush, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6714
diff
changeset
|
680 .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), |
9028 | 681 .pix_fmts= ff_pixfmt_list_420, |
5983 | 682 }; |