GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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 |
/** |
||
23 |
* @file |
||
24 |
* RV40 decoder |
||
25 |
*/ |
||
26 |
|||
27 |
#include "config.h" |
||
28 |
|||
29 |
#include "libavutil/imgutils.h" |
||
30 |
|||
31 |
#include "avcodec.h" |
||
32 |
#include "mpegutils.h" |
||
33 |
#include "mpegvideo.h" |
||
34 |
#include "golomb.h" |
||
35 |
|||
36 |
#include "rv34.h" |
||
37 |
#include "rv40vlc2.h" |
||
38 |
#include "rv40data.h" |
||
39 |
|||
40 |
static VLC aic_top_vlc; |
||
41 |
static VLC aic_mode1_vlc[AIC_MODE1_NUM], aic_mode2_vlc[AIC_MODE2_NUM]; |
||
42 |
static VLC ptype_vlc[NUM_PTYPE_VLCS], btype_vlc[NUM_BTYPE_VLCS]; |
||
43 |
|||
44 |
190 |
static av_cold void rv40_init_table(VLC *vlc, unsigned *offset, int nb_bits, |
|
45 |
int nb_codes, const uint8_t (*tab)[2]) |
||
46 |
{ |
||
47 |
static VLC_TYPE vlc_buf[11776][2]; |
||
48 |
|||
49 |
190 |
vlc->table = &vlc_buf[*offset]; |
|
50 |
190 |
vlc->table_allocated = 1 << nb_bits; |
|
51 |
190 |
*offset += 1 << nb_bits; |
|
52 |
|||
53 |
190 |
ff_init_vlc_from_lengths(vlc, nb_bits, nb_codes, |
|
54 |
190 |
&tab[0][1], 2, &tab[0][0], 2, 1, |
|
55 |
0, INIT_VLC_USE_NEW_STATIC, NULL); |
||
56 |
190 |
} |
|
57 |
|||
58 |
/** |
||
59 |
* Initialize all tables. |
||
60 |
*/ |
||
61 |
2 |
static av_cold void rv40_init_tables(void) |
|
62 |
{ |
||
63 |
2 |
int i, offset = 0; |
|
64 |
static VLC_TYPE aic_mode2_table[11814][2]; |
||
65 |
|||
66 |
2 |
rv40_init_table(&aic_top_vlc, &offset, AIC_TOP_BITS, AIC_TOP_SIZE, |
|
67 |
rv40_aic_top_vlc_tab); |
||
68 |
✓✓ | 182 |
for(i = 0; i < AIC_MODE1_NUM; i++){ |
69 |
// Every tenth VLC table is empty |
||
70 |
✓✓ | 180 |
if((i % 10) == 9) continue; |
71 |
162 |
rv40_init_table(&aic_mode1_vlc[i], &offset, AIC_MODE1_BITS, |
|
72 |
162 |
AIC_MODE1_SIZE, aic_mode1_vlc_tabs[i]); |
|
73 |
} |
||
74 |
✓✓ | 42 |
for (unsigned i = 0, offset = 0; i < AIC_MODE2_NUM; i++){ |
75 |
uint16_t syms[AIC_MODE2_SIZE]; |
||
76 |
|||
77 |
✓✓ | 3280 |
for (int j = 0; j < AIC_MODE2_SIZE; j++) { |
78 |
3240 |
int first = aic_mode2_vlc_syms[i][j] >> 4; |
|
79 |
3240 |
int second = aic_mode2_vlc_syms[i][j] & 0xF; |
|
80 |
if (HAVE_BIGENDIAN) |
||
81 |
syms[j] = (first << 8) | second; |
||
82 |
else |
||
83 |
3240 |
syms[j] = first | (second << 8); |
|
84 |
} |
||
85 |
40 |
aic_mode2_vlc[i].table = &aic_mode2_table[offset]; |
|
86 |
40 |
aic_mode2_vlc[i].table_allocated = FF_ARRAY_ELEMS(aic_mode2_table) - offset; |
|
87 |
40 |
ff_init_vlc_from_lengths(&aic_mode2_vlc[i], AIC_MODE2_BITS, AIC_MODE2_SIZE, |
|
88 |
40 |
aic_mode2_vlc_bits[i], 1, |
|
89 |
syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL); |
||
90 |
40 |
offset += aic_mode2_vlc[i].table_size; |
|
91 |
} |
||
92 |
✓✓ | 16 |
for(i = 0; i < NUM_PTYPE_VLCS; i++){ |
93 |
14 |
rv40_init_table(&ptype_vlc[i], &offset, PTYPE_VLC_BITS, PTYPE_VLC_SIZE, |
|
94 |
14 |
ptype_vlc_tabs[i]); |
|
95 |
} |
||
96 |
✓✓ | 14 |
for(i = 0; i < NUM_BTYPE_VLCS; i++){ |
97 |
12 |
rv40_init_table(&btype_vlc[i], &offset, BTYPE_VLC_BITS, BTYPE_VLC_SIZE, |
|
98 |
12 |
btype_vlc_tabs[i]); |
|
99 |
} |
||
100 |
2 |
} |
|
101 |
|||
102 |
/** |
||
103 |
* Get stored dimension from bitstream. |
||
104 |
* |
||
105 |
* If the width/height is the standard one then it's coded as a 3-bit index. |
||
106 |
* Otherwise it is coded as escaped 8-bit portions. |
||
107 |
*/ |
||
108 |
112 |
static int get_dimension(GetBitContext *gb, const int *dim) |
|
109 |
{ |
||
110 |
112 |
int t = get_bits(gb, 3); |
|
111 |
112 |
int val = dim[t]; |
|
112 |
✓✓ | 112 |
if(val < 0) |
113 |
56 |
val = dim[get_bits1(gb) - val]; |
|
114 |
✓✗ | 112 |
if(!val){ |
115 |
do{ |
||
116 |
✗✓ | 112 |
if (get_bits_left(gb) < 8) |
117 |
return AVERROR_INVALIDDATA; |
||
118 |
112 |
t = get_bits(gb, 8); |
|
119 |
112 |
val += t << 2; |
|
120 |
✗✓ | 112 |
}while(t == 0xFF); |
121 |
} |
||
122 |
112 |
return val; |
|
123 |
} |
||
124 |
|||
125 |
/** |
||
126 |
* Get encoded picture size - usually this is called from rv40_parse_slice_header. |
||
127 |
*/ |
||
128 |
56 |
static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h) |
|
129 |
{ |
||
130 |
56 |
*w = get_dimension(gb, rv40_standard_widths); |
|
131 |
56 |
*h = get_dimension(gb, rv40_standard_heights); |
|
132 |
56 |
} |
|
133 |
|||
134 |
2064 |
static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si) |
|
135 |
{ |
||
136 |
int mb_bits; |
||
137 |
2064 |
int w = r->s.width, h = r->s.height; |
|
138 |
int mb_size; |
||
139 |
int ret; |
||
140 |
|||
141 |
2064 |
memset(si, 0, sizeof(SliceInfo)); |
|
142 |
✗✓ | 2064 |
if(get_bits1(gb)) |
143 |
return AVERROR_INVALIDDATA; |
||
144 |
2064 |
si->type = get_bits(gb, 2); |
|
145 |
✓✓ | 2064 |
if(si->type == 1) si->type = 0; |
146 |
2064 |
si->quant = get_bits(gb, 5); |
|
147 |
✗✓ | 2064 |
if(get_bits(gb, 2)) |
148 |
return AVERROR_INVALIDDATA; |
||
149 |
2064 |
si->vlc_set = get_bits(gb, 2); |
|
150 |
2064 |
skip_bits1(gb); |
|
151 |
2064 |
si->pts = get_bits(gb, 13); |
|
152 |
✓✓✓✓ |
2064 |
if(!si->type || !get_bits1(gb)) |
153 |
56 |
rv40_parse_picture_size(gb, &w, &h); |
|
154 |
✗✓ | 2064 |
if ((ret = av_image_check_size(w, h, 0, r->s.avctx)) < 0) |
155 |
return ret; |
||
156 |
2064 |
si->width = w; |
|
157 |
2064 |
si->height = h; |
|
158 |
2064 |
mb_size = ((w + 15) >> 4) * ((h + 15) >> 4); |
|
159 |
2064 |
mb_bits = ff_rv34_get_start_offset(gb, mb_size); |
|
160 |
2064 |
si->start = get_bits(gb, mb_bits); |
|
161 |
|||
162 |
2064 |
return 0; |
|
163 |
} |
||
164 |
|||
165 |
/** |
||
166 |
* Decode 4x4 intra types array. |
||
167 |
*/ |
||
168 |
12372 |
static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst) |
|
169 |
{ |
||
170 |
12372 |
MpegEncContext *s = &r->s; |
|
171 |
int i, j, k, v; |
||
172 |
int A, B, C; |
||
173 |
int pattern; |
||
174 |
int8_t *ptr; |
||
175 |
|||
176 |
✓✓ | 61860 |
for(i = 0; i < 4; i++, dst += r->intra_types_stride){ |
177 |
✓✓✓✓ |
49488 |
if(!i && s->first_slice_line){ |
178 |
4856 |
pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1); |
|
179 |
4856 |
dst[0] = (pattern >> 2) & 2; |
|
180 |
4856 |
dst[1] = (pattern >> 1) & 2; |
|
181 |
4856 |
dst[2] = pattern & 2; |
|
182 |
4856 |
dst[3] = (pattern << 1) & 2; |
|
183 |
4856 |
continue; |
|
184 |
} |
||
185 |
44632 |
ptr = dst; |
|
186 |
✓✓ | 190656 |
for(j = 0; j < 4; j++){ |
187 |
/* Coefficients are read using VLC chosen by the prediction pattern |
||
188 |
* The first one (used for retrieving a pair of coefficients) is |
||
189 |
* constructed from the top, top right and left coefficients |
||
190 |
* The second one (used for retrieving only one coefficient) is |
||
191 |
* top + 10 * left. |
||
192 |
*/ |
||
193 |
146024 |
A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row |
|
194 |
146024 |
B = ptr[-r->intra_types_stride]; |
|
195 |
146024 |
C = ptr[-1]; |
|
196 |
146024 |
pattern = A + B * (1 << 4) + C * (1 << 8); |
|
197 |
✓✓ | 2593089 |
for(k = 0; k < MODE2_PATTERNS_NUM; k++) |
198 |
✓✓ | 2480499 |
if(pattern == rv40_aic_table_index[k]) |
199 |
33434 |
break; |
|
200 |
✓✓✓✓ |
146024 |
if(j < 3 && k < MODE2_PATTERNS_NUM){ //pattern is found, decoding 2 coefficients |
201 |
32504 |
AV_WN16(ptr, get_vlc2(gb, aic_mode2_vlc[k].table, AIC_MODE2_BITS, 2)); |
|
202 |
32504 |
ptr += 2; |
|
203 |
32504 |
j++; |
|
204 |
}else{ |
||
205 |
✓✗✓✓ |
113520 |
if(B != -1 && C != -1) |
206 |
111222 |
v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1); |
|
207 |
else{ // tricky decoding |
||
208 |
2298 |
v = 0; |
|
209 |
✓✗✗ | 2298 |
switch(C){ |
210 |
2298 |
case -1: // code 0 -> 1, 1 -> 0 |
|
211 |
✓✗ | 2298 |
if(B < 2) |
212 |
2298 |
v = get_bits1(gb) ^ 1; |
|
213 |
2298 |
break; |
|
214 |
case 0: |
||
215 |
case 2: // code 0 -> 2, 1 -> 0 |
||
216 |
v = (get_bits1(gb) ^ 1) << 1; |
||
217 |
break; |
||
218 |
} |
||
219 |
113520 |
} |
|
220 |
113520 |
*ptr++ = v; |
|
221 |
} |
||
222 |
} |
||
223 |
} |
||
224 |
12372 |
return 0; |
|
225 |
} |
||
226 |
|||
227 |
/** |
||
228 |
* Decode macroblock information. |
||
229 |
*/ |
||
230 |
216000 |
static int rv40_decode_mb_info(RV34DecContext *r) |
|
231 |
{ |
||
232 |
216000 |
MpegEncContext *s = &r->s; |
|
233 |
216000 |
GetBitContext *gb = &s->gb; |
|
234 |
int q, i; |
||
235 |
216000 |
int prev_type = 0; |
|
236 |
216000 |
int mb_pos = s->mb_x + s->mb_y * s->mb_stride; |
|
237 |
|||
238 |
✓✓ | 216000 |
if(!r->s.mb_skip_run) { |
239 |
80045 |
r->s.mb_skip_run = get_interleaved_ue_golomb(gb) + 1; |
|
240 |
✗✓ | 80045 |
if(r->s.mb_skip_run > (unsigned)s->mb_num) |
241 |
return -1; |
||
242 |
} |
||
243 |
|||
244 |
✓✓ | 216000 |
if(--r->s.mb_skip_run) |
245 |
136461 |
return RV34_MB_SKIP; |
|
246 |
|||
247 |
✓✓ | 79539 |
if(r->avail_cache[6-4]){ |
248 |
60557 |
int blocks[RV34_MB_TYPES] = {0}; |
|
249 |
60557 |
int count = 0; |
|
250 |
✓✓ | 60557 |
if(r->avail_cache[6-1]) |
251 |
58685 |
blocks[r->mb_type[mb_pos - 1]]++; |
|
252 |
60557 |
blocks[r->mb_type[mb_pos - s->mb_stride]]++; |
|
253 |
✓✓ | 60557 |
if(r->avail_cache[6-2]) |
254 |
59440 |
blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; |
|
255 |
✓✓ | 60557 |
if(r->avail_cache[6-5]) |
256 |
58378 |
blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; |
|
257 |
✓✓ | 360282 |
for(i = 0; i < RV34_MB_TYPES; i++){ |
258 |
✓✓ | 357222 |
if(blocks[i] > count){ |
259 |
80201 |
count = blocks[i]; |
|
260 |
80201 |
prev_type = i; |
|
261 |
✓✓ | 80201 |
if(count>1) |
262 |
57497 |
break; |
|
263 |
} |
||
264 |
} |
||
265 |
✓✓ | 18982 |
} else if (r->avail_cache[6-1]) |
266 |
18051 |
prev_type = r->mb_type[mb_pos - 1]; |
|
267 |
|||
268 |
✓✓ | 79539 |
if(s->pict_type == AV_PICTURE_TYPE_P){ |
269 |
25793 |
prev_type = block_num_to_ptype_vlc_num[prev_type]; |
|
270 |
25793 |
q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); |
|
271 |
✓✗ | 25793 |
if(q < PBTYPE_ESCAPE) |
272 |
25793 |
return q; |
|
273 |
q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); |
||
274 |
av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); |
||
275 |
}else{ |
||
276 |
53746 |
prev_type = block_num_to_btype_vlc_num[prev_type]; |
|
277 |
53746 |
q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); |
|
278 |
✓✗ | 53746 |
if(q < PBTYPE_ESCAPE) |
279 |
53746 |
return q; |
|
280 |
q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); |
||
281 |
av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); |
||
282 |
} |
||
283 |
return 0; |
||
284 |
} |
||
285 |
|||
286 |
enum RV40BlockPos{ |
||
287 |
POS_CUR, |
||
288 |
POS_TOP, |
||
289 |
POS_LEFT, |
||
290 |
POS_BOTTOM, |
||
291 |
}; |
||
292 |
|||
293 |
#define MASK_CUR 0x0001 |
||
294 |
#define MASK_RIGHT 0x0008 |
||
295 |
#define MASK_BOTTOM 0x0010 |
||
296 |
#define MASK_TOP 0x1000 |
||
297 |
#define MASK_Y_TOP_ROW 0x000F |
||
298 |
#define MASK_Y_LAST_ROW 0xF000 |
||
299 |
#define MASK_Y_LEFT_COL 0x1111 |
||
300 |
#define MASK_Y_RIGHT_COL 0x8888 |
||
301 |
#define MASK_C_TOP_ROW 0x0003 |
||
302 |
#define MASK_C_LAST_ROW 0x000C |
||
303 |
#define MASK_C_LEFT_COL 0x0005 |
||
304 |
#define MASK_C_RIGHT_COL 0x000A |
||
305 |
|||
306 |
static const int neighbour_offs_x[4] = { 0, 0, -1, 0 }; |
||
307 |
static const int neighbour_offs_y[4] = { 0, -1, 0, 1 }; |
||
308 |
|||
309 |
2315053 |
static void rv40_adaptive_loop_filter(RV34DSPContext *rdsp, |
|
310 |
uint8_t *src, int stride, int dmode, |
||
311 |
int lim_q1, int lim_p1, |
||
312 |
int alpha, int beta, int beta2, |
||
313 |
int chroma, int edge, int dir) |
||
314 |
{ |
||
315 |
int filter_p1, filter_q1; |
||
316 |
int strong; |
||
317 |
int lims; |
||
318 |
|||
319 |
2315053 |
strong = rdsp->rv40_loop_filter_strength[dir](src, stride, beta, beta2, |
|
320 |
edge, &filter_p1, &filter_q1); |
||
321 |
|||
322 |
2315053 |
lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1; |
|
323 |
|||
324 |
✓✓ | 2315053 |
if (strong) { |
325 |
328913 |
rdsp->rv40_strong_loop_filter[dir](src, stride, alpha, |
|
326 |
lims, dmode, chroma); |
||
327 |
✓✓ | 1986140 |
} else if (filter_p1 & filter_q1) { |
328 |
1247984 |
rdsp->rv40_weak_loop_filter[dir](src, stride, 1, 1, alpha, beta, |
|
329 |
lims, lim_q1, lim_p1); |
||
330 |
✓✓ | 738156 |
} else if (filter_p1 | filter_q1) { |
331 |
240995 |
rdsp->rv40_weak_loop_filter[dir](src, stride, filter_p1, filter_q1, |
|
332 |
alpha, beta, lims >> 1, lim_q1 >> 1, |
||
333 |
lim_p1 >> 1); |
||
334 |
} |
||
335 |
2315053 |
} |
|
336 |
|||
337 |
/** |
||
338 |
* RV40 loop filtering function |
||
339 |
*/ |
||
340 |
6100 |
static void rv40_loop_filter(RV34DecContext *r, int row) |
|
341 |
{ |
||
342 |
6100 |
MpegEncContext *s = &r->s; |
|
343 |
int mb_pos, mb_x; |
||
344 |
int i, j, k; |
||
345 |
uint8_t *Y, *C; |
||
346 |
int alpha, beta, betaY, betaC; |
||
347 |
int q; |
||
348 |
int mbtype[4]; ///< current macroblock and its neighbours types |
||
349 |
/** |
||
350 |
* flags indicating that macroblock can be filtered with strong filter |
||
351 |
* it is set only for intra coded MB and MB with DCs coded separately |
||
352 |
*/ |
||
353 |
int mb_strong[4]; |
||
354 |
int clip[4]; ///< MB filter clipping value calculated from filtering strength |
||
355 |
/** |
||
356 |
* coded block patterns for luma part of current macroblock and its neighbours |
||
357 |
* Format: |
||
358 |
* LSB corresponds to the top left block, |
||
359 |
* each nibble represents one row of subblocks. |
||
360 |
*/ |
||
361 |
int cbp[4]; |
||
362 |
/** |
||
363 |
* coded block patterns for chroma part of current macroblock and its neighbours |
||
364 |
* Format is the same as for luma with two subblocks in a row. |
||
365 |
*/ |
||
366 |
int uvcbp[4][2]; |
||
367 |
/** |
||
368 |
* This mask represents the pattern of luma subblocks that should be filtered |
||
369 |
* in addition to the coded ones because they lie at the edge of |
||
370 |
* 8x8 block with different enough motion vectors |
||
371 |
*/ |
||
372 |
unsigned mvmasks[4]; |
||
373 |
|||
374 |
6100 |
mb_pos = row * s->mb_stride; |
|
375 |
✓✓ | 225700 |
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ |
376 |
219600 |
int mbtype = s->current_picture_ptr->mb_type[mb_pos]; |
|
377 |
✓✓✓✓ |
219600 |
if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype)) |
378 |
23358 |
r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF; |
|
379 |
✓✓ | 219600 |
if(IS_INTRA(mbtype)) |
380 |
22811 |
r->cbp_chroma[mb_pos] = 0xFF; |
|
381 |
} |
||
382 |
6100 |
mb_pos = row * s->mb_stride; |
|
383 |
✓✓ | 225700 |
for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){ |
384 |
int y_h_deblock, y_v_deblock; |
||
385 |
int c_v_deblock[2], c_h_deblock[2]; |
||
386 |
int clip_left; |
||
387 |
int avail[4]; |
||
388 |
unsigned y_to_deblock; |
||
389 |
int c_to_deblock[2]; |
||
390 |
|||
391 |
219600 |
q = s->current_picture_ptr->qscale_table[mb_pos]; |
|
392 |
219600 |
alpha = rv40_alpha_tab[q]; |
|
393 |
219600 |
beta = rv40_beta_tab [q]; |
|
394 |
219600 |
betaY = betaC = beta * 3; |
|
395 |
✗✓ | 219600 |
if(s->width * s->height <= 176*144) |
396 |
betaY += beta; |
||
397 |
|||
398 |
219600 |
avail[0] = 1; |
|
399 |
219600 |
avail[1] = row; |
|
400 |
219600 |
avail[2] = mb_x; |
|
401 |
219600 |
avail[3] = row < s->mb_height - 1; |
|
402 |
✓✓ | 1098000 |
for(i = 0; i < 4; i++){ |
403 |
✓✓ | 878400 |
if(avail[i]){ |
404 |
850340 |
int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride; |
|
405 |
850340 |
mvmasks[i] = r->deblock_coefs[pos]; |
|
406 |
850340 |
mbtype [i] = s->current_picture_ptr->mb_type[pos]; |
|
407 |
850340 |
cbp [i] = r->cbp_luma[pos]; |
|
408 |
850340 |
uvcbp[i][0] = r->cbp_chroma[pos] & 0xF; |
|
409 |
850340 |
uvcbp[i][1] = r->cbp_chroma[pos] >> 4; |
|
410 |
}else{ |
||
411 |
28060 |
mvmasks[i] = 0; |
|
412 |
28060 |
mbtype [i] = mbtype[0]; |
|
413 |
28060 |
cbp [i] = 0; |
|
414 |
28060 |
uvcbp[i][0] = uvcbp[i][1] = 0; |
|
415 |
} |
||
416 |
✓✓✓✓ |
878400 |
mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]); |
417 |
878400 |
clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q]; |
|
418 |
} |
||
419 |
219600 |
y_to_deblock = mvmasks[POS_CUR] |
|
420 |
219600 |
| (mvmasks[POS_BOTTOM] << 16); |
|
421 |
/* This pattern contains bits signalling that horizontal edges of |
||
422 |
* the current block can be filtered. |
||
423 |
* That happens when either of adjacent subblocks is coded or lies on |
||
424 |
* the edge of 8x8 blocks with motion vectors differing by more than |
||
425 |
* 3/4 pel in any component (any edge orientation for some reason). |
||
426 |
*/ |
||
427 |
219600 |
y_h_deblock = y_to_deblock |
|
428 |
219600 |
| ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW) |
|
429 |
219600 |
| ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12); |
|
430 |
/* This pattern contains bits signalling that vertical edges of |
||
431 |
* the current block can be filtered. |
||
432 |
* That happens when either of adjacent subblocks is coded or lies on |
||
433 |
* the edge of 8x8 blocks with motion vectors differing by more than |
||
434 |
* 3/4 pel in any component (any edge orientation for some reason). |
||
435 |
*/ |
||
436 |
219600 |
y_v_deblock = y_to_deblock |
|
437 |
219600 |
| ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL) |
|
438 |
219600 |
| ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3); |
|
439 |
✓✓ | 219600 |
if(!mb_x) |
440 |
6100 |
y_v_deblock &= ~MASK_Y_LEFT_COL; |
|
441 |
✓✓ | 219600 |
if(!row) |
442 |
10980 |
y_h_deblock &= ~MASK_Y_TOP_ROW; |
|
443 |
✓✓✓✓ |
219600 |
if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM])) |
444 |
44066 |
y_h_deblock &= ~(MASK_Y_TOP_ROW << 16); |
|
445 |
/* Calculating chroma patterns is similar and easier since there is |
||
446 |
* no motion vector pattern for them. |
||
447 |
*/ |
||
448 |
✓✓ | 658800 |
for(i = 0; i < 2; i++){ |
449 |
439200 |
c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i]; |
|
450 |
439200 |
c_v_deblock[i] = c_to_deblock[i] |
|
451 |
439200 |
| ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL) |
|
452 |
439200 |
| ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1); |
|
453 |
439200 |
c_h_deblock[i] = c_to_deblock[i] |
|
454 |
439200 |
| ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2) |
|
455 |
439200 |
| (uvcbp[POS_CUR][i] << 2); |
|
456 |
✓✓ | 439200 |
if(!mb_x) |
457 |
12200 |
c_v_deblock[i] &= ~MASK_C_LEFT_COL; |
|
458 |
✓✓ | 439200 |
if(!row) |
459 |
21960 |
c_h_deblock[i] &= ~MASK_C_TOP_ROW; |
|
460 |
✓✓✓✓ |
439200 |
if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM])) |
461 |
88132 |
c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4); |
|
462 |
} |
||
463 |
|||
464 |
✓✓ | 1098000 |
for(j = 0; j < 16; j += 4){ |
465 |
878400 |
Y = s->current_picture_ptr->f->data[0] + mb_x*16 + (row*16 + j) * s->linesize; |
|
466 |
✓✓ | 4392000 |
for(i = 0; i < 4; i++, Y += 4){ |
467 |
3513600 |
int ij = i + j; |
|
468 |
✓✓ | 3513600 |
int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0; |
469 |
✓✓ | 3513600 |
int dither = j ? ij : i*4; |
470 |
|||
471 |
// if bottom block is coded then we can filter its top edge |
||
472 |
// (or bottom edge of this block, which is the same) |
||
473 |
✓✓ | 3513600 |
if(y_h_deblock & (MASK_BOTTOM << ij)){ |
474 |
705968 |
rv40_adaptive_loop_filter(&r->rdsp, Y+4*s->linesize, |
|
475 |
705968 |
s->linesize, dither, |
|
476 |
✓✓ | 705968 |
y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0, |
477 |
clip_cur, alpha, beta, betaY, |
||
478 |
0, 0, 0); |
||
479 |
} |
||
480 |
// filter left block edge in ordinary mode (with low filtering strength) |
||
481 |
✓✓✓✓ ✓✓ |
3513600 |
if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){ |
482 |
✓✓ | 703622 |
if(!i) |
483 |
✓✓ | 140445 |
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; |
484 |
else |
||
485 |
✓✓ | 563177 |
clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; |
486 |
703622 |
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither, |
|
487 |
clip_cur, |
||
488 |
clip_left, |
||
489 |
alpha, beta, betaY, 0, 0, 1); |
||
490 |
} |
||
491 |
// filter top edge of the current macroblock when filtering strength is high |
||
492 |
✓✓✓✓ ✓✓ |
3513600 |
if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){ |
493 |
132344 |
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither, |
|
494 |
clip_cur, |
||
495 |
✓✓ | 132344 |
mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0, |
496 |
alpha, beta, betaY, 0, 1, 0); |
||
497 |
} |
||
498 |
// filter left block edge in edge mode (with high filtering strength) |
||
499 |
✓✓✓✓ ✓✓ |
3513600 |
if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){ |
500 |
✓✓ | 121464 |
clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0; |
501 |
121464 |
rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither, |
|
502 |
clip_cur, |
||
503 |
clip_left, |
||
504 |
alpha, beta, betaY, 0, 1, 1); |
||
505 |
} |
||
506 |
} |
||
507 |
} |
||
508 |
✓✓ | 658800 |
for(k = 0; k < 2; k++){ |
509 |
✓✓ | 1317600 |
for(j = 0; j < 2; j++){ |
510 |
878400 |
C = s->current_picture_ptr->f->data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize; |
|
511 |
✓✓ | 2635200 |
for(i = 0; i < 2; i++, C += 4){ |
512 |
1756800 |
int ij = i + j*2; |
|
513 |
✓✓ | 1756800 |
int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0; |
514 |
✓✓ | 1756800 |
if(c_h_deblock[k] & (MASK_CUR << (ij+2))){ |
515 |
✓✓ | 201976 |
int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0; |
516 |
201976 |
rv40_adaptive_loop_filter(&r->rdsp, C+4*s->uvlinesize, s->uvlinesize, i*8, |
|
517 |
clip_bot, |
||
518 |
clip_cur, |
||
519 |
alpha, beta, betaC, 1, 0, 0); |
||
520 |
} |
||
521 |
✓✓✓✓ ✓✓ |
1756800 |
if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){ |
522 |
✓✓ | 199885 |
if(!i) |
523 |
✓✓ | 48364 |
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; |
524 |
else |
||
525 |
✓✓ | 151521 |
clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0; |
526 |
199885 |
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8, |
|
527 |
clip_cur, |
||
528 |
clip_left, |
||
529 |
alpha, beta, betaC, 1, 0, 1); |
||
530 |
} |
||
531 |
✓✓✓✓ ✓✓ |
1756800 |
if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){ |
532 |
✓✓ | 130217 |
int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0; |
533 |
130217 |
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, i*8, |
|
534 |
clip_cur, |
||
535 |
clip_top, |
||
536 |
alpha, beta, betaC, 1, 1, 0); |
||
537 |
} |
||
538 |
✓✓✓✓ ✓✓ |
1756800 |
if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){ |
539 |
✓✓ | 119577 |
clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0; |
540 |
119577 |
rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8, |
|
541 |
clip_cur, |
||
542 |
clip_left, |
||
543 |
alpha, beta, betaC, 1, 1, 1); |
||
544 |
} |
||
545 |
} |
||
546 |
} |
||
547 |
} |
||
548 |
} |
||
549 |
6100 |
} |
|
550 |
|||
551 |
/** |
||
552 |
* Initialize decoder. |
||
553 |
*/ |
||
554 |
4 |
static av_cold int rv40_decode_init(AVCodecContext *avctx) |
|
555 |
{ |
||
556 |
4 |
RV34DecContext *r = avctx->priv_data; |
|
557 |
int ret; |
||
558 |
|||
559 |
4 |
r->rv30 = 0; |
|
560 |
✗✓ | 4 |
if ((ret = ff_rv34_decode_init(avctx)) < 0) |
561 |
return ret; |
||
562 |
✓✓ | 4 |
if(!aic_top_vlc.bits) |
563 |
2 |
rv40_init_tables(); |
|
564 |
4 |
r->parse_slice_header = rv40_parse_slice_header; |
|
565 |
4 |
r->decode_intra_types = rv40_decode_intra_types; |
|
566 |
4 |
r->decode_mb_info = rv40_decode_mb_info; |
|
567 |
4 |
r->loop_filter = rv40_loop_filter; |
|
568 |
4 |
r->luma_dc_quant_i = rv40_luma_dc_quant[0]; |
|
569 |
4 |
r->luma_dc_quant_p = rv40_luma_dc_quant[1]; |
|
570 |
4 |
return 0; |
|
571 |
} |
||
572 |
|||
573 |
AVCodec ff_rv40_decoder = { |
||
574 |
.name = "rv40", |
||
575 |
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"), |
||
576 |
.type = AVMEDIA_TYPE_VIDEO, |
||
577 |
.id = AV_CODEC_ID_RV40, |
||
578 |
.priv_data_size = sizeof(RV34DecContext), |
||
579 |
.init = rv40_decode_init, |
||
580 |
.close = ff_rv34_decode_end, |
||
581 |
.decode = ff_rv34_decode_frame, |
||
582 |
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | |
||
583 |
AV_CODEC_CAP_FRAME_THREADS, |
||
584 |
.flush = ff_mpeg_flush, |
||
585 |
.pix_fmts = (const enum AVPixelFormat[]) { |
||
586 |
AV_PIX_FMT_YUV420P, |
||
587 |
AV_PIX_FMT_NONE |
||
588 |
}, |
||
589 |
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context), |
||
590 |
.caps_internal = FF_CODEC_CAP_ALLOCATE_PROGRESS, |
||
591 |
}; |
Generated by: GCOVR (Version 4.2) |