FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/rv60dec.c
Date: 2026-10-30 23:38:52
Exec Total Coverage
Lines: 1321 1469 89.9%
Functions: 87 89 97.8%
Branches: 887 1128 78.6%

Line Branch Exec Source
1 /*
2 * RV60 decoder
3 * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
4 * Copyright (C) 2023 Peter Ross
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "avcodec.h"
24 #include "codec_internal.h"
25 #include "decode.h"
26 #include "get_bits.h"
27 #include "golomb.h"
28 #include "libavutil/mem.h"
29 #include "rv60data.h"
30 #include "rv60dsp.h"
31 #include "rv60vlcs.h"
32 #include "threadprogress.h"
33 #include "unary.h"
34 #include "videodsp.h"
35
36 #include "libavutil/attributes.h"
37
38 static const int8_t frame_types[4] = {AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, AV_PICTURE_TYPE_NONE};
39
40 enum CUType {
41 CU_INTRA = 0,
42 CU_INTER_MV,
43 CU_SKIP,
44 CU_INTER
45 };
46
47 enum PUType {
48 PU_FULL = 0,
49 PU_N2HOR,
50 PU_N2VER,
51 PU_QUARTERS,
52 PU_N4HOR,
53 PU_N34HOR,
54 PU_N4VER,
55 PU_N34VER
56 };
57
58 enum IntraMode {
59 INTRAMODE_INDEX = 0,
60 INTRAMODE_DC64,
61 INTRAMODE_PLANE64,
62 INTRAMODE_MODE
63 };
64
65 enum MVRefEnum {
66 MVREF_NONE = 0,
67 MVREF_REF0,
68 MVREF_REF1,
69 MVREF_BREF,
70 MVREF_REF0ANDBREF,
71 MVREF_SKIP0,
72 MVREF_SKIP1,
73 MVREF_SKIP2,
74 MVREF_SKIP3
75 };
76
77 static const uint8_t skip_mv_ref[4] = {MVREF_SKIP0, MVREF_SKIP1, MVREF_SKIP2, MVREF_SKIP3};
78
79 enum {
80 TRANSFORM_NONE = 0,
81 TRANSFORM_16X16,
82 TRANSFORM_8X8,
83 TRANSFORM_4X4
84 };
85
86 static const VLCElem * cbp8_vlc[7][4];
87 static const VLCElem * cbp16_vlc[7][4][4];
88
89 typedef struct {
90 const VLCElem * l0[2];
91 const VLCElem * l12[2];
92 const VLCElem * l3[2];
93 const VLCElem * esc;
94 } CoeffVLCs;
95
96 static CoeffVLCs intra_coeff_vlc[5];
97 static CoeffVLCs inter_coeff_vlc[7];
98
99 #define MAX_VLC_SIZE 864
100 static VLCElem table_data[129148];
101
102 /* 32-bit version of rv34_gen_vlc */
103 392 static const VLCElem * gen_vlc(const uint8_t * bits, int size, VLCInitState * state)
104 {
105 392 int counts[17] = {0};
106 uint32_t codes[18];
107 uint32_t cw[MAX_VLC_SIZE];
108
109
2/2
✓ Branch 0 taken 66944 times.
✓ Branch 1 taken 392 times.
67336 for (int i = 0; i < size; i++)
110 66944 counts[bits[i]]++;
111
112 392 codes[0] = counts[0] = 0;
113
2/2
✓ Branch 0 taken 6664 times.
✓ Branch 1 taken 392 times.
7056 for (int i = 0; i < 17; i++)
114 6664 codes[i+1] = (codes[i] + counts[i]) << 1;
115
116
2/2
✓ Branch 0 taken 66944 times.
✓ Branch 1 taken 392 times.
67336 for (int i = 0; i < size; i++)
117 66944 cw[i] = codes[bits[i]]++;
118
119 392 return ff_vlc_init_tables(state, 9, size,
120 bits, 1, 1,
121 cw, 4, 4, 0);
122 }
123
124 4 static void build_coeff_vlc(const CoeffLens * lens, CoeffVLCs * vlc, int count, VLCInitState * state)
125 {
126
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 for (int i = 0; i < count; i++) {
127
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 24 times.
72 for (int j = 0; j < 2; j++) {
128 48 vlc[i].l0[j] = gen_vlc(lens[i].l0[j], 864, state);
129 48 vlc[i].l12[j] = gen_vlc(lens[i].l12[j], 108, state);
130 48 vlc[i].l3[j] = gen_vlc(lens[i].l3[j], 108, state);
131 }
132 24 vlc[i].esc = gen_vlc(lens[i].esc, 32, state);
133 }
134 4 }
135
136 2 static av_cold void rv60_init_static_data(void)
137 {
138 2 VLCInitState state = VLC_INIT_STATE(table_data);
139
140
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 for (int i = 0; i < 7; i++)
141
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14 times.
70 for (int j = 0; j < 4; j++)
142 56 cbp16_vlc[i][0][j] = cbp8_vlc[i][j] = gen_vlc(rv60_cbp8_lens[i][j], 64, &state);
143
144
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 for (int i = 0; i < 7; i++)
145
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 14 times.
56 for (int j = 0; j < 3; j++)
146
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 42 times.
210 for (int k = 0; k < 4; k++)
147 168 cbp16_vlc[i][j + 1][k] = gen_vlc(rv60_cbp16_lens[i][j][k], 64, &state);
148
149 2 build_coeff_vlc(rv60_intra_lens, intra_coeff_vlc, 5, &state);
150 2 build_coeff_vlc(rv60_inter_lens, inter_coeff_vlc, 7, &state);
151 2 }
152
153 typedef struct {
154 int sign;
155 int size;
156 const uint8_t * data;
157 int data_size;
158 } Slice;
159
160 typedef struct {
161 int cu_split_pos;
162 uint8_t cu_split[1+4+16+64];
163
164 uint8_t coded_blk[64];
165
166 uint8_t avg_buffer[64*64 + 32*32*2];
167 uint8_t * avg_data[3];
168 int avg_linesize[3];
169 } ThreadContext;
170
171 typedef struct {
172 int16_t x;
173 int16_t y;
174 } MV;
175
176 typedef struct {
177 enum MVRefEnum mvref;
178 MV f_mv;
179 MV b_mv;
180 } MVInfo;
181
182 typedef struct {
183 enum IntraMode imode;
184 MVInfo mv;
185 } BlockInfo;
186
187 typedef struct {
188 enum CUType cu_type;
189 enum PUType pu_type;
190 } PUInfo;
191
192 typedef struct RV60Context {
193 AVCodecContext * avctx;
194 VideoDSPContext vdsp;
195
196 #define CUR_PIC 0
197 #define LAST_PIC 1
198 #define NEXT_PIC 2
199 AVFrame *last_frame[3];
200
201 int pict_type;
202 int qp;
203 int osvquant;
204 int ts;
205 int two_f_refs;
206 int qp_off_type;
207 int deblock;
208 int deblock_chroma;
209 int awidth;
210 int aheight;
211 int cu_width;
212 int cu_height;
213
214 Slice * slice;
215
216 int pu_stride;
217 PUInfo * pu_info;
218
219 int blk_stride;
220 BlockInfo * blk_info;
221
222 int dblk_stride;
223 uint8_t * left_str;
224 uint8_t * top_str;
225
226 uint64_t ref_pts[2], ts_scale;
227 uint32_t ref_ts[2];
228
229 struct ThreadProgress *progress;
230 unsigned nb_progress;
231 } RV60Context;
232
233 39 static int progress_init(RV60Context *s, unsigned count)
234 {
235
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 37 times.
39 if (s->nb_progress < count) {
236 2 void *tmp = av_realloc_array(s->progress, count, sizeof(*s->progress));
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!tmp)
238 ✗ return AVERROR(ENOMEM);
239 2 s->progress = tmp;
240 2 memset(s->progress + s->nb_progress, 0, (count - s->nb_progress) * sizeof(*s->progress));
241
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 for (int i = s->nb_progress; i < count; i++) {
242 10 int ret = ff_thread_progress_init(&s->progress[i], 1);
243
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (ret < 0)
244 ✗ return ret;
245 10 s->nb_progress = i + 1;
246 }
247 }
248
249
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 39 times.
141 for (int i = 0; i < count; i++)
250 102 ff_thread_progress_reset(&s->progress[i]);
251
252 39 return 0;
253 }
254
255 4 static av_cold int rv60_decode_init(AVCodecContext * avctx)
256 {
257 static AVOnce init_static_once = AV_ONCE_INIT;
258 4 RV60Context *s = avctx->priv_data;
259
260 4 s->avctx = avctx;
261
262 4 ff_videodsp_init(&s->vdsp, 8);
263
264 4 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
265
266
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 for (int i = 0; i < 3; i++) {
267 12 s->last_frame[i] = av_frame_alloc();
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!s->last_frame[i])
269 ✗ return AVERROR(ENOMEM);
270 }
271
272 4 ff_thread_once(&init_static_once, rv60_init_static_data);
273
274 4 return 0;
275 }
276
277 39 static int update_dimensions_clear_info(RV60Context *s, int width, int height)
278 {
279 int ret;
280
281
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
39 if (width != s->avctx->width || height != s->avctx->height) {
282
283 ✗ av_log(s->avctx, AV_LOG_INFO, "changing dimensions to %dx%d\n", width, height);
284
285 ✗ for (int i = 0; i < 3; i++)
286 ✗ av_frame_unref(s->last_frame[i]);
287
288 ✗ if ((ret = ff_set_dimensions(s->avctx, width, height)) < 0)
289 ✗ return ret;
290
291 ✗ if (s->avctx->width <= 64 || s->avctx->height <= 64)
292 ✗ av_log(s->avctx, AV_LOG_WARNING, "unable to faithfully reproduce emulated edges; expect visual artefacts\n");
293 }
294
295 39 s->awidth = FFALIGN(width, 16);
296 39 s->aheight = FFALIGN(height, 16);
297
298 39 s->cu_width = (width + 63) >> 6;
299 39 s->cu_height = (height + 63) >> 6;
300
301 39 s->pu_stride = s->cu_width << 3;
302 39 s->blk_stride = s->cu_width << 4;
303
304
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = av_reallocp_array(&s->slice, s->cu_height, sizeof(s->slice[0]))) < 0)
305 ✗ return ret;
306
307
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = av_reallocp_array(&s->pu_info, s->pu_stride * (s->cu_height << 3), sizeof(s->pu_info[0]))) < 0)
308 ✗ return ret;
309
310
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = av_reallocp_array(&s->blk_info, s->blk_stride * (s->cu_height << 4), sizeof(s->blk_info[0]))) < 0)
311 ✗ return ret;
312
313 39 memset(s->pu_info, 0, s->pu_stride * (s->cu_height << 3) * sizeof(s->pu_info[0]));
314 39 memset(s->blk_info, 0, s->blk_stride * (s->cu_height << 4) * sizeof(s->blk_info[0]));
315
316
2/2
✓ Branch 0 taken 1632 times.
✓ Branch 1 taken 39 times.
1671 for (int j = 0; j < s->cu_height << 4; j++)
317
2/2
✓ Branch 0 taken 101376 times.
✓ Branch 1 taken 1632 times.
103008 for (int i = 0; i < s->cu_width << 4; i++)
318 101376 s->blk_info[j*s->blk_stride + i].mv.mvref = MVREF_NONE;
319
320
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if (s->deblock) {
321 int size;
322
323 39 s->dblk_stride = s->awidth >> 2;
324
325 39 size = s->dblk_stride * (s->aheight >> 2);
326
327
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = av_reallocp_array(&s->top_str, size, sizeof(s->top_str[0]))) < 0)
328 ✗ return ret;
329
330
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = av_reallocp_array(&s->left_str, size, sizeof(s->left_str[0]))) < 0)
331 ✗ return ret;
332
333 39 memset(s->top_str, 0, size);
334 39 memset(s->left_str, 0, size);
335 }
336
337 39 return 0;
338 }
339
340 4039 static int read_code012(GetBitContext * gb)
341 {
342
2/2
✓ Branch 1 taken 2755 times.
✓ Branch 2 taken 1284 times.
4039 if (!get_bits1(gb))
343 2755 return 0;
344 1284 return get_bits1(gb) + 1;
345 }
346
347 39 static int read_frame_header(RV60Context *s, GetBitContext *gb, int * width, int * height)
348 {
349
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if (get_bits(gb, 2) != 3)
350 ✗ return AVERROR_INVALIDDATA;
351
352 39 skip_bits(gb, 2);
353 39 skip_bits(gb, 4);
354
355 39 s->pict_type = frame_types[get_bits(gb, 2)];
356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (s->pict_type == AV_PICTURE_TYPE_NONE)
357 ✗ return AVERROR_INVALIDDATA;
358
359 39 s->qp = get_bits(gb, 6);
360 39 skip_bits1(gb);
361 39 skip_bits(gb, 2);
362 39 s->osvquant = get_bits(gb, 2);
363 39 skip_bits1(gb);
364 39 skip_bits(gb, 2);
365 39 s->ts = get_bits(gb, 24);
366 39 *width = (get_bits(gb, 11) + 1) * 4;
367 39 *height = get_bits(gb, 11) * 4;
368 39 skip_bits1(gb);
369
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 37 times.
39 if (s->pict_type == AV_PICTURE_TYPE_I) {
370 2 s->two_f_refs = 0;
371 } else {
372
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (get_bits1(gb))
373 ✗ skip_bits(gb, 3);
374 37 s->two_f_refs = get_bits1(gb);
375 }
376 39 read_code012(gb);
377 39 read_code012(gb);
378 39 s->qp_off_type = read_code012(gb);
379 39 s->deblock = get_bits1(gb);
380
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 39 times.
✗ Branch 4 not taken.
39 s->deblock_chroma = s->deblock && !get_bits1(gb);
381
382
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if (get_bits1(gb)) {
383 ✗ int count = get_bits(gb, 2);
384 ✗ if (count) {
385 ✗ skip_bits(gb, 2);
386 ✗ for (int i = 0; i < count; i++)
387 ✗ for (int j = 0; j < 2 << i; j++)
388 ✗ skip_bits(gb, 8);
389 }
390 }
391
392 39 return 0;
393 }
394
395 39 static int read_slice_sizes(RV60Context *s, GetBitContext *gb)
396 {
397 39 int nbits = get_bits(gb, 5) + 1;
398 int64_t last_size;
399
400
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 39 times.
141 for (int i = 0; i < s->cu_height; i++)
401 102 s->slice[i].sign = get_bits1(gb);
402
403 39 s->slice[0].size = last_size = get_bits_long(gb, nbits);
404
405
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
39 if (last_size < 0 || last_size > INT32_MAX)
406 ✗ return AVERROR_INVALIDDATA;
407
408
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 39 times.
102 for (int i = 1; i < s->cu_height; i++) {
409 63 int diff = get_bits_long(gb, nbits);
410
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 55 times.
63 if (s->slice[i].sign)
411 8 last_size += diff;
412 else
413 55 last_size -= diff;
414
2/4
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 63 times.
63 if (last_size <= 0 || last_size > INT32_MAX)
415 ✗ return AVERROR_INVALIDDATA;
416 63 s->slice[i].size = last_size;
417 }
418
419 39 align_get_bits(gb);
420 39 return 0;
421 }
422
423 4447 static int read_intra_mode(GetBitContext * gb, int * param)
424 {
425
2/2
✓ Branch 1 taken 3922 times.
✓ Branch 2 taken 525 times.
4447 if (get_bits1(gb)) {
426 3922 *param = read_code012(gb);
427 3922 return INTRAMODE_INDEX;
428 } else {
429 525 *param = get_bits(gb, 5);
430 525 return INTRAMODE_MODE;
431 }
432 }
433
434 15476 static int has_top_block(const RV60Context * s, int xpos, int ypos, int dx, int dy, int size)
435 {
436
4/4
✓ Branch 0 taken 15315 times.
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 14998 times.
✓ Branch 3 taken 317 times.
15476 return ypos + dy && xpos + dx + size <= s->awidth;
437 }
438
439 13316 static int has_left_block(const RV60Context * s, int xpos, int ypos, int dx, int dy, int size)
440 {
441
4/4
✓ Branch 0 taken 13232 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 13080 times.
✓ Branch 3 taken 152 times.
13316 return xpos + dx && ypos + dy + size <= s->aheight;
442 }
443
444 8848 static int has_top_right_block(const RV60Context * s, int xpos, int ypos, int dx, int dy, int size)
445 {
446
2/2
✓ Branch 1 taken 8603 times.
✓ Branch 2 taken 245 times.
8848 if (has_top_block(s, xpos, ypos, dx, dy, size * 2)) {
447 8603 int cxpos = ((xpos + dx) & 63) >> ff_log2(size);
448 8603 int cypos = ((ypos + dy) & 63) >> ff_log2(size);
449 8603 return !(rv60_avail_mask[cxpos] & cypos);
450 }
451 245 return 0;
452 }
453
454 8869 static int has_left_down_block(const RV60Context * s, int xpos, int ypos, int dx, int dy, int size)
455 {
456
2/2
✓ Branch 1 taken 8717 times.
✓ Branch 2 taken 152 times.
8869 if (has_left_block(s, xpos, ypos, dx, dy, size * 2)) {
457 8717 int cxpos = (~(xpos + dx) & 63) >> ff_log2(size);
458 8717 int cypos = (~(ypos + dy) & 63) >> ff_log2(size);
459 8717 return rv60_avail_mask[cxpos] & cypos;
460 }
461 152 return 0;
462 }
463
464 typedef struct {
465 uint8_t t[129];
466 uint8_t l[129];
467 int has_t;
468 int has_tr;
469 int has_l;
470 int has_ld;
471 } IntraPredContext;
472
473 typedef struct {
474 int xpos;
475 int ypos;
476 int pu_pos;
477 int blk_pos;
478
479 enum CUType cu_type;
480 enum PUType pu_type;
481 enum IntraMode imode[4];
482 int imode_param[4];
483 MVInfo mv[4];
484
485 IntraPredContext ipred;
486 } CUContext;
487
488 9033 static void ipred_init(IntraPredContext * i)
489 {
490 9033 memset(i->t, 0x80, sizeof(i->t));
491 9033 memset(i->l, 0x80, sizeof(i->l));
492 9033 i->has_t = i->has_tr = i->has_l = i->has_ld = 0;
493 9033 }
494
495 9033 static void populate_ipred(const RV60Context * s, CUContext * cu, const uint8_t * src, int stride, int xoff, int yoff, int size, int is_luma)
496 {
497
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 4586 times.
9033 if (is_luma)
498 4447 src += (cu->ypos + yoff) * stride + cu->xpos + xoff;
499 else
500 4586 src += (cu->ypos >> 1) * stride + (cu->xpos >> 1);
501
502 9033 ipred_init(&cu->ipred);
503
504
2/2
✓ Branch 0 taken 8848 times.
✓ Branch 1 taken 185 times.
9033 if (cu->ypos + yoff > 0) {
505 8848 cu->ipred.has_t = 1;
506
507 8848 memcpy(cu->ipred.t + 1, src - stride, size);
508
509
6/6
✓ Branch 0 taken 4370 times.
✓ Branch 1 taken 4478 times.
✓ Branch 3 taken 1529 times.
✓ Branch 4 taken 2841 times.
✓ Branch 5 taken 4478 times.
✓ Branch 6 taken 1529 times.
8848 if ((is_luma && has_top_right_block(s, cu->xpos, cu->ypos, xoff, yoff, size)) ||
510
2/2
✓ Branch 1 taken 2856 times.
✓ Branch 2 taken 1622 times.
4478 (!is_luma && has_top_right_block(s, cu->xpos, cu->ypos, 0, 0, size << 1))) {
511 5697 cu->ipred.has_tr = 1;
512 5697 memcpy(cu->ipred.t + size + 1, src - stride + size, size);
513 } else
514 3151 memset(cu->ipred.t + size + 1, cu->ipred.t[size], size);
515
516
2/2
✓ Branch 0 taken 8690 times.
✓ Branch 1 taken 158 times.
8848 if (cu->xpos + xoff > 0)
517 8690 cu->ipred.t[0] = src[-stride - 1];
518 }
519
520
2/2
✓ Branch 0 taken 8869 times.
✓ Branch 1 taken 164 times.
9033 if (cu->xpos + xoff > 0) {
521 8869 cu->ipred.has_l = 1;
522
523
2/2
✓ Branch 0 taken 54160 times.
✓ Branch 1 taken 8869 times.
63029 for (int y = 0; y < size; y++)
524 54160 cu->ipred.l[y + 1] = src[y*stride - 1];
525
526
6/6
✓ Branch 0 taken 4385 times.
✓ Branch 1 taken 4484 times.
✓ Branch 3 taken 2994 times.
✓ Branch 4 taken 1391 times.
✓ Branch 5 taken 4484 times.
✓ Branch 6 taken 2994 times.
8869 if ((is_luma && has_left_down_block(s, cu->xpos, cu->ypos, xoff, yoff, size)) ||
527
2/2
✓ Branch 1 taken 1368 times.
✓ Branch 2 taken 3116 times.
4484 (!is_luma && has_left_down_block(s, cu->xpos, cu->ypos, 0, 0, size << 1))) {
528 2759 cu->ipred.has_ld = 1;
529
2/2
✓ Branch 0 taken 17032 times.
✓ Branch 1 taken 2759 times.
19791 for (int y = size; y < size * 2; y++)
530 17032 cu->ipred.l[y + 1] = src[y*stride - 1];
531 } else
532 6110 memset(cu->ipred.l + size + 1, cu->ipred.l[size], size);
533
534
2/2
✓ Branch 0 taken 8690 times.
✓ Branch 1 taken 179 times.
8869 if (cu->ypos + yoff > 0)
535 8690 cu->ipred.l[0] = src[-stride - 1];
536 }
537 9033 }
538
539 1492 static void pred_plane(const IntraPredContext * p, uint8_t * dst, int stride, int size)
540 {
541 1492 int lastl = p->l[size + 1];
542 1492 int lastt = p->t[size + 1];
543 int tmp1[64], tmp2[64];
544 int top_ref[64], left_ref[64];
545 int shift;
546
547
2/2
✓ Branch 0 taken 6656 times.
✓ Branch 1 taken 1492 times.
8148 for (int i = 0; i < size; i++) {
548 6656 tmp1[i] = lastl - p->t[i + 1];
549 6656 tmp2[i] = lastt - p->l[i + 1];
550 }
551
552 1492 shift = ff_log2(size) + 1;
553
2/2
✓ Branch 0 taken 6656 times.
✓ Branch 1 taken 1492 times.
8148 for (int i = 0; i < size; i++) {
554 6656 top_ref[i] = p->t[i + 1] << (shift - 1);
555 6656 left_ref[i] = p->l[i + 1] << (shift - 1);
556 }
557
558
2/2
✓ Branch 0 taken 6656 times.
✓ Branch 1 taken 1492 times.
8148 for (int y = 0; y < size; y++) {
559 6656 int add = tmp2[y];
560 6656 int sum = left_ref[y] + size;
561
2/2
✓ Branch 0 taken 34816 times.
✓ Branch 1 taken 6656 times.
41472 for (int x = 0; x < size; x++) {
562 34816 int v = tmp1[x] + top_ref[x];
563 34816 sum += add;
564 34816 top_ref[x] = v;
565 34816 dst[y*stride + x] = (sum + v) >> shift;
566 }
567 }
568 1492 }
569
570 5606 static void pred_dc(const IntraPredContext * p, uint8_t * dst, int stride, int size, int filter)
571 {
572 int dc;
573
574
3/4
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 5477 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 129 times.
5606 if (!p->has_t && !p->has_l)
575 ✗ dc = 0x80;
576 else {
577 5606 int sum = 0;
578
2/2
✓ Branch 0 taken 5477 times.
✓ Branch 1 taken 129 times.
5606 if (p->has_t)
579
2/2
✓ Branch 0 taken 37568 times.
✓ Branch 1 taken 5477 times.
43045 for (int x = 0; x < size; x++)
580 37568 sum += p->t[x + 1];
581
2/2
✓ Branch 0 taken 5458 times.
✓ Branch 1 taken 148 times.
5606 if (p->has_l)
582
2/2
✓ Branch 0 taken 37304 times.
✓ Branch 1 taken 5458 times.
42762 for (int y = 0; y < size; y++)
583 37304 sum += p->l[y + 1];
584
4/4
✓ Branch 0 taken 5477 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 5329 times.
✓ Branch 3 taken 148 times.
5606 if (p->has_t && p->has_l)
585 5329 dc = (sum + size) / (size * 2);
586 else
587 277 dc = (sum + size / 2) / size;
588 }
589
590
2/2
✓ Branch 0 taken 38516 times.
✓ Branch 1 taken 5606 times.
44122 for (int y = 0; y < size; y++)
591 38516 memset(dst + y*stride, dc, size);
592
593
6/6
✓ Branch 0 taken 2478 times.
✓ Branch 1 taken 3128 times.
✓ Branch 2 taken 2427 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 2373 times.
✓ Branch 5 taken 54 times.
5606 if (filter && p->has_t && p->has_l) {
594 2373 dst[0] = (p->t[1] + p->l[1] + 2 * dst[0] + 2) >> 2;
595
2/2
✓ Branch 0 taken 16911 times.
✓ Branch 1 taken 2373 times.
19284 for (int x = 1; x < size; x++)
596 16911 dst[x] = (p->t[x + 1] + 3 * dst[x] + 2) >> 2;
597
2/2
✓ Branch 0 taken 16911 times.
✓ Branch 1 taken 2373 times.
19284 for (int y = 1; y < size; y++)
598 16911 dst[y*stride] = (p->l[y + 1] + 3 * dst[y*stride] + 2) >> 2;
599 }
600 5606 }
601
602 1762 static void filter_weak(uint8_t * dst, const uint8_t * src, int size)
603 {
604 1762 dst[0] = src[0];
605
2/2
✓ Branch 0 taken 6530 times.
✓ Branch 1 taken 1762 times.
8292 for (int i = 1; i < size - 1; i++)
606 6530 dst[i] = (src[i - 1] + 2*src[i] + src[i + 1] + 2) >> 2;
607 1762 dst[size - 1] = src[size - 1];
608 1762 }
609
610 ✗ static void filter_bilin32(uint8_t * dst, int v0, int v1, int size)
611 {
612 ✗ int diff = v1 - v0;
613 ✗ int sum = (v0 << 5) + (1 << (5 - 1));
614 ✗ for (int i = 0; i < size; i++) {
615 ✗ dst[i] = sum >> 5;
616 ✗ sum += diff;
617 }
618 ✗ }
619
620 355 static void pred_hor_angle(uint8_t * dst, int stride, int size, int weight, const uint8_t * src)
621 {
622 355 int sum = 0;
623
2/2
✓ Branch 0 taken 1420 times.
✓ Branch 1 taken 355 times.
1775 for (int x = 0; x < size; x++) {
624 int off, frac;
625 1420 sum += weight;
626 1420 off = (sum >> 5) + 32;
627 1420 frac = sum & 0x1F;
628
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1420 times.
1420 if (!frac)
629 ✗ for (int y = 0; y < size; y++)
630 ✗ dst[y*stride + x] = src[off + y];
631 else {
632
2/2
✓ Branch 0 taken 5680 times.
✓ Branch 1 taken 1420 times.
7100 for (int y = 0; y < size; y++) {
633 5680 int a = src[off + y];
634 5680 int b = src[off + y + 1];
635 5680 dst[y*stride + x] = ((32 - frac) * a + frac * b + 16) >> 5;
636 }
637 }
638 }
639 355 }
640
641 351 static void pred_ver_angle(uint8_t * dst, int stride, int size, int weight, const uint8_t * src)
642 {
643 351 int sum = 0;
644
2/2
✓ Branch 0 taken 1516 times.
✓ Branch 1 taken 351 times.
1867 for (int y = 0; y < size; y++) {
645 int off, frac;
646 1516 sum += weight;
647 1516 off = (sum >> 5) + 32;
648 1516 frac = sum & 0x1F;
649
2/2
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 1308 times.
1516 if (!frac)
650 208 memcpy(dst + y*stride, src + off, size);
651 else {
652
2/2
✓ Branch 0 taken 5232 times.
✓ Branch 1 taken 1308 times.
6540 for (int x = 0; x < size; x++) {
653 5232 int a = src[off + x];
654 5232 int b = src[off + x + 1];
655 5232 dst[y*stride + x] = ((32 - frac) * a + frac * b + 16) >> 5;
656 }
657 }
658 }
659 351 }
660
661 9033 static int pred_angle(const IntraPredContext * p, uint8_t * dst, int stride, int size, int imode, int filter)
662 {
663 uint8_t filtered1[96], filtered2[96];
664
665
3/6
✓ Branch 0 taken 9033 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9033 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9033 times.
9033 if (size < 4 || size > 64 || (size & (size - 1)))
666 ✗ return AVERROR_INVALIDDATA;
667
668
2/2
✓ Branch 0 taken 1492 times.
✓ Branch 1 taken 7541 times.
9033 if (!imode) {
669 1492 pred_plane(p, dst, stride, size);
670
2/2
✓ Branch 0 taken 5606 times.
✓ Branch 1 taken 1935 times.
7541 } else if (imode == 1) {
671 5606 pred_dc(p, dst, stride, size, filter);
672
2/2
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 1612 times.
1935 } else if (imode <= 9) {
673 323 int ang_weight = rv60_ipred_angle[10 - imode];
674 323 int add_size = (size * ang_weight + 31) >> 5;
675
1/2
✓ Branch 0 taken 323 times.
✗ Branch 1 not taken.
323 if (size <= 16) {
676 323 const int filtered_size = size + add_size;
677
2/4
✓ Branch 0 taken 323 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 323 times.
323 if (filtered_size < 1 || filtered_size > 64)
678 ✗ return AVERROR_INVALIDDATA;
679 323 filter_weak(filtered1 + 32, &p->l[1], filtered_size);
680 } else {
681 ✗ if (add_size < 0 || add_size > 32)
682 ✗ return AVERROR_INVALIDDATA;
683 ✗ filter_bilin32(filtered1 + 32, p->l[1], p->l[33], 32);
684 ✗ filter_bilin32(filtered1 + 64, p->l[32], p->l[64], add_size);
685 }
686 323 pred_hor_angle(dst, stride, size, ang_weight, filtered1);
687
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 1255 times.
1612 } else if (imode == 10) {
688
1/2
✓ Branch 0 taken 357 times.
✗ Branch 1 not taken.
357 if (size <= 16)
689 357 filter_weak(filtered1 + 32, &p->l[1], size);
690 else
691 ✗ filter_bilin32(filtered1 + 32, p->l[1], p->l[33], 32);
692
2/2
✓ Branch 0 taken 2232 times.
✓ Branch 1 taken 357 times.
2589 for (int y = 0; y < size; y++)
693
2/2
✓ Branch 0 taken 18336 times.
✓ Branch 1 taken 2232 times.
20568 for (int x = 0; x < size; x++)
694 18336 dst[y*stride + x] = filtered1[32 + y];
695
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 192 times.
357 if (filter) {
696 165 int tl = p->t[0];
697
2/2
✓ Branch 0 taken 1216 times.
✓ Branch 1 taken 165 times.
1381 for (int x = 0; x < size; x++)
698 1216 dst[x] = av_clip_uint8(dst[x] + ((p->t[x + 1] - tl) >> 1));
699 }
700
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1223 times.
1255 } else if (imode <= 17) {
701 32 int ang_weight = rv60_ipred_angle[imode - 10];
702 32 int inv_angle = rv60_ipred_inv_angle[imode - 10];
703 32 int add_size = (size * ang_weight + 31) >> 5;
704
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (size <= 16) {
705 32 memcpy(filtered1 + 32 - 1, p->l, size + 1);
706 32 memcpy(filtered2 + 32 - 1, p->t, size + 1);
707 } else {
708 ✗ filtered1[32 - 1] = p->l[0];
709 ✗ filter_bilin32(filtered1 + 32, p->l[0], p->l[32], 32);
710 ✗ filtered2[32 - 1] = p->t[0];
711 ✗ filter_bilin32(filtered2 + 32, p->t[0], p->t[32], 32);
712 }
713
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 22 times.
32 if (add_size > 1) {
714 10 int sum = 0x80;
715
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 10 times.
28 for (int i = 1; i < add_size; i++) {
716 18 sum += inv_angle;
717 18 filtered1[32 - 1 - i] = filtered2[32 - 1 + (sum >> 8)];
718 }
719 }
720 32 pred_hor_angle(dst, stride, size, -ang_weight, filtered1);
721
2/2
✓ Branch 0 taken 141 times.
✓ Branch 1 taken 1082 times.
1223 } else if (imode <= 25) {
722 141 int ang_weight = rv60_ipred_angle[26 - imode];
723 141 int inv_angle = rv60_ipred_inv_angle[26 - imode];
724 141 int add_size = (size * ang_weight + 31) >> 5;
725
1/2
✓ Branch 0 taken 141 times.
✗ Branch 1 not taken.
141 if (size <= 16) {
726 141 memcpy(filtered1 + 32 - 1, p->t, size + 1);
727 141 memcpy(filtered2 + 32 - 1, p->l, size + 1);
728 } else {
729 ✗ filtered1[32 - 1] = p->t[0];
730 ✗ filter_bilin32(filtered1 + 32, p->t[0], p->t[32], 32);
731 ✗ filtered2[32 - 1] = p->l[0];
732 ✗ filter_bilin32(filtered2 + 32, p->l[0], p->l[32], 32);
733 }
734
2/2
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 76 times.
141 if (add_size > 1) {
735 65 int sum = 0x80;
736
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 65 times.
307 for (int i = 1; i < add_size; i++) {
737 242 sum += inv_angle;
738 242 filtered1[32 - 1 - i] = filtered2[32 - 1 + (sum >> 8)];
739 }
740 }
741 141 pred_ver_angle(dst, stride, size, -ang_weight, filtered1);
742
2/2
✓ Branch 0 taken 872 times.
✓ Branch 1 taken 210 times.
1082 } else if (imode == 26) {
743
1/2
✓ Branch 0 taken 872 times.
✗ Branch 1 not taken.
872 if (size <= 16)
744 872 filter_weak(&filtered1[32], &p->t[1], size);
745 else
746 ✗ filter_bilin32(filtered1 + 32, p->t[1], p->t[33], 32);
747
2/2
✓ Branch 0 taken 5100 times.
✓ Branch 1 taken 872 times.
5972 for (int i = 0; i < size; i++)
748 5100 memcpy(dst + i*stride, filtered1 + 32, size);
749
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 476 times.
872 if (filter) {
750 396 int tl = p->l[0];
751
2/2
✓ Branch 0 taken 2844 times.
✓ Branch 1 taken 396 times.
3240 for (int y = 0; y < size; y++)
752 2844 dst[y*stride] = av_clip_uint8(dst[y*stride] + ((p->l[y+1] - tl) >> 1));
753 }
754
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 } else if (imode <= 34) {
755 210 int ang_weight = rv60_ipred_angle[imode - 26];
756 210 int add_size = (size * ang_weight + 31) >> 5;
757
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 if (size <= 16) {
758 210 const int filtered_size = size + add_size;
759
2/4
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 210 times.
210 if (filtered_size < 1 || filtered_size > 64)
760 ✗ return AVERROR_INVALIDDATA;
761 210 filter_weak(&filtered1[32], &p->t[1], filtered_size);
762 } else {
763 ✗ if (add_size < 0 || add_size > 32)
764 ✗ return AVERROR_INVALIDDATA;
765 ✗ filter_bilin32(filtered1 + 32, p->t[1], p->t[33], 32);
766 ✗ filter_bilin32(filtered1 + 64, p->t[32], p->t[64], add_size);
767 }
768 210 pred_ver_angle(dst, stride, size, ang_weight, filtered1);
769 } else
770 ✗ return AVERROR_INVALIDDATA;
771 9033 return 0;
772 }
773
774 12986 static int pu_is_intra(const PUInfo * pu)
775 {
776 12986 return pu->cu_type == CU_INTRA;
777 }
778
779 1355 static int ipm_compar(const void * a, const void * b)
780 {
781 1355 return *(const enum IntraMode *)a - *(const enum IntraMode *)b;
782 }
783
784 #define MK_UNIQUELIST(name, type, max_size) \
785 typedef struct { \
786 type list[max_size]; \
787 int size; \
788 } unique_list_##name; \
789 \
790 static void unique_list_##name##_init(unique_list_##name * s) \
791 { \
792 memset(s->list, 0, sizeof(s->list)); \
793 s->size = 0; \
794 } \
795 \
796 static void unique_list_##name##_add(unique_list_##name * s, type cand) \
797 { \
798 if (s->size == max_size) \
799 return; \
800 \
801 for (int i = 0; i < s->size; i++) { \
802 if (!memcmp(&s->list[i], &cand, sizeof(type))) { \
803 return; \
804 } \
805 } \
806 s->list[s->size++] = cand; \
807 }
808
809
6/6
✓ Branch 0 taken 16662 times.
✓ Branch 1 taken 20926 times.
✓ Branch 2 taken 7585 times.
✓ Branch 3 taken 14982 times.
✓ Branch 4 taken 22567 times.
✓ Branch 5 taken 13341 times.
114034 MK_UNIQUELIST(intramode, enum IntraMode, 3)
810
6/6
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 8788 times.
✓ Branch 2 taken 5422 times.
✓ Branch 3 taken 3400 times.
✓ Branch 4 taken 8822 times.
✓ Branch 5 taken 3366 times.
28116 MK_UNIQUELIST(mvinfo, MVInfo, 4)
811
812 4447 static int reconstruct_intra(const RV60Context * s, const CUContext * cu, int size, int sub)
813 {
814 int blk_pos, tl_x, tl_y;
815 unique_list_intramode ipm_cand;
816
817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (cu->imode[0] == INTRAMODE_DC64)
818 ✗ return 1;
819
820
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (cu->imode[0] == INTRAMODE_PLANE64)
821 ✗ return 0;
822
823 4447 unique_list_intramode_init(&ipm_cand);
824
825
2/2
✓ Branch 1 taken 4324 times.
✓ Branch 2 taken 123 times.
4447 if (has_top_block(s, cu->xpos, cu->ypos, (sub & 1) * 4, 0, size)) {
826 4324 const PUInfo * pu = &s->pu_info[cu->pu_pos - s->pu_stride];
827
2/2
✓ Branch 1 taken 3612 times.
✓ Branch 2 taken 712 times.
4324 if (pu_is_intra(pu))
828 3612 unique_list_intramode_add(&ipm_cand, s->blk_info[cu->blk_pos - s->blk_stride + (sub & 1)].imode);
829 }
830
831 4447 blk_pos = cu->blk_pos + (sub >> 1) * s->blk_stride + (sub & 1);
832
833
2/2
✓ Branch 1 taken 4363 times.
✓ Branch 2 taken 84 times.
4447 if (has_left_block(s, cu->xpos, cu->ypos, 0, (sub & 2) * 2, size)) {
834 4363 const PUInfo * pu = &s->pu_info[cu->pu_pos - 1];
835
2/2
✓ Branch 1 taken 3678 times.
✓ Branch 2 taken 685 times.
4363 if (pu_is_intra(pu))
836 3678 unique_list_intramode_add(&ipm_cand, s->blk_info[blk_pos - 1 - (sub & 1)].imode);
837 }
838
839
2/2
✓ Branch 0 taken 3011 times.
✓ Branch 1 taken 1436 times.
4447 tl_x = !(sub & 2) ? (cu->xpos + (sub & 1) * 4) : cu->xpos;
840 4447 tl_y = cu->ypos + (sub & 2) * 4;
841
4/4
✓ Branch 0 taken 4374 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 4299 times.
✓ Branch 3 taken 75 times.
4447 if (tl_x > 0 && tl_y > 0) {
842 const PUInfo * pu;
843
3/3
✓ Branch 0 taken 2190 times.
✓ Branch 1 taken 695 times.
✓ Branch 2 taken 1414 times.
4299 switch (sub) {
844 2190 case 0: pu = &s->pu_info[cu->pu_pos - s->pu_stride - 1]; break;
845 695 case 1: pu = &s->pu_info[cu->pu_pos - s->pu_stride]; break;
846 1414 default: pu = &s->pu_info[cu->pu_pos - 1];
847 }
848
2/2
✓ Branch 1 taken 3616 times.
✓ Branch 2 taken 683 times.
4299 if (pu_is_intra(pu)) {
849
2/2
✓ Branch 0 taken 3046 times.
✓ Branch 1 taken 570 times.
3616 if (sub != 3)
850 3046 unique_list_intramode_add(&ipm_cand, s->blk_info[blk_pos - s->blk_stride - 1].imode);
851 else
852 570 unique_list_intramode_add(&ipm_cand, s->blk_info[blk_pos - s->blk_stride - 2].imode);
853 }
854 }
855
856
2/2
✓ Branch 0 taken 26682 times.
✓ Branch 1 taken 4447 times.
31129 for (int i = 0; i < FF_ARRAY_ELEMS(rv60_candidate_intra_angles); i++)
857 26682 unique_list_intramode_add(&ipm_cand, rv60_candidate_intra_angles[i]);
858
859
2/2
✓ Branch 0 taken 3922 times.
✓ Branch 1 taken 525 times.
4447 if (cu->imode[sub] == INTRAMODE_INDEX)
860 3922 return ipm_cand.list[cu->imode_param[sub]];
861
862
1/2
✓ Branch 0 taken 525 times.
✗ Branch 1 not taken.
525 if (cu->imode[sub] == INTRAMODE_MODE) {
863 525 enum IntraMode imode = cu->imode_param[sub];
864 525 qsort(ipm_cand.list, 3, sizeof(ipm_cand.list[0]), ipm_compar);
865
2/2
✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 525 times.
2100 for (int i = 0; i < 3; i++)
866
2/2
✓ Branch 0 taken 1175 times.
✓ Branch 1 taken 400 times.
1575 if (imode >= ipm_cand.list[i])
867 1175 imode++;
868 525 return imode;
869 }
870
871 ✗ av_assert0(0); // should never reach here
872 return 0;
873 }
874
875 1812 static int get_skip_mv_index(enum MVRefEnum mvref)
876 {
877
4/4
✓ Branch 0 taken 287 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1449 times.
1812 switch (mvref) {
878 287 case MVREF_SKIP1: return 1;
879 61 case MVREF_SKIP2: return 2;
880 15 case MVREF_SKIP3: return 3;
881 1449 default: return 0;
882 }
883 }
884
885 10767 static void add_if_valid(unique_list_mvinfo * skip_cand, const MVInfo * mvi)
886 {
887
2/2
✓ Branch 0 taken 8846 times.
✓ Branch 1 taken 1921 times.
10767 if (mvi->mvref != MVREF_NONE)
888 8846 unique_list_mvinfo_add(skip_cand, *mvi);
889 10767 }
890
891 1812 static void fill_mv_skip_cand(RV60Context * s, const CUContext * cu, unique_list_mvinfo * skip_cand, int size)
892 {
893 1812 int mv_size = size >> 2;
894
895
2/2
✓ Branch 0 taken 1649 times.
✓ Branch 1 taken 163 times.
1812 if (cu->xpos)
896 1649 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos - 1].mv);
897
2/2
✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 250 times.
1812 if (cu->ypos)
898 1562 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos - s->blk_stride].mv);
899
4/4
✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 250 times.
✓ Branch 2 taken 1418 times.
✓ Branch 3 taken 144 times.
1812 if (cu->ypos && cu->xpos + size < s->awidth)
900 1418 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos - s->blk_stride + mv_size].mv);
901
4/4
✓ Branch 0 taken 1649 times.
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 1503 times.
✓ Branch 3 taken 146 times.
1812 if (cu->xpos && cu->ypos + size < s->aheight)
902 1503 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos + s->blk_stride * mv_size - 1].mv);
903
2/2
✓ Branch 0 taken 1649 times.
✓ Branch 1 taken 163 times.
1812 if (cu->xpos)
904 1649 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos + s->blk_stride * (mv_size - 1) - 1].mv);
905
2/2
✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 250 times.
1812 if (cu->ypos)
906 1562 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos - s->blk_stride + mv_size - 1].mv);
907
4/4
✓ Branch 0 taken 1649 times.
✓ Branch 1 taken 163 times.
✓ Branch 2 taken 1424 times.
✓ Branch 3 taken 225 times.
1812 if (cu->xpos && cu->ypos)
908 1424 add_if_valid(skip_cand, &s->blk_info[cu->blk_pos - s->blk_stride - 1].mv);
909
910
2/2
✓ Branch 0 taken 3882 times.
✓ Branch 1 taken 1812 times.
5694 for (int i = skip_cand->size; i < 4; i++)
911 3882 skip_cand->list[i] = (MVInfo){.mvref=MVREF_REF0,.f_mv={0,0},.b_mv={0,0}};
912 1812 }
913
914 typedef struct {
915 int w, h;
916 } Dimensions;
917
918 5808 static void get_mv_dimensions(Dimensions * dim, enum PUType pu_type, int part_no, int size)
919 {
920 5808 int mv_size = size >> 2;
921
4/9
✓ Branch 0 taken 2920 times.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 356 times.
✓ Branch 3 taken 2152 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
5808 switch (pu_type) {
922 2920 case PU_FULL:
923 2920 dim->w = dim->h = mv_size;
924 2920 break;
925 380 case PU_N2HOR:
926 380 dim->w = mv_size;
927 380 dim->h = mv_size >> 1;
928 380 break;
929 356 case PU_N2VER:
930 356 dim->w = mv_size >> 1;
931 356 dim->h = mv_size;
932 356 break;
933 2152 case PU_QUARTERS:
934 2152 dim->w = dim->h = mv_size >> 1;
935 2152 break;
936 ✗ case PU_N4HOR:
937 ✗ dim->w = mv_size;
938 ✗ dim->h = !part_no ? (mv_size >> 2) : ((3 * mv_size) >> 2);
939 ✗ break;
940 ✗ case PU_N34HOR:
941 ✗ dim->w = mv_size;
942 ✗ dim->h = !part_no ? ((3 * mv_size) >> 2) : (mv_size >> 2);
943 ✗ break;
944 ✗ case PU_N4VER:
945 ✗ dim->w = !part_no ? (mv_size >> 2) : ((3 * mv_size) >> 2);
946 ✗ dim->h = mv_size;
947 ✗ break;
948 ✗ case PU_N34VER:
949 ✗ dim->w = !part_no ? ((3 * mv_size) >> 2) : (mv_size >> 2);
950 ✗ dim->h = mv_size;
951 ✗ break;
952 }
953 5808 }
954
955 3656 static int has_hor_split(enum PUType pu_type)
956 {
957
5/8
✓ Branch 0 taken 3276 times.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 3276 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3276 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3276 times.
3656 return pu_type == PU_N2HOR || pu_type == PU_N4HOR || pu_type == PU_N34HOR || pu_type == PU_QUARTERS;
958 }
959
960 3276 static int has_ver_split(enum PUType pu_type)
961 {
962
5/8
✓ Branch 0 taken 2920 times.
✓ Branch 1 taken 356 times.
✓ Branch 2 taken 2920 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2920 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2920 times.
3276 return pu_type == PU_N2VER || pu_type == PU_N4VER || pu_type == PU_N34VER || pu_type == PU_QUARTERS;
963 }
964
965 4833 static int pu_type_num_parts(enum PUType pu_type)
966 {
967
3/3
✓ Branch 0 taken 3474 times.
✓ Branch 1 taken 807 times.
✓ Branch 2 taken 552 times.
4833 switch (pu_type) {
968 3474 case PU_FULL: return 1;
969 807 case PU_QUARTERS: return 4;
970 552 default: return 2;
971 }
972 }
973
974 5808 static void get_next_mv(const RV60Context * s, const Dimensions * dim, enum PUType pu_type, int part_no, int * mv_pos, int * mv_x, int * mv_y)
975 {
976
2/2
✓ Branch 0 taken 2152 times.
✓ Branch 1 taken 3656 times.
5808 if (pu_type == PU_QUARTERS) {
977
2/2
✓ Branch 0 taken 1614 times.
✓ Branch 1 taken 538 times.
2152 if (part_no != 1) {
978 1614 *mv_pos += dim->w;
979 1614 *mv_x += dim->w;
980 } else {
981 538 *mv_pos += dim->h*s->blk_stride - dim->w;
982 538 *mv_x -= dim->w;
983 538 *mv_y += dim->h;
984 }
985
2/2
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 3276 times.
3656 } else if (has_hor_split(pu_type)) {
986 380 *mv_pos += dim->h * s->blk_stride;
987 380 *mv_y += dim->h;
988
2/2
✓ Branch 1 taken 356 times.
✓ Branch 2 taken 2920 times.
3276 } else if (has_ver_split(pu_type)) {
989 356 *mv_pos += dim->w;
990 356 *mv_x += dim->w;
991 }
992 5808 }
993
994 2915 static int mv_is_ref0(enum MVRefEnum mvref)
995 {
996
4/4
✓ Branch 0 taken 2314 times.
✓ Branch 1 taken 601 times.
✓ Branch 2 taken 309 times.
✓ Branch 3 taken 2005 times.
2915 return mvref == MVREF_REF0 || mvref == MVREF_REF0ANDBREF;
997 }
998
999 24675 static int mv_is_forward(enum MVRefEnum mvref)
1000 {
1001
6/6
✓ Branch 0 taken 5209 times.
✓ Branch 1 taken 19466 times.
✓ Branch 2 taken 4975 times.
✓ Branch 3 taken 234 times.
✓ Branch 4 taken 1207 times.
✓ Branch 5 taken 3768 times.
24675 return mvref == MVREF_REF0 || mvref == MVREF_REF1 || mvref == MVREF_REF0ANDBREF;
1002 }
1003
1004 27282 static int mv_is_backward(enum MVRefEnum mvref)
1005 {
1006
4/4
✓ Branch 0 taken 22417 times.
✓ Branch 1 taken 4865 times.
✓ Branch 2 taken 1686 times.
✓ Branch 3 taken 20731 times.
27282 return mvref == MVREF_BREF || mvref == MVREF_REF0ANDBREF;
1007 }
1008
1009 4408 static int mvinfo_matches_forward(const MVInfo * a, const MVInfo * b)
1010 {
1011
6/6
✓ Branch 0 taken 2314 times.
✓ Branch 1 taken 2094 times.
✓ Branch 3 taken 601 times.
✓ Branch 4 taken 1713 times.
✓ Branch 6 taken 309 times.
✓ Branch 7 taken 292 times.
4408 return a->mvref == b->mvref || (mv_is_ref0(a->mvref) && mv_is_ref0(b->mvref));
1012 }
1013
1014 1819 static int mvinfo_matches_backward(const MVInfo * a, const MVInfo * b)
1015 {
1016
3/4
✓ Branch 1 taken 788 times.
✓ Branch 2 taken 1031 times.
✓ Branch 4 taken 788 times.
✗ Branch 5 not taken.
1819 return mv_is_backward(a->mvref) && mv_is_backward(b->mvref);
1017 }
1018
1019 24452 static int mvinfo_is_deblock_cand(const MVInfo * a, const MVInfo * b)
1020 {
1021 int diff;
1022
1023
2/2
✓ Branch 0 taken 1775 times.
✓ Branch 1 taken 22677 times.
24452 if (a->mvref != b->mvref)
1024 1775 return 1;
1025
1026 22677 diff = 0;
1027
2/2
✓ Branch 1 taken 19370 times.
✓ Branch 2 taken 3307 times.
22677 if (mv_is_forward(a->mvref)) {
1028 19370 int dx = a->f_mv.x - b->f_mv.x;
1029 19370 int dy = a->f_mv.y - b->f_mv.y;
1030 19370 diff += FFABS(dx) + FFABS(dy);
1031 }
1032
2/2
✓ Branch 1 taken 4331 times.
✓ Branch 2 taken 18346 times.
22677 if (mv_is_backward(a->mvref)) {
1033 4331 int dx = a->b_mv.x - b->b_mv.x;
1034 4331 int dy = a->b_mv.y - b->b_mv.y;
1035 4331 diff += FFABS(dx) + FFABS(dy);
1036 }
1037 22677 return diff > 4;
1038 }
1039
1040 367 static void mv_pred(MV * ret, MV a, MV b, MV c)
1041 {
1042 #define MEDIAN(x) \
1043 if (a.x < b.x) \
1044 if (b.x < c.x) \
1045 ret->x = b.x; \
1046 else \
1047 ret->x = a.x < c.x ? c.x : a.x; \
1048 else \
1049 if (b.x < c.x) \
1050 ret->x = a.x < c.x ? a.x : c.x; \
1051 else \
1052 ret->x = b.x; \
1053
1054
6/6
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 42 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 303 times.
367 MEDIAN(x)
1055
6/6
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 293 times.
367 MEDIAN(y)
1056 367 }
1057
1058 1998 static void predict_mv(const RV60Context * s, MVInfo * dst, int mv_x, int mv_y, int mv_w, const MVInfo * src)
1059 {
1060 1998 int mv_pos = mv_y * s->blk_stride + mv_x;
1061 MV f_mv, b_mv;
1062
1063 1998 dst->mvref = src->mvref;
1064
1065
2/2
✓ Branch 1 taken 1537 times.
✓ Branch 2 taken 461 times.
1998 if (mv_is_forward(src->mvref)) {
1066 1537 MV cand[3] = {0};
1067 1537 int cand_size = 0;
1068
2/2
✓ Branch 0 taken 1426 times.
✓ Branch 1 taken 111 times.
1537 if (mv_x > 0) {
1069 1426 const MVInfo * mv = &s->blk_info[mv_pos - 1].mv;
1070
2/2
✓ Branch 1 taken 906 times.
✓ Branch 2 taken 520 times.
1426 if (mvinfo_matches_forward(mv, src))
1071 906 cand[cand_size++] = mv->f_mv;
1072 }
1073
2/2
✓ Branch 0 taken 1515 times.
✓ Branch 1 taken 22 times.
1537 if (mv_y > 0) {
1074 1515 const MVInfo * mv = &s->blk_info[mv_pos - s->blk_stride].mv;
1075
2/2
✓ Branch 1 taken 936 times.
✓ Branch 2 taken 579 times.
1515 if (mvinfo_matches_forward(mv, src))
1076 936 cand[cand_size++] = mv->f_mv;
1077 }
1078
2/2
✓ Branch 1 taken 1467 times.
✓ Branch 2 taken 70 times.
1537 if (has_top_block(s, mv_x << 2, mv_y << 2, mv_w << 2, 0, 4)) {
1079 1467 const MVInfo * mv = &s->blk_info[mv_pos - s->blk_stride + mv_w].mv;
1080
2/2
✓ Branch 1 taken 561 times.
✓ Branch 2 taken 906 times.
1467 if (mvinfo_matches_forward(mv, src))
1081 561 cand[cand_size++] = mv->f_mv;
1082 }
1083
1084
4/4
✓ Branch 0 taken 481 times.
✓ Branch 1 taken 523 times.
✓ Branch 2 taken 292 times.
✓ Branch 3 taken 241 times.
1537 switch (cand_size) {
1085 481 case 1:
1086 481 f_mv.x = cand[0].x;
1087 481 f_mv.y = cand[0].y;
1088 481 break;
1089 523 case 2:
1090 523 f_mv.x = (cand[0].x + cand[1].x) >> 1;
1091 523 f_mv.y = (cand[0].y + cand[1].y) >> 1;
1092 523 break;
1093 292 case 3:
1094 292 mv_pred(&f_mv, cand[0], cand[1], cand[2]);
1095 292 break;
1096 241 default:
1097 241 f_mv = (MV){0,0};
1098 241 break;
1099 }
1100 } else {
1101 461 f_mv = (MV){0,0};
1102 }
1103
1104 1998 dst->f_mv.x = src->f_mv.x + f_mv.x;
1105 1998 dst->f_mv.y = src->f_mv.y + f_mv.y;
1106
1107
2/2
✓ Branch 1 taken 644 times.
✓ Branch 2 taken 1354 times.
1998 if (mv_is_backward(src->mvref)) {
1108 644 MV cand[3] = {0};
1109 644 int cand_size = 0;
1110
2/2
✓ Branch 0 taken 587 times.
✓ Branch 1 taken 57 times.
644 if (mv_x > 0) {
1111 587 const MVInfo * mv = &s->blk_info[mv_pos - 1].mv;
1112
2/2
✓ Branch 1 taken 296 times.
✓ Branch 2 taken 291 times.
587 if (mvinfo_matches_backward(mv, src))
1113 296 cand[cand_size++] = mv->b_mv;
1114 }
1115
2/2
✓ Branch 0 taken 628 times.
✓ Branch 1 taken 16 times.
644 if (mv_y > 0) {
1116 628 const MVInfo * mv = &s->blk_info[mv_pos - s->blk_stride].mv;
1117
2/2
✓ Branch 1 taken 297 times.
✓ Branch 2 taken 331 times.
628 if (mvinfo_matches_backward(mv, src))
1118 297 cand[cand_size++] = mv->b_mv;
1119 }
1120
2/2
✓ Branch 1 taken 604 times.
✓ Branch 2 taken 40 times.
644 if (has_top_block(s, mv_x << 2, mv_y << 2, mv_w << 2, 0, 4)) {
1121 604 const MVInfo * mv = &s->blk_info[mv_pos - s->blk_stride + mv_w].mv;
1122
2/2
✓ Branch 1 taken 195 times.
✓ Branch 2 taken 409 times.
604 if (mvinfo_matches_backward(mv, src))
1123 195 cand[cand_size++] = mv->b_mv;
1124 }
1125
1126
4/4
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 172 times.
✓ Branch 2 taken 75 times.
✓ Branch 3 taken 178 times.
644 switch (cand_size) {
1127 219 case 1:
1128 219 b_mv.x = cand[0].x;
1129 219 b_mv.y = cand[0].y;
1130 219 break;
1131 172 case 2:
1132 172 b_mv.x = (cand[0].x + cand[1].x) >> 1;
1133 172 b_mv.y = (cand[0].y + cand[1].y) >> 1;
1134 172 break;
1135 75 case 3:
1136 75 mv_pred(&b_mv, cand[0], cand[1], cand[2]);
1137 75 break;
1138 178 default:
1139 178 b_mv = (MV){0,0};
1140 178 break;
1141 }
1142 } else {
1143 1354 b_mv = (MV){0,0};
1144 }
1145
1146 1998 dst->b_mv.x = src->b_mv.x + b_mv.x;
1147 1998 dst->b_mv.y = src->b_mv.y + b_mv.y;
1148 1998 }
1149
1150 5112 static void reconstruct(RV60Context * s, const CUContext * cu, int size)
1151 {
1152 5112 int pu_size = size >> 3;
1153 PUInfo pui;
1154 int imode, mv_x, mv_y, mv_pos, count, mv_size;
1155 unique_list_mvinfo skip_cand;
1156 Dimensions dim;
1157 MVInfo mv;
1158
1159 5112 pui.cu_type = cu->cu_type;
1160 5112 pui.pu_type = cu->pu_type;
1161
1162
4/4
✓ Branch 0 taken 2293 times.
✓ Branch 1 taken 2819 times.
✓ Branch 2 taken 718 times.
✓ Branch 3 taken 1575 times.
5112 if (cu->cu_type == CU_INTRA && cu->pu_type == PU_QUARTERS) {
1163 718 s->pu_info[cu->pu_pos] = pui;
1164
2/2
✓ Branch 0 taken 1436 times.
✓ Branch 1 taken 718 times.
2154 for (int y = 0; y < 2; y++)
1165
2/2
✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 1436 times.
4308 for (int x = 0; x < 2; x++)
1166 2872 s->blk_info[cu->blk_pos + y*s->blk_stride + x].imode =
1167 2872 reconstruct_intra(s, cu, 4, y*2 + x);
1168 718 return;
1169 }
1170
1171
3/3
✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 1007 times.
✓ Branch 2 taken 1812 times.
4394 switch (cu->cu_type) {
1172 1575 case CU_INTRA:
1173 1575 imode = reconstruct_intra(s, cu, size, 0);
1174
2/2
✓ Branch 0 taken 4776 times.
✓ Branch 1 taken 1575 times.
6351 for (int y = 0; y < size >> 2; y++)
1175
2/2
✓ Branch 0 taken 16056 times.
✓ Branch 1 taken 4776 times.
20832 for (int x = 0; x < size >> 2; x++)
1176 16056 s->blk_info[cu->blk_pos + y*s->blk_stride + x].imode = imode;
1177 1575 break;
1178 1007 case CU_INTER_MV:
1179 1007 mv_x = cu->xpos >> 2;
1180 1007 mv_y = cu->ypos >> 2;
1181 1007 mv_pos = cu->blk_pos;
1182 1007 count = pu_type_num_parts(cu->pu_type);
1183
2/2
✓ Branch 0 taken 1998 times.
✓ Branch 1 taken 1007 times.
3005 for (int part_no = 0; part_no < count; part_no++) {
1184 MVInfo mv;
1185 1998 get_mv_dimensions(&dim, cu->pu_type, part_no, size);
1186 1998 predict_mv(s, &mv, mv_x, mv_y, dim.w, &cu->mv[part_no]);
1187
2/2
✓ Branch 0 taken 3456 times.
✓ Branch 1 taken 1998 times.
5454 for (int y = 0; y < dim.h; y++)
1188
2/2
✓ Branch 0 taken 6908 times.
✓ Branch 1 taken 3456 times.
10364 for (int x = 0; x < dim.w; x++)
1189 6908 s->blk_info[mv_pos + y*s->blk_stride + x].mv = mv;
1190 1998 get_next_mv(s, &dim, cu->pu_type, part_no, &mv_pos, &mv_x, &mv_y);
1191 }
1192 1007 break;
1193 1812 default:
1194 1812 unique_list_mvinfo_init(&skip_cand);
1195 1812 fill_mv_skip_cand(s, cu, &skip_cand, size);
1196 1812 mv = skip_cand.list[get_skip_mv_index(cu->mv[0].mvref)];
1197 1812 mv_size = size >> 2;
1198
2/2
✓ Branch 0 taken 7506 times.
✓ Branch 1 taken 1812 times.
9318 for (int y = 0; y < mv_size; y++)
1199
2/2
✓ Branch 0 taken 53700 times.
✓ Branch 1 taken 7506 times.
61206 for (int x = 0; x < mv_size; x++)
1200 53700 s->blk_info[cu->blk_pos + y*s->blk_stride + x].mv = mv;
1201 }
1202
1203
2/2
✓ Branch 0 taken 7372 times.
✓ Branch 1 taken 4394 times.
11766 for (int y = 0; y < pu_size; y++)
1204
2/2
✓ Branch 0 taken 19166 times.
✓ Branch 1 taken 7372 times.
26538 for (int x = 0; x < pu_size; x++)
1205 19166 s->pu_info[cu->pu_pos + y*s->pu_stride + x] = pui;
1206 }
1207
1208 2181 static void read_mv(GetBitContext * gb, MV * mv)
1209 {
1210 2181 mv->x = get_interleaved_se_golomb(gb);
1211 2181 mv->y = get_interleaved_se_golomb(gb);
1212 2181 }
1213
1214 1998 static void read_mv_info(RV60Context *s, GetBitContext * gb, MVInfo * mvinfo, int size, enum PUType pu_type)
1215 {
1216
2/2
✓ Branch 0 taken 866 times.
✓ Branch 1 taken 1132 times.
1998 if (s->pict_type != AV_PICTURE_TYPE_B) {
1217
3/4
✓ Branch 0 taken 866 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 192 times.
✓ Branch 4 taken 674 times.
866 if (s->two_f_refs && get_bits1(gb))
1218 192 mvinfo->mvref = MVREF_REF1;
1219 else
1220 674 mvinfo->mvref = MVREF_REF0;
1221 866 read_mv(gb, &mvinfo->f_mv);
1222 866 mvinfo->b_mv.x = mvinfo->b_mv.y = 0;
1223 } else {
1224
7/8
✓ Branch 0 taken 817 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 817 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 291 times.
✓ Branch 5 taken 526 times.
✓ Branch 7 taken 423 times.
✓ Branch 8 taken 183 times.
1132 if ((size <= 8 && (size != 8 || pu_type != PU_FULL)) || get_bits1(gb)) {
1225
2/2
✓ Branch 1 taken 488 times.
✓ Branch 2 taken 461 times.
1898 if (!get_bits1(gb)) {
1226 488 mvinfo->mvref = MVREF_REF0;
1227 488 read_mv(gb, &mvinfo->f_mv);
1228 488 mvinfo->b_mv.x = mvinfo->b_mv.y = 0;
1229 } else {
1230 461 mvinfo->mvref = MVREF_BREF;
1231 461 mvinfo->f_mv.x = mvinfo->f_mv.y = 0;
1232 461 read_mv(gb, &mvinfo->b_mv);
1233 }
1234 } else {
1235 183 mvinfo->mvref = MVREF_REF0ANDBREF;
1236 183 read_mv(gb, &mvinfo->f_mv);
1237 183 read_mv(gb, &mvinfo->b_mv);
1238 }
1239 }
1240 1998 }
1241
1242 #define FILTER1(src, src_stride, src_y_ofs, step) \
1243 ( (src)[(y + src_y_ofs)*(src_stride) + x - 2*step] \
1244 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x - 1*step] \
1245 +52 * (src)[(y + src_y_ofs)*(src_stride) + x ] \
1246 +20 * (src)[(y + src_y_ofs)*(src_stride) + x + 1*step] \
1247 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x + 2*step] \
1248 + (src)[(y + src_y_ofs)*(src_stride) + x + 3*step] + 32) >> 6
1249
1250 #define FILTER2(src, src_stride, src_y_ofs, step) \
1251 ( (src)[(y + src_y_ofs)*(src_stride) + x - 2*step] \
1252 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x - 1*step] \
1253 +20 * (src)[(y + src_y_ofs)*(src_stride) + x ] \
1254 +20 * (src)[(y + src_y_ofs)*(src_stride) + x + 1*step] \
1255 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x + 2*step] \
1256 + (src)[(y + src_y_ofs)*(src_stride) + x + 3*step] + 16) >> 5
1257
1258 #define FILTER3(src, src_stride, src_y_ofs, step) \
1259 ( (src)[(y + src_y_ofs)*(src_stride) + x - 2*step] \
1260 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x - 1*step] \
1261 +20 * (src)[(y + src_y_ofs)*(src_stride) + x ] \
1262 +52 * (src)[(y + src_y_ofs)*(src_stride) + x + 1*step] \
1263 - 5 * (src)[(y + src_y_ofs)*(src_stride) + x + 2*step] \
1264 + (src)[(y + src_y_ofs)*(src_stride) + x + 3*step] + 32) >> 6
1265
1266 #define FILTER_CASE(idx, dst, dst_stride, filter, w, h) \
1267 case idx: \
1268 for (int y = 0; y < h; y++) \
1269 for (int x = 0; x < w; x++) \
1270 (dst)[y*dst_stride + x] = av_clip_uint8(filter); \
1271 break;
1272
1273 #define FILTER_BLOCK(dst, dst_stride, src, src_stride, src_y_ofs, w, h, cond, step) \
1274 switch (cond) { \
1275 FILTER_CASE(1, dst, dst_stride, FILTER1(src, src_stride, src_y_ofs, step), w, h) \
1276 FILTER_CASE(2, dst, dst_stride, FILTER2(src, src_stride, src_y_ofs, step), w, h) \
1277 FILTER_CASE(3, dst, dst_stride, FILTER3(src, src_stride, src_y_ofs, step), w, h) \
1278 }
1279
1280 4117 static void luma_mc(uint8_t * dst, int dst_stride, const uint8_t * src, int src_stride, int w, int h, int cx, int cy)
1281 {
1282
2/4
✓ Branch 0 taken 4117 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4117 times.
✗ Branch 3 not taken.
4117 if (!cx && !cy) {
1283
2/2
✓ Branch 0 taken 47344 times.
✓ Branch 1 taken 4117 times.
51461 for (int y = 0; y < h; y++)
1284 47344 memcpy(dst + y*dst_stride, src + y*src_stride, w);
1285 ✗ } else if (!cy) {
1286 ✗ FILTER_BLOCK(dst, dst_stride, src, src_stride, 0, w, h, cx, 1)
1287 ✗ } else if (!cx) {
1288 ✗ FILTER_BLOCK(dst, dst_stride, src, src_stride, 0, w, h, cy, src_stride)
1289 ✗ } else if (cx != 3 || cy != 3) {
1290 uint8_t tmp[70 * 64];
1291 ✗ FILTER_BLOCK(tmp, 64, src - src_stride * 2, src_stride, 0, w, h + 5, cx, 1)
1292 ✗ FILTER_BLOCK(dst, dst_stride, tmp + 2*64, 64, 0, w, h, cy, 64)
1293 } else {
1294 ✗ for (int j = 0; j < h; j++)
1295 ✗ for (int i = 0; i < w; i++)
1296 ✗ dst[j*dst_stride + i] = (
1297 ✗ src[j*src_stride + i] +
1298 ✗ src[j*src_stride + i + 1] +
1299 ✗ src[(j + 1)*src_stride + i] +
1300 ✗ src[(j + 1)*src_stride + i + 1] + 2) >> 2;
1301 }
1302 4117 }
1303
1304 8234 static void chroma_mc(uint8_t * dst, int dst_stride, const uint8_t * src, int src_stride, int w, int h, int x, int y)
1305 {
1306
4/4
✓ Branch 0 taken 7822 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 7440 times.
✓ Branch 3 taken 382 times.
8234 if (!x && !y) {
1307
2/2
✓ Branch 0 taken 44208 times.
✓ Branch 1 taken 7440 times.
51648 for (int j = 0; j < h; j++)
1308 44208 memcpy(dst + j*dst_stride, src + j*src_stride, w);
1309
4/4
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 382 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 330 times.
876 } else if (x > 0 && y > 0) {
1310 int a, b, c, d;
1311
1312
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
82 if (x == 3 && y == 3)
1313 ✗ y = 2; //reproduce bug in rv60 decoder. tested with realplayer version 18.1.7.344 and 22.0.0.321
1314
1315 82 a = (4 - x) * (4 - y);
1316 82 b = x * (4 - y);
1317 82 c = (4 - x) * y;
1318 82 d = x * y;
1319
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 82 times.
382 for (int j = 0; j < h; j++)
1320
2/2
✓ Branch 0 taken 1104 times.
✓ Branch 1 taken 300 times.
1404 for (int i = 0; i < w; i++)
1321 1104 dst[j*dst_stride + i] =
1322 1104 (a * src[j*src_stride + i] +
1323 1104 b * src[j*src_stride + i + 1] +
1324 1104 c * src[(j + 1)*src_stride + i] +
1325 1104 d * src[(j + 1)*src_stride + i + 1] + 8) >> 4;
1326 } else {
1327 712 int a = (4 - x) * (4 - y);
1328 712 int e = x * (4 - y) + (4 - x) * y;
1329
2/2
✓ Branch 0 taken 382 times.
✓ Branch 1 taken 330 times.
712 int step = y > 0 ? src_stride : 1;
1330
2/2
✓ Branch 0 taken 2836 times.
✓ Branch 1 taken 712 times.
3548 for (int j = 0; j < h; j++)
1331
2/2
✓ Branch 0 taken 14512 times.
✓ Branch 1 taken 2836 times.
17348 for (int i = 0; i < w; i++)
1332 14512 dst[j*dst_stride + i] =
1333 14512 (a * src[j*src_stride + i] +
1334 14512 e * src[j*src_stride + i + step] + 8) >> 4;
1335 }
1336 8234 }
1337
1338 12351 static int check_pos(int x, int y, int cw, int ch, int w, int h, int dx, int dy, int e0, int e1, int e2, int e3)
1339 {
1340 12351 int x2 = x + dx;
1341 12351 int y2 = y + dy;
1342
7/8
✓ Branch 0 taken 12318 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 11770 times.
✓ Branch 3 taken 548 times.
✓ Branch 4 taken 11770 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11351 times.
✓ Branch 7 taken 419 times.
12351 return x2 - e0 >= 0 && x2 + cw + e1 <= w && y2 - e2 >= 0 && y2 + ch + e3 <= h;
1343 }
1344
1345 4117 static void mc(RV60Context * s, uint8_t * frame_data[3], int frame_linesize[3], const AVFrame * ref, int x, int y, int w, int h, MV mv, int avg)
1346 {
1347 {
1348
2/2
✓ Branch 0 taken 3810 times.
✓ Branch 1 taken 307 times.
4117 int off = !avg ? y * frame_linesize[0] + x : 0;
1349 4117 int fw = s->awidth;
1350 4117 int fh = s->aheight;
1351 4117 int dx = mv.x >> 2;
1352 4117 int cx = mv.x & 3;
1353 4117 int dy = mv.y >> 2;
1354 4117 int cy = mv.y & 3;
1355
1356
2/2
✓ Branch 1 taken 4041 times.
✓ Branch 2 taken 76 times.
4117 if (check_pos(x, y, w, h, fw, fh, dx, dy, rv60_edge1[cx], rv60_edge2[cx], rv60_edge1[cy], rv60_edge2[cy])) {
1357 4041 luma_mc(
1358 4041 frame_data[0] + off,
1359 frame_linesize[0],
1360 4041 ref->data[0] + (y + dy) * ref->linesize[0] + x + dx,
1361 4041 ref->linesize[0],
1362 w, h, cx, cy);
1363 } else {
1364 uint8_t buf[70*70];
1365 76 int xoff = x + dx - 2;
1366 76 int yoff = y + dy - 2;
1367 76 s->vdsp.emulated_edge_mc(buf,
1368 76 ref->data[0] + yoff * ref->linesize[0] + xoff,
1369 76 70, ref->linesize[0],
1370 w + 5, h + 5,
1371 xoff, yoff,
1372 fw, fh);
1373
1374 76 luma_mc(frame_data[0] + off, frame_linesize[0],
1375 buf + 70 * 2 + 2, 70, w, h, cx, cy);
1376 }
1377 }
1378 {
1379 4117 int fw = s->awidth >> 1;
1380 4117 int fh = s->aheight >> 1;
1381 4117 int mvx = mv.x / 2;
1382 4117 int mvy = mv.y / 2;
1383 4117 int dx = mvx >> 2;
1384 4117 int cx = mvx & 3;
1385 4117 int dy = mvy >> 2;
1386 4117 int cy = mvy & 3;
1387 4117 int cw = w >> 1;
1388 4117 int ch = h >> 1;
1389
1390
2/2
✓ Branch 0 taken 8234 times.
✓ Branch 1 taken 4117 times.
12351 for (int plane = 1; plane < 3; plane++) {
1391
2/2
✓ Branch 0 taken 7620 times.
✓ Branch 1 taken 614 times.
8234 int off = !avg ? (y >> 1) * frame_linesize[plane] + (x >> 1) : 0;
1392
2/2
✓ Branch 1 taken 7310 times.
✓ Branch 2 taken 924 times.
8234 if (check_pos(x >> 1, y >> 1, cw, ch, fw, fh, dx, dy, 0, 1, 0, 1)) {
1393 7310 chroma_mc(
1394 7310 frame_data[plane] + off,
1395 7310 frame_linesize[plane],
1396 7310 ref->data[plane] + ((y >> 1) + dy) * ref->linesize[plane] + (x >> 1) + dx,
1397 7310 ref->linesize[plane],
1398 cw, ch, cx, cy);
1399 } else {
1400 uint8_t buf[40*40];
1401 924 s->vdsp.emulated_edge_mc(buf,
1402 924 ref->data[plane] + ((y >> 1) + dy) * ref->linesize[plane] + (x >> 1) + dx,
1403 924 40, ref->linesize[plane],
1404 cw + 1, ch + 1,
1405 924 (x >> 1) + dx, (y >> 1) + dy,
1406 fw, fh);
1407 924 chroma_mc(frame_data[plane] + off, frame_linesize[plane], buf, 40, cw, ch, cx, cy);
1408 }
1409 }
1410 }
1411 4117 }
1412
1413 921 static void avg_plane(uint8_t * dst, int dst_stride, const uint8_t * src, int src_stride, int w, int h)
1414 {
1415
2/2
✓ Branch 0 taken 6992 times.
✓ Branch 1 taken 921 times.
7913 for (int j = 0; j < h; j++)
1416
2/2
✓ Branch 0 taken 94944 times.
✓ Branch 1 taken 6992 times.
101936 for (int i = 0; i < w; i++)
1417 94944 dst[j*dst_stride + i] = (dst[j*dst_stride + i] + src[j*src_stride + i]) >> 1;
1418 921 }
1419
1420 307 static void avg(AVFrame * frame, uint8_t * prev_frame_data[3], int prev_frame_linesize[3], int x, int y, int w, int h)
1421 {
1422
2/2
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 307 times.
1228 for (int plane = 0; plane < 3; plane++) {
1423 921 int shift = !plane ? 0 : 1;
1424 921 avg_plane(frame->data[plane] + (y >> shift) * frame->linesize[plane] + (x >> shift), frame->linesize[plane],
1425 921 prev_frame_data[plane], prev_frame_linesize[plane],
1426 w >> shift, h >> shift);
1427 }
1428 307 }
1429
1430 2253 static int get_c4x4_set(int qp, int is_intra)
1431 {
1432
2/2
✓ Branch 0 taken 1166 times.
✓ Branch 1 taken 1087 times.
2253 if (is_intra)
1433 1166 return rv60_qp_to_idx[qp + 32];
1434 else
1435 1087 return rv60_qp_to_idx[qp];
1436 }
1437
1438 137688 static int quant(int v, int q)
1439 {
1440 137688 return (v * q + 8) >> 4;
1441 }
1442
1443 137688 static int decode_coeff(GetBitContext * gb, const CoeffVLCs * vlcs, int inval, int val)
1444 {
1445 int esc_sym;
1446
1447
2/2
✓ Branch 0 taken 73186 times.
✓ Branch 1 taken 64502 times.
137688 if (inval != val)
1448
4/4
✓ Branch 0 taken 30539 times.
✓ Branch 1 taken 42647 times.
✓ Branch 3 taken 15512 times.
✓ Branch 4 taken 15027 times.
73186 return inval && get_bits1(gb) ? -inval : inval;
1449
1450 64502 esc_sym = get_vlc2(gb, vlcs->esc, 9, 2);
1451
2/2
✓ Branch 0 taken 2214 times.
✓ Branch 1 taken 62288 times.
64502 if (esc_sym > 23) {
1452 2214 int esc_bits = esc_sym - 23;
1453 2214 val += (1 << esc_bits) + get_bits(gb, esc_bits) + 22;
1454 } else
1455 62288 val += esc_sym;
1456
1457
2/2
✓ Branch 1 taken 32044 times.
✓ Branch 2 taken 32458 times.
64502 return get_bits1(gb) ? -val : val;
1458 }
1459
1460 4396 static void decode_2x2_dc(GetBitContext * gb, const CoeffVLCs * vlcs, int16_t * coeffs, int stride, int block2, int dsc, int q_dc, int q_ac)
1461 {
1462 const uint8_t * lx;
1463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4396 times.
4396 if (!dsc)
1464 ✗ return;
1465
1466 4396 lx = rv60_dsc_to_lx[dsc - 1];
1467
1468 4396 coeffs[0] = quant(decode_coeff(gb, vlcs, lx[0], 3), q_dc);
1469
1/2
✓ Branch 0 taken 4396 times.
✗ Branch 1 not taken.
4396 if (!block2) {
1470 4396 coeffs[1] = quant(decode_coeff(gb, vlcs, lx[1], 2), q_ac);
1471 4396 coeffs[stride] = quant(decode_coeff(gb, vlcs, lx[2], 2), q_ac);
1472 } else {
1473 ✗ coeffs[stride] = quant(decode_coeff(gb, vlcs, lx[1], 2), q_ac);
1474 ✗ coeffs[1] = quant(decode_coeff(gb, vlcs, lx[2], 2), q_ac);
1475 }
1476 4396 coeffs[stride + 1] = quant(decode_coeff(gb, vlcs, lx[3], 2), q_ac);
1477 }
1478
1479 30026 static void decode_2x2(GetBitContext * gb, const CoeffVLCs * vlcs, int16_t * coeffs, int stride, int block2, int dsc, int q_ac)
1480 {
1481 const uint8_t * lx;
1482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30026 times.
30026 if (!dsc)
1483 ✗ return;
1484
1485 30026 lx = rv60_dsc_to_lx[dsc - 1];
1486
1487 30026 coeffs[0] = quant(decode_coeff(gb, vlcs, lx[0], 3), q_ac);
1488
2/2
✓ Branch 0 taken 22293 times.
✓ Branch 1 taken 7733 times.
30026 if (!block2) {
1489 22293 coeffs[1] = quant(decode_coeff(gb, vlcs, lx[1], 2), q_ac);
1490 22293 coeffs[stride] = quant(decode_coeff(gb, vlcs, lx[2], 2), q_ac);
1491 } else {
1492 7733 coeffs[stride] = quant(decode_coeff(gb, vlcs, lx[1], 2), q_ac);
1493 7733 coeffs[1] = quant(decode_coeff(gb, vlcs, lx[2], 2), q_ac);
1494 }
1495 30026 coeffs[stride + 1] = quant(decode_coeff(gb, vlcs, lx[3], 2), q_ac);
1496 }
1497
1498 4548 static void decode_4x4_block_dc(GetBitContext * gb, const CoeffVLCs * vlcs, int is_luma, int16_t * coeffs, int stride, int q_dc, int q_ac)
1499 {
1500 4548 int sym0 = get_vlc2(gb, vlcs->l0[!is_luma], 9, 2);
1501 4548 int grp0 = sym0 >> 3;
1502
1503
2/2
✓ Branch 0 taken 4396 times.
✓ Branch 1 taken 152 times.
4548 if (grp0)
1504 4396 decode_2x2_dc(gb, vlcs, coeffs, stride, 0, grp0, q_dc, q_ac);
1505
1506
2/2
✓ Branch 0 taken 3242 times.
✓ Branch 1 taken 1306 times.
4548 if (sym0 & 4) {
1507 3242 int grp = get_vlc2(gb, vlcs->l12[!is_luma], 9, 2);
1508 3242 decode_2x2(gb, vlcs, coeffs + 2, stride, 0, grp, q_ac);
1509 }
1510
2/2
✓ Branch 0 taken 2779 times.
✓ Branch 1 taken 1769 times.
4548 if (sym0 & 2) {
1511 2779 int grp = get_vlc2(gb, vlcs->l12[!is_luma], 9, 2);
1512 2779 decode_2x2(gb, vlcs, coeffs + 2*stride, stride, 1, grp, q_ac);
1513 }
1514
2/2
✓ Branch 0 taken 2478 times.
✓ Branch 1 taken 2070 times.
4548 if (sym0 & 1) {
1515 2478 int grp = get_vlc2(gb, vlcs->l3[!is_luma], 9, 2);
1516 2478 decode_2x2(gb, vlcs, coeffs + 2*stride + 2, stride, 0, grp, q_ac);
1517 }
1518 4548 }
1519
1520 7219 static void decode_4x4_block(GetBitContext * gb, const CoeffVLCs * vlcs, int is_luma, int16_t * coeffs, int stride, int q_ac)
1521 {
1522 7219 int sym0 = get_vlc2(gb, vlcs->l0[!is_luma], 9, 2);
1523 7219 int grp0 = (sym0 >> 3);
1524
1525
2/2
✓ Branch 0 taken 6761 times.
✓ Branch 1 taken 458 times.
7219 if (grp0)
1526 6761 decode_2x2(gb, vlcs, coeffs, stride, 0, grp0, q_ac);
1527
1528
2/2
✓ Branch 0 taken 5569 times.
✓ Branch 1 taken 1650 times.
7219 if (sym0 & 4) {
1529 5569 int grp = get_vlc2(gb, vlcs->l12[!is_luma], 9, 2);
1530 5569 decode_2x2(gb, vlcs, coeffs + 2, stride, 0, grp, q_ac);
1531 }
1532
2/2
✓ Branch 0 taken 4954 times.
✓ Branch 1 taken 2265 times.
7219 if (sym0 & 2) {
1533 4954 int grp = get_vlc2(gb, vlcs->l12[!is_luma], 9, 2);
1534 4954 decode_2x2(gb, vlcs, coeffs + 2*stride, stride, 1, grp, q_ac);
1535 }
1536
2/2
✓ Branch 0 taken 4243 times.
✓ Branch 1 taken 2976 times.
7219 if (sym0 & 1) {
1537 4243 int grp = get_vlc2(gb, vlcs->l3[!is_luma], 9, 2);
1538 4243 decode_2x2(gb, vlcs, coeffs + 2*stride + 2, stride, 0, grp, q_ac);
1539 }
1540 7219 }
1541
1542 139 static void decode_cu_4x4in16x16(GetBitContext * gb, int is_intra, int qp, int sel_qp, int16_t * y_coeffs, int16_t * u_coeffs, int16_t * v_coeffs, int cbp)
1543 {
1544 139 int cb_set = get_c4x4_set(sel_qp, is_intra);
1545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 const CoeffVLCs * vlc = is_intra ? &intra_coeff_vlc[cb_set] : &inter_coeff_vlc[cb_set];
1546 139 int q_y = rv60_quants_b[qp];
1547 139 int q_c_dc = rv60_quants_b[rv60_chroma_quant_dc[qp]];
1548 139 int q_c_ac = rv60_quants_b[rv60_chroma_quant_ac[qp]];
1549
1550 139 memset(y_coeffs, 0, sizeof(y_coeffs[0])*256);
1551
2/2
✓ Branch 0 taken 2224 times.
✓ Branch 1 taken 139 times.
2363 for (int i = 0; i < 16; i++)
1552
2/2
✓ Branch 0 taken 979 times.
✓ Branch 1 taken 1245 times.
2224 if ((cbp >> i) & 1)
1553 979 decode_4x4_block(gb, vlc, 1, y_coeffs + i * 16 , 4, q_y);
1554
1555 139 memset(u_coeffs, 0, sizeof(u_coeffs[0])*64);
1556
2/2
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 139 times.
695 for (int i = 0; i < 4; i++)
1557
2/2
✓ Branch 0 taken 341 times.
✓ Branch 1 taken 215 times.
556 if ((cbp >> (16 + i)) & 1)
1558 341 decode_4x4_block_dc(gb, vlc, 0, u_coeffs + i * 16, 4, q_c_dc, q_c_ac);
1559
1560 139 memset(v_coeffs, 0, sizeof(v_coeffs[0])*64);
1561
2/2
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 139 times.
695 for (int i = 0; i < 4; i++)
1562
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 221 times.
556 if ((cbp >> (20 + i)) & 1)
1563 335 decode_4x4_block_dc(gb, vlc, 0, v_coeffs + i * 16, 4, q_c_dc, q_c_ac);
1564 139 }
1565
1566 2387 static int decode_cbp8(GetBitContext * gb, int subset, int qp)
1567 {
1568 2387 int cb_set = rv60_qp_to_idx[qp];
1569 2387 return get_vlc2(gb, cbp8_vlc[cb_set][subset], 9, 2);
1570 }
1571
1572 1901 static void decode_cu_8x8(GetBitContext * gb, int is_intra, int qp, int sel_qp, int16_t * y_coeffs, int16_t * u_coeffs, int16_t * v_coeffs, int ccbp, int mode4x4)
1573 {
1574 1901 int cb_set = get_c4x4_set(sel_qp, is_intra);
1575
2/2
✓ Branch 0 taken 1070 times.
✓ Branch 1 taken 831 times.
1901 const CoeffVLCs * vlc = is_intra ? &intra_coeff_vlc[cb_set] : &inter_coeff_vlc[cb_set];
1576 1901 int q_y = rv60_quants_b[qp];
1577 1901 int q_c_dc = rv60_quants_b[rv60_chroma_quant_dc[qp]];
1578 1901 int q_c_ac = rv60_quants_b[rv60_chroma_quant_ac[qp]];
1579
1580 1901 memset(y_coeffs, 0, sizeof(y_coeffs[0])*64);
1581
2/2
✓ Branch 0 taken 7604 times.
✓ Branch 1 taken 1901 times.
9505 for (int i = 0; i < 4; i++) {
1582
2/2
✓ Branch 0 taken 4514 times.
✓ Branch 1 taken 3090 times.
7604 if ((ccbp >> i) & 1) {
1583 int offset, stride;
1584
2/2
✓ Branch 0 taken 2468 times.
✓ Branch 1 taken 2046 times.
4514 if (mode4x4) {
1585 2468 offset = i*16;
1586 2468 stride = 4;
1587 } else {
1588 2046 offset = (i & 1) * 4 + (i & 2) * 2 * 8;
1589 2046 stride = 8;
1590 }
1591 4514 decode_4x4_block(gb, vlc, 1, y_coeffs + offset, stride, q_y);
1592 }
1593 }
1594
1595
2/2
✓ Branch 0 taken 1741 times.
✓ Branch 1 taken 160 times.
1901 if ((ccbp >> 4) & 1) {
1596 1741 memset(u_coeffs, 0, sizeof(u_coeffs[0])*16);
1597 1741 decode_4x4_block_dc(gb, vlc, 0, u_coeffs, 4, q_c_dc, q_c_ac);
1598 }
1599
1600
2/2
✓ Branch 0 taken 1778 times.
✓ Branch 1 taken 123 times.
1901 if ((ccbp >> 5) & 1) {
1601 1778 memset(v_coeffs, 0, sizeof(u_coeffs[0])*16);
1602 1778 decode_4x4_block_dc(gb, vlc, 0, v_coeffs, 4, q_c_dc, q_c_ac);
1603 }
1604 1901 }
1605
1606 213 static void decode_cu_16x16(GetBitContext * gb, int is_intra, int qp, int sel_qp, int16_t * y_coeffs, int16_t * u_coeffs, int16_t * v_coeffs, int ccbp)
1607 {
1608 213 int cb_set = get_c4x4_set(sel_qp, is_intra);
1609
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 117 times.
213 const CoeffVLCs * vlc = is_intra ? &intra_coeff_vlc[cb_set] : &inter_coeff_vlc[cb_set];
1610 213 int q_y = rv60_quants_b[qp];
1611 213 int q_c_dc = rv60_quants_b[rv60_chroma_quant_dc[qp]];
1612 213 int q_c_ac = rv60_quants_b[rv60_chroma_quant_ac[qp]];
1613
1614 213 memset(y_coeffs, 0, sizeof(y_coeffs[0])*256);
1615
2/2
✓ Branch 0 taken 3408 times.
✓ Branch 1 taken 213 times.
3621 for (int i = 0; i < 16; i++)
1616
2/2
✓ Branch 0 taken 1230 times.
✓ Branch 1 taken 2178 times.
3408 if ((ccbp >> i) & 1) {
1617 1230 int off = (i & 3) * 4 + (i >> 2) * 4 * 16;
1618 1230 decode_4x4_block(gb, vlc, 1, y_coeffs + off, 16, q_y);
1619 }
1620
1621 213 memset(u_coeffs, 0, sizeof(u_coeffs[0])*64);
1622
2/2
✓ Branch 0 taken 852 times.
✓ Branch 1 taken 213 times.
1065 for (int i = 0; i < 4; i++)
1623
2/2
✓ Branch 0 taken 428 times.
✓ Branch 1 taken 424 times.
852 if ((ccbp >> (16 + i)) & 1) {
1624 428 int off = (i & 1) * 4 + (i & 2) * 2 * 8;
1625
2/2
✓ Branch 0 taken 161 times.
✓ Branch 1 taken 267 times.
428 if (!i)
1626 161 decode_4x4_block_dc(gb, vlc, 0, u_coeffs + off, 8, q_c_dc, q_c_ac);
1627 else
1628 267 decode_4x4_block(gb, vlc, 0, u_coeffs + off, 8, q_c_ac);
1629 }
1630
1631 213 memset(v_coeffs, 0, sizeof(v_coeffs[0])*64);
1632
2/2
✓ Branch 0 taken 852 times.
✓ Branch 1 taken 213 times.
1065 for (int i = 0; i < 4; i++)
1633
2/2
✓ Branch 0 taken 421 times.
✓ Branch 1 taken 431 times.
852 if ((ccbp >> (20 + i)) & 1) {
1634 421 int off = (i & 1) * 4 + (i & 2) * 2 * 8;
1635
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 229 times.
421 if (!i)
1636 192 decode_4x4_block_dc(gb, vlc, 0, v_coeffs + off, 8, q_c_dc, q_c_ac);
1637 else
1638 229 decode_4x4_block(gb, vlc, 0, v_coeffs + off, 8, q_c_ac);
1639 }
1640 213 }
1641
1642 352 static int decode_super_cbp(GetBitContext * gb, const VLCElem * vlc[4])
1643 {
1644 352 int sym0 = get_vlc2(gb, vlc[0], 9, 2);
1645 352 int sym1 = get_vlc2(gb, vlc[1], 9, 2);
1646 352 int sym2 = get_vlc2(gb, vlc[2], 9, 2);
1647 352 int sym3 = get_vlc2(gb, vlc[3], 9, 2);
1648 return 0
1649 352 + ((sym0 & 0x03) << 0)
1650 352 + ((sym0 & 0x0C) << 2)
1651 352 + ((sym0 & 0x10) << 12)
1652 352 + ((sym0 & 0x20) << 15)
1653 352 + ((sym1 & 0x03) << 2)
1654 352 + ((sym1 & 0x0C) << 4)
1655 352 + ((sym1 & 0x10) << 13)
1656 352 + ((sym1 & 0x20) << 16)
1657 352 + ((sym2 & 0x03) << 8)
1658 352 + ((sym2 & 0x0C) << 10)
1659 352 + ((sym2 & 0x10) << 14)
1660 352 + ((sym2 & 0x20) << 17)
1661 352 + ((sym3 & 0x03) << 10)
1662 352 + ((sym3 & 0x0C) << 12)
1663 352 + ((sym3 & 0x10) << 15)
1664 352 + ((sym3 & 0x20) << 18);
1665 }
1666
1667 352 static int decode_cbp16(GetBitContext * gb, int subset, int qp)
1668 {
1669 352 int cb_set = rv60_qp_to_idx[qp];
1670 352 return decode_super_cbp(gb, cbp16_vlc[cb_set][subset]);
1671 }
1672
1673 7524 static int decode_cu_r(RV60Context * s, AVFrame * frame, ThreadContext * thread, GetBitContext * gb, int xpos, int ypos, int log_size, int qp, int sel_qp)
1674 {
1675 7524 int size = 1 << log_size;
1676 int split, ret, ttype, count, is_intra, cu_pos, subset, cbp8, imode, split_i4x4, num_clusters, cl_cbp, super_cbp, mv_x, mv_y, mv_pos;
1677 int16_t y_coeffs[16*16], u_coeffs[8*8], v_coeffs[8*8];
1678 CUContext cu;
1679
1680
4/4
✓ Branch 0 taken 7174 times.
✓ Branch 1 taken 350 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 6894 times.
7524 if (xpos >= s->awidth || ypos >= s->aheight)
1681 630 return 0;
1682
1683
8/8
✓ Branch 0 taken 6719 times.
✓ Branch 1 taken 175 times.
✓ Branch 2 taken 6614 times.
✓ Branch 3 taken 105 times.
✓ Branch 4 taken 3462 times.
✓ Branch 5 taken 3152 times.
✓ Branch 7 taken 1502 times.
✓ Branch 8 taken 1960 times.
6894 split = xpos + size > s->awidth || ypos + size > s->aheight || (size > 8 && get_bits1(gb));
1684 6894 thread->cu_split[thread->cu_split_pos++] = split;
1685
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 5112 times.
6894 if (split) {
1686 1782 size >>= 1;
1687 1782 log_size -= 1;
1688
2/4
✓ Branch 1 taken 1782 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1782 times.
✗ Branch 4 not taken.
3564 if ((ret = decode_cu_r(s, frame, thread, gb, xpos, ypos, log_size, qp, sel_qp)) < 0 ||
1689
1/2
✓ Branch 1 taken 1782 times.
✗ Branch 2 not taken.
3564 (ret = decode_cu_r(s, frame, thread, gb, xpos + size, ypos, log_size, qp, sel_qp)) < 0 ||
1690
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1782 times.
3564 (ret = decode_cu_r(s, frame, thread, gb, xpos, ypos + size, log_size, qp, sel_qp)) < 0 ||
1691 1782 (ret = decode_cu_r(s, frame, thread, gb, xpos + size, ypos + size, log_size, qp, sel_qp)) < 0)
1692 ✗ return ret;
1693 1782 return 0;
1694 }
1695
1696 5112 cu.xpos = xpos;
1697 5112 cu.ypos = ypos;
1698 5112 cu.pu_pos = (xpos >> 3) + (ypos >> 3) * s->pu_stride;
1699 5112 cu.blk_pos = (xpos >> 2) + (ypos >> 2) * s->blk_stride;
1700
2/2
✓ Branch 0 taken 3163 times.
✓ Branch 1 taken 1949 times.
5112 cu.cu_type = s->pict_type != AV_PICTURE_TYPE_I ? get_bits(gb, 2) : CU_INTRA;
1701
1702
3/3
✓ Branch 0 taken 2293 times.
✓ Branch 1 taken 1007 times.
✓ Branch 2 taken 1812 times.
5112 switch (cu.cu_type) {
1703 2293 case CU_INTRA:
1704
4/4
✓ Branch 0 taken 1480 times.
✓ Branch 1 taken 813 times.
✓ Branch 3 taken 718 times.
✓ Branch 4 taken 762 times.
2293 cu.pu_type = size == 8 && get_bits1(gb) ? PU_QUARTERS : PU_FULL;
1705
2/2
✓ Branch 0 taken 718 times.
✓ Branch 1 taken 1575 times.
2293 if (cu.pu_type == PU_QUARTERS)
1706
2/2
✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 718 times.
3590 for (int i = 0; i < 4; i++)
1707 2872 cu.imode[i] = read_intra_mode(gb, &cu.imode_param[i]);
1708
1/2
✓ Branch 0 taken 1575 times.
✗ Branch 1 not taken.
1575 else if (size <= 32)
1709 1575 cu.imode[0] = read_intra_mode(gb, &cu.imode_param[0]);
1710 else
1711 ✗ cu.imode[0] = get_bits1(gb) ? INTRAMODE_PLANE64 : INTRAMODE_DC64;
1712 2293 break;
1713 1007 case CU_INTER_MV:
1714
2/2
✓ Branch 0 taken 799 times.
✓ Branch 1 taken 208 times.
1007 cu.pu_type = get_bits(gb, size == 8 ? 2 : 3);
1715 1007 count = pu_type_num_parts(cu.pu_type);
1716
2/2
✓ Branch 0 taken 1998 times.
✓ Branch 1 taken 1007 times.
3005 for (int i = 0; i < count; i++)
1717 1998 read_mv_info(s, gb, &cu.mv[i], size, cu.pu_type);
1718 1007 break;
1719 1812 default:
1720 1812 cu.pu_type = PU_FULL;
1721 1812 cu.mv[0].mvref = skip_mv_ref[get_unary(gb, 0, 3)];
1722 1812 break;
1723 }
1724
1725 5112 reconstruct(s, &cu, size);
1726
1727
6/6
✓ Branch 0 taken 2293 times.
✓ Branch 1 taken 2819 times.
✓ Branch 2 taken 1480 times.
✓ Branch 3 taken 813 times.
✓ Branch 4 taken 718 times.
✓ Branch 5 taken 762 times.
5112 split_i4x4 = cu.cu_type == CU_INTRA && size == 8 && cu.pu_type == PU_QUARTERS;
1728
1729
2/2
✓ Branch 0 taken 2293 times.
✓ Branch 1 taken 2819 times.
5112 switch (cu.cu_type) {
1730 2293 case CU_INTRA:
1731 2293 imode = s->blk_info[cu.blk_pos].imode;
1732
2/2
✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 718 times.
2293 if (!split_i4x4) {
1733 1575 int off = ypos * frame->linesize[0] + xpos;
1734 1575 populate_ipred(s, &cu, frame->data[0], frame->linesize[0], 0, 0, size, 1);
1735
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1575 times.
1575 if (pred_angle(&cu.ipred, frame->data[0] + off, frame->linesize[0], size, imode, 1) < 0)
1736 ✗ return AVERROR_INVALIDDATA;
1737 }
1738
2/2
✓ Branch 0 taken 4586 times.
✓ Branch 1 taken 2293 times.
6879 for (int plane = 1; plane < 3; plane++) {
1739 4586 int off = (ypos >> 1) * frame->linesize[plane] + (xpos >> 1);
1740 4586 populate_ipred(s, &cu, frame->data[plane], frame->linesize[plane], 0, 0, size >> 1, 0);
1741
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4586 times.
4586 if (pred_angle(&cu.ipred, frame->data[plane] + off, frame->linesize[plane], size >> 1, imode, 0) < 0)
1742 ✗ return AVERROR_INVALIDDATA;
1743 }
1744 2293 break;
1745 2819 default:
1746 2819 mv_x = xpos >> 2;
1747 2819 mv_y = ypos >> 2;
1748 2819 mv_pos = mv_y * s->blk_stride + mv_x;
1749 2819 count = pu_type_num_parts(cu.pu_type);
1750
2/2
✓ Branch 0 taken 3810 times.
✓ Branch 1 taken 2819 times.
6629 for (int part_no = 0; part_no < count; part_no++) {
1751 MVInfo mv;
1752 Dimensions dim;
1753 int bw, bh, bx, by;
1754
1755 3810 mv = s->blk_info[mv_pos].mv;
1756 3810 get_mv_dimensions(&dim, cu.pu_type, part_no, size);
1757 3810 bw = dim.w << 2;
1758 3810 bh = dim.h << 2;
1759 3810 bx = mv_x << 2;
1760 3810 by = mv_y << 2;
1761
1762
2/2
✓ Branch 0 taken 2725 times.
✓ Branch 1 taken 1085 times.
3810 if (!(mv.mvref & 2)) {
1763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2725 times.
2725 if (!s->last_frame[LAST_PIC]->data[0]) {
1764 ✗ av_log(s->avctx, AV_LOG_ERROR, "missing reference frame\n");
1765 ✗ return AVERROR_INVALIDDATA;
1766 }
1767 }
1768
2/2
✓ Branch 0 taken 1392 times.
✓ Branch 1 taken 2418 times.
3810 if (mv.mvref & 6) {
1769
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1392 times.
1392 if (!s->last_frame[NEXT_PIC]->data[0]) {
1770 ✗ av_log(s->avctx, AV_LOG_ERROR, "missing reference frame\n");
1771 ✗ return AVERROR_INVALIDDATA;
1772 }
1773 }
1774
1775
4/5
✓ Branch 0 taken 2418 times.
✓ Branch 1 taken 207 times.
✓ Branch 2 taken 878 times.
✓ Branch 3 taken 307 times.
✗ Branch 4 not taken.
3810 switch (mv.mvref) {
1776 2418 case MVREF_REF0:
1777 2418 mc(s, frame->data, frame->linesize, s->last_frame[LAST_PIC], bx, by, bw, bh, mv.f_mv, 0);
1778 2418 break;
1779 207 case MVREF_REF1:
1780 207 mc(s, frame->data, frame->linesize, s->last_frame[NEXT_PIC], bx, by, bw, bh, mv.f_mv, 0);
1781 207 break;
1782 878 case MVREF_BREF:
1783 878 mc(s, frame->data, frame->linesize, s->last_frame[NEXT_PIC], bx, by, bw, bh, mv.b_mv, 0);
1784 878 break;
1785 307 case MVREF_REF0ANDBREF:
1786 307 mc(s, frame->data, frame->linesize, s->last_frame[LAST_PIC], bx, by, bw, bh, mv.f_mv, 0);
1787 307 mc(s, thread->avg_data, thread->avg_linesize, s->last_frame[NEXT_PIC], bx, by, bw, bh, mv.b_mv, 1);
1788 307 avg(frame, thread->avg_data, thread->avg_linesize, bx, by, bw, bh);
1789 307 break;
1790 ✗ default:
1791 ✗ av_assert0(0); //should never reach here
1792 }
1793 3810 get_next_mv(s, &dim, cu.pu_type, part_no, &mv_pos, &mv_x, &mv_y);
1794 }
1795 2819 break;
1796 }
1797
1798
2/2
✓ Branch 0 taken 1639 times.
✓ Branch 1 taken 3473 times.
5112 if (cu.cu_type == CU_SKIP)
1799 1639 ttype = TRANSFORM_NONE;
1800
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3445 times.
3473 else if (size >= 32)
1801 28 ttype = TRANSFORM_16X16;
1802
2/2
✓ Branch 0 taken 1058 times.
✓ Branch 1 taken 2387 times.
3445 else if (size == 16)
1803
4/4
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 813 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 148 times.
1058 ttype = cu.cu_type == CU_INTRA || cu.pu_type == PU_FULL ? TRANSFORM_16X16 : TRANSFORM_4X4;
1804 else
1805
2/2
✓ Branch 0 taken 1370 times.
✓ Branch 1 taken 1017 times.
2387 ttype = cu.pu_type == PU_FULL ? TRANSFORM_8X8 : TRANSFORM_4X4;
1806
1807 5112 is_intra = cu.cu_type == CU_INTRA;
1808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5112 times.
5112 if (qp >= 32)
1809 ✗ return AVERROR_INVALIDDATA;
1810 5112 cu_pos = ((xpos & 63) >> 3) + ((ypos & 63) >> 3) * 8;
1811
1812
4/4
✓ Branch 0 taken 1165 times.
✓ Branch 1 taken 1370 times.
✓ Branch 2 taken 938 times.
✓ Branch 3 taken 1639 times.
5112 switch (ttype) {
1813 1165 case TRANSFORM_4X4:
1814
2/2
✓ Branch 0 taken 718 times.
✓ Branch 1 taken 447 times.
1165 subset = is_intra ? 0 : 2;
1815
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 1017 times.
1165 if (size == 16) {
1816
2/2
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 9 times.
148 int cbp16 = get_bits1(gb) ? decode_cbp16(gb, subset, sel_qp) : 0;
1817
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 9 times.
148 if (cbp16) {
1818 139 decode_cu_4x4in16x16(gb, is_intra, qp, sel_qp, y_coeffs, u_coeffs, v_coeffs, cbp16);
1819
2/2
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 139 times.
695 for (int y = 0; y < 4; y++)
1820
2/2
✓ Branch 0 taken 2224 times.
✓ Branch 1 taken 556 times.
2780 for (int x = 0; x < 4; x++) {
1821 2224 int i = y*4 + x;
1822
2/2
✓ Branch 0 taken 979 times.
✓ Branch 1 taken 1245 times.
2224 if ((cbp16 >> i) & 1) {
1823 979 int off = (ypos + y * 4)*frame->linesize[0] + xpos + x * 4;
1824 979 ff_rv60_idct4x4_add(y_coeffs + i*16, frame->data[0] + off, frame->linesize[0]);
1825 979 thread->coded_blk[cu_pos + (y/2)*8 + (x/2)] = 1;
1826 }
1827 }
1828
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 139 times.
417 for (int y = 0; y < 2; y++)
1829
2/2
✓ Branch 0 taken 556 times.
✓ Branch 1 taken 278 times.
834 for (int x = 0; x < 2; x++) {
1830 556 int i = y * 2 + x;
1831 556 int xoff = (xpos >> 1) + x * 4;
1832 556 int yoff = (ypos >> 1) + y * 4;
1833
2/2
✓ Branch 0 taken 341 times.
✓ Branch 1 taken 215 times.
556 if ((cbp16 >> (16 + i)) & 1) {
1834 341 int off = yoff * frame->linesize[1] + xoff;
1835 341 ff_rv60_idct4x4_add(u_coeffs + i * 16, frame->data[1] + off, frame->linesize[1]);
1836 341 thread->coded_blk[cu_pos + y*8 + x] = 1;
1837 }
1838
2/2
✓ Branch 0 taken 335 times.
✓ Branch 1 taken 221 times.
556 if ((cbp16 >> (20 + i)) & 1) {
1839 335 int off = yoff * frame->linesize[2] + xoff;
1840 335 ff_rv60_idct4x4_add(v_coeffs + i * 16, frame->data[2] + off, frame->linesize[2]);
1841 335 thread->coded_blk[cu_pos + y*8 + x] = 1;
1842 }
1843 }
1844 }
1845 } else {
1846 1017 cbp8 = decode_cbp8(gb, subset, sel_qp);
1847
2/2
✓ Branch 0 taken 967 times.
✓ Branch 1 taken 50 times.
1017 if (cbp8) {
1848 967 thread->coded_blk[cu_pos] = 1;
1849 967 decode_cu_8x8(gb, is_intra, qp, sel_qp, y_coeffs, u_coeffs, v_coeffs, cbp8, 1);
1850 }
1851
2/2
✓ Branch 0 taken 4068 times.
✓ Branch 1 taken 1017 times.
5085 for (int i = 0; i < 4; i++) {
1852 4068 int xoff = (i & 1) << 2;
1853 4068 int yoff = (i & 2) << 1;
1854
2/2
✓ Branch 0 taken 2872 times.
✓ Branch 1 taken 1196 times.
4068 if (split_i4x4) {
1855 2872 int off = (ypos + yoff) * frame->linesize[0] + xpos + xoff;
1856 2872 int imode = s->blk_info[cu.blk_pos + (i >> 1) * s->blk_stride + (i & 1)].imode;
1857 2872 populate_ipred(s, &cu, frame->data[0], frame->linesize[0], xoff, yoff, 4, 1);
1858
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2872 times.
2872 if (pred_angle(&cu.ipred, frame->data[0] + off, frame->linesize[0], 4, imode, 1) < 0)
1859 ✗ return AVERROR_INVALIDDATA;
1860 }
1861
2/2
✓ Branch 0 taken 2468 times.
✓ Branch 1 taken 1600 times.
4068 if ((cbp8 >> i) & 1) {
1862 2468 int off = (ypos + yoff) * frame->linesize[0] + xpos + xoff;
1863 2468 ff_rv60_idct4x4_add(y_coeffs + i * 16, frame->data[0] + off, frame->linesize[0]);
1864 }
1865 }
1866
2/2
✓ Branch 0 taken 935 times.
✓ Branch 1 taken 82 times.
1017 if ((cbp8 >> 4) & 1) {
1867 935 int off = (ypos >> 1) * frame->linesize[1] + (xpos >> 1);
1868 935 ff_rv60_idct4x4_add(u_coeffs, frame->data[1] + off, frame->linesize[1]);
1869 }
1870
2/2
✓ Branch 0 taken 936 times.
✓ Branch 1 taken 81 times.
1017 if ((cbp8 >> 5) & 1) {
1871 936 int off = (ypos >> 1) * frame->linesize[2] + (xpos >> 1);
1872 936 ff_rv60_idct4x4_add(v_coeffs, frame->data[2] + off, frame->linesize[2]);
1873 }
1874 }
1875 1165 break;
1876 1370 case TRANSFORM_8X8:
1877
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 608 times.
1370 subset = is_intra ? 1 : 3;
1878 1370 cbp8 = decode_cbp8(gb, subset, sel_qp);
1879
2/2
✓ Branch 0 taken 934 times.
✓ Branch 1 taken 436 times.
1370 if (cbp8) {
1880 934 thread->coded_blk[cu_pos] = 1;
1881 934 decode_cu_8x8(gb, is_intra, qp, sel_qp, y_coeffs, u_coeffs, v_coeffs, cbp8, 0);
1882
2/2
✓ Branch 0 taken 851 times.
✓ Branch 1 taken 83 times.
934 if (cbp8 & 0xF) {
1883 851 int off = ypos * frame->linesize[0] + xpos;
1884 851 ff_rv60_idct8x8_add(y_coeffs, frame->data[0] + off, frame->linesize[0]);
1885 }
1886
2/2
✓ Branch 0 taken 806 times.
✓ Branch 1 taken 128 times.
934 if ((cbp8 >> 4) & 1) {
1887 806 int off = (ypos >> 1) * frame->linesize[1] + (xpos >> 1);
1888 806 ff_rv60_idct4x4_add(u_coeffs, frame->data[1] + off, frame->linesize[1]);
1889 }
1890
2/2
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 92 times.
934 if ((cbp8 >> 5) & 1) {
1891 842 int off = (ypos >> 1) * frame->linesize[2] + (xpos >> 1);
1892 842 ff_rv60_idct4x4_add(v_coeffs, frame->data[2] + off, frame->linesize[2]);
1893 }
1894 }
1895 1370 break;
1896 938 case TRANSFORM_16X16:
1897
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 125 times.
938 subset = is_intra ? 1 : 3;
1898 938 num_clusters = size >> 4;
1899 938 cl_cbp = get_bits(gb, num_clusters * num_clusters);
1900
2/2
✓ Branch 0 taken 966 times.
✓ Branch 1 taken 938 times.
1904 for (int y = 0; y < num_clusters; y++) {
1901
2/2
✓ Branch 0 taken 1022 times.
✓ Branch 1 taken 966 times.
1988 for (int x = 0; x < num_clusters; x++) {
1902
2/2
✓ Branch 0 taken 809 times.
✓ Branch 1 taken 213 times.
1022 if (!((cl_cbp >> (y*num_clusters + x)) & 1))
1903 809 continue;
1904 213 thread->coded_blk[cu_pos + y*2*8 + x*2 + 0] = 1;
1905 213 thread->coded_blk[cu_pos + y*2*8 + x*2 + 1] = 1;
1906 213 thread->coded_blk[cu_pos + y*2*8 + x*2 + 8] = 1;
1907 213 thread->coded_blk[cu_pos + y*2*8 + x*2 + 9] = 1;
1908 213 super_cbp = decode_cbp16(gb, subset, sel_qp);
1909
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 if (super_cbp) {
1910 213 decode_cu_16x16(gb, is_intra, qp, sel_qp, y_coeffs, u_coeffs, v_coeffs, super_cbp);
1911
2/2
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 42 times.
213 if (super_cbp & 0xFFFF) {
1912 171 int off = (ypos + y * 16) * frame->linesize[0] + xpos + x * 16;
1913 171 ff_rv60_idct16x16_add(y_coeffs, frame->data[0] + off, frame->linesize[0]);
1914 }
1915
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 51 times.
213 if ((super_cbp >> 16) & 0xF) {
1916 162 int off = ((ypos >> 1) + y * 8) * frame->linesize[1] + (xpos >> 1) + x * 8;
1917 162 ff_rv60_idct8x8_add(u_coeffs, frame->data[1] + off, frame->linesize[1]);
1918 }
1919
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 19 times.
213 if ((super_cbp >> 20) & 0xF) {
1920 194 int off = ((ypos >> 1) + y * 8) * frame->linesize[2] + (xpos >> 1) + x * 8;
1921 194 ff_rv60_idct8x8_add(v_coeffs, frame->data[2] + off, frame->linesize[2]);
1922 }
1923 }
1924 }
1925 }
1926 938 break;
1927 }
1928
1929 5112 return 0;
1930 }
1931
1932 19711 static int deblock_get_pos(RV60Context * s, int xpos, int ypos)
1933 {
1934 19711 return (ypos >> 2) * s->dblk_stride + (xpos >> 2);
1935 }
1936
1937 7779 static void deblock_set_strength(RV60Context * s, int xpos, int ypos, int size, int q, int strength)
1938 {
1939 7779 int pos = deblock_get_pos(s, xpos, ypos);
1940 7779 int dsize = size >> 2;
1941 7779 int dval = (q << 2) + strength;
1942
1943
2/2
✓ Branch 0 taken 23628 times.
✓ Branch 1 taken 7779 times.
31407 for (int x = 0; x < dsize; x++) {
1944 23628 s->top_str[pos + x] = dval;
1945 23628 s->top_str[pos + (dsize - 1)*s->dblk_stride + x] = dval;
1946 }
1947
1948
2/2
✓ Branch 0 taken 23628 times.
✓ Branch 1 taken 7779 times.
31407 for (int y = 0; y < dsize; y++) {
1949 23628 s->left_str[pos + y*s->dblk_stride] = dval;
1950 23628 s->left_str[pos + y*s->dblk_stride + dsize - 1] = dval;
1951 }
1952 7779 }
1953
1954 13514 static int deblock_get_top_strength(const RV60Context * s, int pos)
1955 {
1956 13514 return s->top_str[pos] & 3;
1957 }
1958
1959 13716 static int deblock_get_left_strength(const RV60Context * s, int pos)
1960 {
1961 13716 return s->left_str[pos] & 3;
1962 }
1963
1964 1770 static void deblock_set_top_strength(RV60Context * s, int pos, int strength)
1965 {
1966 1770 s->top_str[pos] |= strength;
1967 1770 }
1968
1969 1216 static void deblock_set_left_strength(RV60Context * s, int pos, int strength)
1970 {
1971 1216 s->left_str[pos] |= strength;
1972 1216 }
1973
1974 4153 static void derive_deblock_strength(RV60Context * s, int xpos, int ypos, int size)
1975 {
1976 4153 int blk_pos = (ypos >> 2) * s->blk_stride + (xpos >> 2);
1977 4153 int dblk_pos = deblock_get_pos(s, xpos, ypos);
1978
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 303 times.
4153 if (ypos > 0)
1979
2/2
✓ Branch 0 taken 13514 times.
✓ Branch 1 taken 3850 times.
17364 for (int i = 0; i < size; i++)
1980
4/4
✓ Branch 1 taken 11940 times.
✓ Branch 2 taken 1574 times.
✓ Branch 4 taken 1770 times.
✓ Branch 5 taken 10170 times.
13514 if (!deblock_get_top_strength(s, dblk_pos - s->dblk_stride + i) && mvinfo_is_deblock_cand(&s->blk_info[blk_pos + i].mv, &s->blk_info[blk_pos - s->blk_stride + i].mv))
1981 1770 deblock_set_top_strength(s, dblk_pos + i, 1);
1982
2/2
✓ Branch 0 taken 3905 times.
✓ Branch 1 taken 248 times.
4153 if (xpos > 0)
1983
2/2
✓ Branch 0 taken 13716 times.
✓ Branch 1 taken 3905 times.
17621 for (int i = 0; i < size; i++)
1984
4/4
✓ Branch 1 taken 12512 times.
✓ Branch 2 taken 1204 times.
✓ Branch 4 taken 1216 times.
✓ Branch 5 taken 11296 times.
13716 if (!deblock_get_left_strength(s, dblk_pos + i *s->dblk_stride - 1) && mvinfo_is_deblock_cand(&s->blk_info[blk_pos + i*s->blk_stride].mv, &s->blk_info[blk_pos + i*s->blk_stride - 1].mv))
1985 1216 deblock_set_left_strength(s, dblk_pos + i *s->dblk_stride, 1);
1986 4153 }
1987
1988 #define STRENGTH(el, lim) (FFABS(el) < (lim) ? 3 : 1)
1989 #define CLIP_SYMM(a, b) av_clip(a, -(b), b)
1990
1991 23366 static void filter_luma_edge(uint8_t * dst, int step, int stride, int mode1, int mode2, int lim1, int lim2)
1992 {
1993 int16_t diff_q1q0[4];
1994 int16_t diff_p1p0[4];
1995 int str_p, str_q, msum, maxprod, weak;
1996
1997
2/2
✓ Branch 0 taken 93464 times.
✓ Branch 1 taken 23366 times.
116830 for (int i = 0; i < 4; i++) {
1998 93464 diff_q1q0[i] = dst[i * stride - 2*step] - dst[i*stride - step];
1999 93464 diff_p1p0[i] = dst[i * stride + step] - dst[i*stride];
2000 }
2001
2002
2/2
✓ Branch 0 taken 1247 times.
✓ Branch 1 taken 22119 times.
23366 str_p = STRENGTH(diff_q1q0[0] + diff_q1q0[1] + diff_q1q0[2] + diff_q1q0[3], lim2);
2003
2/2
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 22073 times.
23366 str_q = STRENGTH(diff_p1p0[0] + diff_p1p0[1] + diff_p1p0[2] + diff_p1p0[3], lim2);
2004
2005
2/2
✓ Branch 0 taken 22045 times.
✓ Branch 1 taken 1321 times.
23366 if (str_p + str_q <= 2)
2006 22045 return;
2007
2008 1321 msum = (mode1 + mode2 + str_q + str_p) >> 1;
2009
4/4
✓ Branch 0 taken 1293 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 1219 times.
1321 if (str_q == 1 || str_p == 1) {
2010 102 maxprod = 384;
2011 102 weak = 1;
2012 } else {
2013 1219 maxprod = 256;
2014 1219 weak = 0;
2015 }
2016
2017
2/2
✓ Branch 0 taken 5284 times.
✓ Branch 1 taken 1321 times.
6605 for (int y = 0; y < 4; y++) {
2018 5284 int diff_p0q0 = dst[0] - dst[-step];
2019 5284 int result = (lim1 * FFABS(diff_p0q0)) & -128;
2020
4/4
✓ Branch 0 taken 3950 times.
✓ Branch 1 taken 1334 times.
✓ Branch 2 taken 2011 times.
✓ Branch 3 taken 1939 times.
5284 if (diff_p0q0 && result <= maxprod) {
2021 2011 int diff_q1q2 = dst[-2*step] - dst[-3*step];
2022 2011 int diff_p1p2 = dst[step] - dst[2*step];
2023 int delta;
2024
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 1885 times.
2011 if (weak) {
2025 126 delta = CLIP_SYMM((diff_p0q0 + 1) >> 1, msum >> 1);
2026 } else {
2027 1885 int diff_strg = (dst[-2*step] - dst[step] + 4 * diff_p0q0 + 4) >> 3;
2028 1885 delta = CLIP_SYMM(diff_strg, msum);
2029 }
2030 2011 dst[-step] = av_clip_uint8(dst[-step] + delta);
2031 2011 dst[0] = av_clip_uint8(dst[0] - delta);
2032
4/4
✓ Branch 0 taken 1915 times.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 1253 times.
✓ Branch 3 taken 662 times.
2011 if (str_p != 1 && FFABS(diff_q1q2) <= (lim2 >> 2)) {
2033 1253 int diff = (diff_q1q0[y] + diff_q1q2 - delta) >> 1;
2034
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1240 times.
1253 int delta_q1 = weak ? CLIP_SYMM(diff, mode1 >> 1) : CLIP_SYMM(diff, mode1);
2035 1253 dst[-2 * step] = av_clip_uint8(dst[-2*step] - delta_q1);
2036 }
2037
4/4
✓ Branch 0 taken 1981 times.
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 1733 times.
✓ Branch 3 taken 248 times.
2011 if (str_q != 1 && FFABS(diff_p1p2) <= (lim2 >> 2)) {
2038 1733 int diff = (diff_p1p0[y] + diff_p1p2 + delta) >> 1;
2039
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 1663 times.
1733 int delta_p1 = weak ? CLIP_SYMM(diff, mode2 >> 1) : CLIP_SYMM(diff, mode2);
2040 1733 dst[step] = av_clip_uint8(dst[step] - delta_p1);
2041 }
2042 }
2043 5284 dst += stride;
2044 }
2045 }
2046
2047 26792 static void filter_chroma_edge(uint8_t * dst, int step, int stride, int mode1, int mode2, int lim1, int lim2)
2048 {
2049 26792 int diff_q = 4 * FFABS(dst[-2*step] - dst[-step]);
2050 26792 int diff_p = 4 * FFABS(dst[ step] - dst[0]);
2051
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 26644 times.
26792 int str_q = STRENGTH(diff_q, lim2);
2052
2/2
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 26591 times.
26792 int str_p = STRENGTH(diff_p, lim2);
2053 int msum, maxprod, weak;
2054
2055
2/2
✓ Branch 0 taken 26545 times.
✓ Branch 1 taken 247 times.
26792 if (str_p + str_q <= 2)
2056 26545 return;
2057
2058 247 msum = (mode1 + mode2 + str_q + str_p) >> 1;
2059
4/4
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 99 times.
✓ Branch 2 taken 46 times.
✓ Branch 3 taken 102 times.
247 if (str_q == 1 || str_p == 1) {
2060 145 maxprod = 384;
2061 145 weak = 1;
2062 } else {
2063 102 maxprod = 256;
2064 102 weak = 0;
2065 }
2066
2067
2/2
✓ Branch 0 taken 494 times.
✓ Branch 1 taken 247 times.
741 for (int y = 0; y < 2; y++) {
2068 494 int diff_pq = dst[0] - dst[-step];
2069 494 int result = (lim1 * FFABS(diff_pq)) & -128;
2070
4/4
✓ Branch 0 taken 417 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 195 times.
✓ Branch 3 taken 222 times.
494 if (diff_pq && result <= maxprod) {
2071 int delta;
2072
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 84 times.
195 if (weak) {
2073 111 delta = CLIP_SYMM((diff_pq + 1) >> 1, msum >> 1);
2074 } else {
2075 84 int diff_strg = (dst[-2*step] - dst[step] + 4 * diff_pq + 4) >> 3;
2076 84 delta = CLIP_SYMM(diff_strg, msum);
2077 }
2078 195 dst[-step] = av_clip_uint8(dst[-step] + delta);
2079 195 dst[ 0 ] = av_clip_uint8(dst[ 0 ] - delta);
2080 }
2081 494 dst += stride;
2082 }
2083 }
2084
2085 11120 static void deblock_edge_ver(AVFrame * frame, int xpos, int ypos, int dblk_l, int dblk_r, int deblock_chroma)
2086 {
2087 11120 int qp_l = dblk_l >> 2;
2088 11120 int str_l = dblk_l & 3;
2089 11120 int qp_r = dblk_r >> 2;
2090 11120 int str_r = dblk_r & 3;
2091 11120 const uint8_t * dl_l = rv60_deblock_limits[qp_l];
2092 11120 const uint8_t * dl_r = rv60_deblock_limits[qp_r];
2093
2/2
✓ Branch 0 taken 8758 times.
✓ Branch 1 taken 2362 times.
11120 int mode_l = str_l ? dl_l[str_l - 1] : 0;
2094
2/2
✓ Branch 0 taken 9916 times.
✓ Branch 1 taken 1204 times.
11120 int mode_r = str_r ? dl_r[str_r - 1] : 0;
2095 11120 int lim1 = dl_r[2];
2096 11120 int lim2 = dl_r[3] * 4;
2097
2098 11120 filter_luma_edge(frame->data[0] + ypos * frame->linesize[0] + xpos, 1, frame->linesize[0], mode_l, mode_r, lim1, lim2);
2099
3/4
✓ Branch 0 taken 6660 times.
✓ Branch 1 taken 4460 times.
✓ Branch 2 taken 6660 times.
✗ Branch 3 not taken.
11120 if ((str_l | str_r) >= 2 && deblock_chroma)
2100
2/2
✓ Branch 0 taken 13320 times.
✓ Branch 1 taken 6660 times.
19980 for (int plane = 1; plane < 3; plane++)
2101 13320 filter_chroma_edge(frame->data[plane] + (ypos >> 1) * frame->linesize[plane] + (xpos >> 1), 1, frame->linesize[plane], mode_l, mode_r, lim1, lim2);
2102 11120 }
2103
2104 12246 static void deblock_edge_hor(AVFrame * frame, int xpos, int ypos, int dblk_t, int dblk_d, int deblock_chroma)
2105 {
2106 12246 int qp_t = dblk_t >> 2;
2107 12246 int str_t = dblk_t & 3;
2108 12246 int qp_d = dblk_d >> 2;
2109 12246 int str_d = dblk_d & 3;
2110 12246 const uint8_t * dl_t = rv60_deblock_limits[qp_t];
2111 12246 const uint8_t * dl_d = rv60_deblock_limits[qp_d];
2112
2/2
✓ Branch 0 taken 8902 times.
✓ Branch 1 taken 3344 times.
12246 int mode_t = str_t ? dl_t[str_t - 1] : 0;
2113
2/2
✓ Branch 0 taken 10672 times.
✓ Branch 1 taken 1574 times.
12246 int mode_d = str_d ? dl_d[str_d - 1] : 0;
2114 12246 int lim1 = dl_d[2];
2115 12246 int lim2 = dl_d[3] * 4;
2116
2117 12246 filter_luma_edge(frame->data[0] + ypos * frame->linesize[0] + xpos, frame->linesize[0], 1, mode_t, mode_d, lim1, lim2);
2118
3/4
✓ Branch 0 taken 6736 times.
✓ Branch 1 taken 5510 times.
✓ Branch 2 taken 6736 times.
✗ Branch 3 not taken.
12246 if ((str_t | str_d) >= 2 && deblock_chroma)
2119
2/2
✓ Branch 0 taken 13472 times.
✓ Branch 1 taken 6736 times.
20208 for (int plane = 1; plane < 3; plane++)
2120 13472 filter_chroma_edge(frame->data[plane] + (ypos >> 1) * frame->linesize[plane] + (xpos >> 1), frame->linesize[plane], 1, mode_t, mode_d, lim1, lim2);
2121 12246 }
2122
2123 15849 static void deblock8x8(const RV60Context * s, AVFrame * frame, int xpos, int ypos, int dblkpos)
2124 {
2125
2/2
✓ Branch 0 taken 15243 times.
✓ Branch 1 taken 606 times.
15849 if (xpos > 0) {
2126
2/2
✓ Branch 0 taken 14676 times.
✓ Branch 1 taken 567 times.
15243 if (ypos > 0) {
2127 14676 int str_l = s->left_str[dblkpos - s->dblk_stride - 1];
2128 14676 int str_r = s->left_str[dblkpos - s->dblk_stride];
2129
2/2
✓ Branch 0 taken 5422 times.
✓ Branch 1 taken 9254 times.
14676 if ((str_l | str_r) & 3)
2130 5422 deblock_edge_ver(frame, xpos, ypos - 4, str_l, str_r, s->deblock_chroma);
2131 }
2132 {
2133 15243 int str_l = s->left_str[dblkpos - 1];
2134 15243 int str_r = s->left_str[dblkpos];
2135
2/2
✓ Branch 0 taken 5563 times.
✓ Branch 1 taken 9680 times.
15243 if ((str_l | str_r) & 3)
2136 5563 deblock_edge_ver(frame, xpos, ypos, str_l, str_r, s->deblock_chroma);
2137 }
2138
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 14931 times.
15243 if (ypos + 8 >= s->aheight) {
2139 312 int str_l = s->left_str[dblkpos + s->dblk_stride - 1];
2140 312 int str_r = s->left_str[dblkpos + s->dblk_stride];
2141
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 177 times.
312 if ((str_l | str_r) & 3)
2142 135 deblock_edge_ver(frame, xpos, ypos + 4, str_l, str_r, s->deblock_chroma);
2143 }
2144 }
2145
2/2
✓ Branch 0 taken 15243 times.
✓ Branch 1 taken 606 times.
15849 if (ypos > 0) {
2146
2/2
✓ Branch 0 taken 14676 times.
✓ Branch 1 taken 567 times.
15243 if (xpos > 0) {
2147 14676 int str_t = s->top_str[dblkpos - s->dblk_stride - 1];
2148 14676 int str_d = s->top_str[dblkpos - 1];
2149
2/2
✓ Branch 0 taken 5906 times.
✓ Branch 1 taken 8770 times.
14676 if ((str_t | str_d) & 3)
2150 5906 deblock_edge_hor(frame, xpos - 4, ypos, str_t, str_d, s->deblock_chroma);
2151 }
2152 {
2153 15243 int str_t = s->top_str[dblkpos - s->dblk_stride];
2154 15243 int str_d = s->top_str[dblkpos];
2155
2/2
✓ Branch 0 taken 6120 times.
✓ Branch 1 taken 9123 times.
15243 if ((str_t | str_d) & 3)
2156 6120 deblock_edge_hor(frame, xpos, ypos, str_t, str_d, s->deblock_chroma);
2157 }
2158
2/2
✓ Branch 0 taken 345 times.
✓ Branch 1 taken 14898 times.
15243 if (xpos + 8 >= s->awidth) {
2159 345 int str_t = s->top_str[dblkpos - s->dblk_stride + 1];
2160 345 int str_d = s->top_str[dblkpos + 1];
2161
2/2
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 125 times.
345 if ((str_t | str_d) & 3)
2162 220 deblock_edge_hor(frame, xpos + 4, ypos, str_t, str_d, s->deblock_chroma);
2163 }
2164 }
2165 15849 }
2166
2167 7779 static void deblock(const RV60Context * s, AVFrame * frame, int xpos, int ypos, int size, int dpos)
2168 {
2169
2/2
✓ Branch 0 taken 11814 times.
✓ Branch 1 taken 7779 times.
19593 for (int x = 0; x < size >> 3; x++)
2170 11814 deblock8x8(s, frame, xpos + x * 8, ypos, dpos + x * 2);
2171
2172
2/2
✓ Branch 0 taken 4035 times.
✓ Branch 1 taken 7779 times.
11814 for (int y = 1; y < size >> 3; y++)
2173 4035 deblock8x8(s, frame, xpos, ypos + y * 8, dpos + y * 2 * s->dblk_stride);
2174 7779 }
2175
2176 7524 static void deblock_cu_r(RV60Context * s, AVFrame * frame, ThreadContext * thread, int xpos, int ypos, int log_size, int qp)
2177 {
2178 int pu_pos, tsize, ntiles;
2179 enum CUType cu_type;
2180
2181
4/4
✓ Branch 0 taken 7174 times.
✓ Branch 1 taken 350 times.
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 6894 times.
7524 if (xpos >= s->awidth || ypos >= s->aheight)
2182 630 return;
2183
2184
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 5112 times.
6894 if (thread->cu_split[thread->cu_split_pos++]) {
2185 1782 int hsize = 1 << (log_size - 1);
2186 1782 log_size--;
2187 1782 deblock_cu_r(s, frame, thread, xpos, ypos, log_size, qp);
2188 1782 deblock_cu_r(s, frame, thread, xpos + hsize, ypos, log_size, qp);
2189 1782 deblock_cu_r(s, frame, thread, xpos, ypos + hsize, log_size, qp);
2190 1782 deblock_cu_r(s, frame, thread, xpos + hsize, ypos + hsize, log_size, qp);
2191 1782 return;
2192 }
2193
2194 5112 pu_pos = (ypos >> 3) * s->pu_stride + (xpos >> 3);
2195 5112 cu_type = s->pu_info[pu_pos].cu_type;
2196
3/4
✓ Branch 0 taken 3152 times.
✓ Branch 1 taken 1683 times.
✓ Branch 2 taken 277 times.
✗ Branch 3 not taken.
5112 switch (log_size) {
2197 3152 case 3: tsize = 3; break;
2198
4/4
✓ Branch 0 taken 870 times.
✓ Branch 1 taken 813 times.
✓ Branch 2 taken 148 times.
✓ Branch 3 taken 722 times.
1683 case 4: tsize = cu_type && s->pu_info[pu_pos].pu_type ? 3 : 4; break;
2199 277 case 5:
2200 277 case 6: tsize = 4; break;
2201 }
2202 5112 ntiles = 1 << (log_size - tsize);
2203
2204
2/2
✓ Branch 0 taken 5769 times.
✓ Branch 1 taken 5112 times.
10881 for (int ty = 0; ty < ntiles; ty++)
2205
2/2
✓ Branch 0 taken 7779 times.
✓ Branch 1 taken 5769 times.
13548 for (int tx = 0; tx < ntiles; tx++) {
2206 7779 int x = xpos + (tx << tsize);
2207 7779 int y = ypos + (ty << tsize);
2208 7779 int cu_pos = ((y & 63) >> 3) * 8 + ((x & 63) >> 3);
2209
2210
2/2
✓ Branch 0 taken 2293 times.
✓ Branch 1 taken 5486 times.
7779 if (cu_type == CU_INTRA)
2211 2293 deblock_set_strength(s, x, y, 1 << tsize, qp, 2);
2212
4/4
✓ Branch 0 taken 1708 times.
✓ Branch 1 taken 3778 times.
✓ Branch 2 taken 1333 times.
✓ Branch 3 taken 375 times.
5486 else if (cu_type != CU_SKIP && thread->coded_blk[cu_pos])
2213 1333 deblock_set_strength(s, x, y, 1 << tsize, qp, 1);
2214 else {
2215 4153 deblock_set_strength(s, x, y, 1 << tsize, qp, 0);
2216 4153 derive_deblock_strength(s, x, y, 1 << (tsize - 2));
2217 }
2218
2219 7779 deblock(s, frame, x, y, 1 << tsize, deblock_get_pos(s, x, y));
2220 }
2221 }
2222
2223 396 static int read_qp_offset(GetBitContext *gb, int qp_off_type)
2224 {
2225 int val;
2226
2227
1/3
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
396 switch (qp_off_type) {
2228 396 case 0:
2229 396 return 0;
2230 ✗ case 1:
2231 ✗ val = read_code012(gb);
2232 ✗ return val != 2 ? val : -1;
2233 ✗ default:
2234 ✗ if (!get_bits1(gb))
2235 ✗ return 0;
2236 ✗ val = get_bits(gb, 2);
2237 ✗ if (!(val & 2))
2238 ✗ return val + 1;
2239 else
2240 ✗ return -((val & 1) + 1);
2241 }
2242 }
2243
2244 396 static int calc_sel_qp(int osvquant, int qp)
2245 {
2246
2/3
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 256 times.
396 switch (osvquant) {
2247 140 case 0: return qp;
2248 ✗ case 1: return qp <= 25 ? qp + 5 : qp;
2249 256 default:
2250
1/2
✓ Branch 0 taken 256 times.
✗ Branch 1 not taken.
256 if (qp <= 18)
2251 256 return qp + 10;
2252 ✗ else if (qp <= 25)
2253 ✗ return qp + 5;
2254 else
2255 ✗ return qp;
2256 }
2257 }
2258
2259 102 static int decode_slice(AVCodecContext *avctx, void *tdata, int cu_y, int threadnr)
2260 {
2261 102 RV60Context *s = avctx->priv_data;
2262 102 AVFrame * frame = tdata;
2263 ThreadContext thread;
2264 GetBitContext gb;
2265 int qp, sel_qp, ret;
2266
2267 102 thread.avg_data[0] = thread.avg_buffer;
2268 102 thread.avg_data[1] = thread.avg_buffer + 64*64;
2269 102 thread.avg_data[2] = thread.avg_buffer + 64*64 + 32*32;
2270 102 thread.avg_linesize[0] = 64;
2271 102 thread.avg_linesize[1] = 32;
2272 102 thread.avg_linesize[2] = 32;
2273
2274
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
102 if ((ret = init_get_bits8(&gb, s->slice[cu_y].data, s->slice[cu_y].data_size)) < 0)
2275 ✗ return ret;
2276
2277
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 102 times.
498 for (int cu_x = 0; cu_x < s->cu_width; cu_x++) {
2278
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 396 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
396 if ((s->avctx->active_thread_type & FF_THREAD_SLICE) && cu_y)
2279 ✗ ff_thread_progress_await(&s->progress[cu_y - 1], cu_x + 2);
2280
2281 396 qp = s->qp + read_qp_offset(&gb, s->qp_off_type);
2282
2/4
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 396 times.
396 if (qp < 0 || qp >= 64) {
2283 ✗ ret = AVERROR_INVALIDDATA;
2284 ✗ break;
2285 }
2286 396 sel_qp = calc_sel_qp(s->osvquant, qp);
2287
2288 396 memset(thread.coded_blk, 0, sizeof(thread.coded_blk));
2289 396 thread.cu_split_pos = 0;
2290
2291
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 396 times.
396 if ((ret = decode_cu_r(s, frame, &thread, &gb, cu_x << 6, cu_y << 6, 6, qp, sel_qp)) < 0)
2292 ✗ break;
2293
2294
1/2
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
396 if (s->deblock) {
2295 396 thread.cu_split_pos = 0;
2296 396 deblock_cu_r(s, frame, &thread, cu_x << 6, cu_y << 6, 6, qp);
2297 }
2298
2299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 396 times.
396 if (s->avctx->active_thread_type & FF_THREAD_SLICE)
2300 ✗ ff_thread_progress_report(&s->progress[cu_y], cu_x + 1);
2301 }
2302
2303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (s->avctx->active_thread_type & FF_THREAD_SLICE)
2304 ✗ ff_thread_progress_report(&s->progress[cu_y], INT_MAX);
2305
2306 102 return ret;
2307 }
2308
2309 43 static int rv60_decode_frame(AVCodecContext *avctx, AVFrame * frame,
2310 int * got_frame, AVPacket * avpkt)
2311 {
2312 43 RV60Context *s = avctx->priv_data;
2313 GetBitContext gb;
2314 int ret, header_size, width, height, ofs;
2315
2316
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 39 times.
43 if (avpkt->size == 0) {
2317
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (s->last_frame[NEXT_PIC]->data[0]) {
2318 2 av_frame_move_ref(frame, s->last_frame[NEXT_PIC]);
2319 2 *got_frame = 1;
2320 }
2321 4 return 0;
2322 }
2323
2324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (avpkt->size < 9)
2325 ✗ return AVERROR_INVALIDDATA;
2326
2327 39 header_size = avpkt->data[0] * 8 + 9;
2328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (avpkt->size < header_size)
2329 ✗ return AVERROR_INVALIDDATA;
2330
2331
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = init_get_bits8(&gb, avpkt->data + header_size, avpkt->size - header_size)) < 0)
2332 ✗ return ret;
2333
2334
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = read_frame_header(s, &gb, &width, &height)) < 0)
2335 ✗ return ret;
2336
2337
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B ||
2338
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I ||
2339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 avctx->skip_frame >= AVDISCARD_ALL)
2340 ✗ return avpkt->size;
2341
2342
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 24 times.
39 if (s->pict_type != AV_PICTURE_TYPE_B)
2343 15 FFSWAP(AVFrame *, s->last_frame[NEXT_PIC], s->last_frame[LAST_PIC]);
2344
2345
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
39 if ((s->pict_type == AV_PICTURE_TYPE_P && !s->last_frame[LAST_PIC]->data[0]) ||
2346
4/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24 times.
39 (s->pict_type == AV_PICTURE_TYPE_B && (!s->last_frame[LAST_PIC]->data[0] || !s->last_frame[NEXT_PIC]->data[0]))) {
2347 ✗ av_log(s->avctx, AV_LOG_ERROR, "missing reference frame\n");
2348 ✗ return AVERROR_INVALIDDATA;
2349 }
2350
2351 39 s->last_frame[CUR_PIC]->pict_type = s->pict_type;
2352
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 37 times.
39 if (s->pict_type == AV_PICTURE_TYPE_I)
2353 2 s->last_frame[CUR_PIC]->flags |= AV_FRAME_FLAG_KEY;
2354
2355
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = update_dimensions_clear_info(s, width, height)) < 0)
2356 ✗ return ret;
2357
2358
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if (!s->last_frame[CUR_PIC]->data[0])
2359
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = ff_get_buffer(avctx, s->last_frame[CUR_PIC], 0)) < 0)
2360 ✗ return ret;
2361
2362
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = read_slice_sizes(s, &gb)) < 0)
2363 ✗ return ret;
2364
2365 39 ofs = get_bits_count(&gb) / 8;
2366
2367
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 39 times.
141 for (int i = 0; i < s->cu_height; i++) {
2368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (ofs >= avpkt->size - header_size)
2369 ✗ return AVERROR_INVALIDDATA;
2370 102 s->slice[i].data = avpkt->data + header_size + ofs;
2371 102 s->slice[i].data_size = FFMIN(s->slice[i].size, avpkt->size - header_size - ofs);
2372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102 times.
102 if (s->slice[i].size > INT32_MAX - ofs)
2373 ✗ return AVERROR_INVALIDDATA;
2374 102 ofs += s->slice[i].size;
2375 }
2376
2377 39 ret = progress_init(s, s->cu_height);
2378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (ret < 0)
2379 ✗ return ret;
2380
2381 39 s->avctx->execute2(s->avctx, decode_slice, s->last_frame[CUR_PIC], NULL, s->cu_height);
2382
2383 39 ret = 0;
2384
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 15 times.
39 if (s->pict_type == AV_PICTURE_TYPE_B)
2385 24 av_frame_move_ref(frame, s->last_frame[CUR_PIC]);
2386
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
15 else if (s->last_frame[LAST_PIC]->data[0])
2387 13 ret = av_frame_ref(frame, s->last_frame[LAST_PIC]);
2388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (ret < 0)
2389 ✗ return ret;
2390
2391
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 2 times.
39 if (frame->data[0])
2392 37 *got_frame = 1;
2393
2394
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 24 times.
39 if (s->pict_type != AV_PICTURE_TYPE_B) {
2395 15 av_frame_unref(s->last_frame[NEXT_PIC]);
2396 15 FFSWAP(AVFrame *, s->last_frame[CUR_PIC], s->last_frame[NEXT_PIC]);
2397 }
2398
2399
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 24 times.
39 if (s->pict_type != AV_PICTURE_TYPE_B) {
2400 15 s->ref_pts[0] = s->ref_pts[1];
2401 15 s->ref_pts[1] = avpkt->pts;
2402
2403 15 s->ref_ts[0] = s->ref_ts[1];
2404 15 s->ref_ts[1] = s->ts;
2405
2406
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
15 if (s->ref_pts[1] > s->ref_pts[0] && s->ref_ts[1] > s->ref_ts[0])
2407 13 s->ts_scale = (s->ref_pts[1] - s->ref_pts[0]) / (s->ref_ts[1] - s->ref_ts[0]);
2408 } else {
2409 24 frame->pts = s->ref_pts[0] + (s->ts - s->ref_ts[0]) * s->ts_scale;
2410 }
2411
2412 39 return avpkt->size;
2413 }
2414
2415 ✗ static av_cold void rv60_flush(AVCodecContext *avctx)
2416 {
2417 ✗ RV60Context *s = avctx->priv_data;
2418
2419 ✗ for (int i = 0; i < 3; i++)
2420 ✗ av_frame_unref(s->last_frame[i]);
2421 ✗ }
2422
2423 4 static av_cold int rv60_decode_end(AVCodecContext * avctx)
2424 {
2425 4 RV60Context *s = avctx->priv_data;
2426
2427
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 for (int i = 0; i < 3; i++)
2428 12 av_frame_free(&s->last_frame[i]);
2429
2430 4 av_freep(&s->slice);
2431 4 av_freep(&s->pu_info);
2432 4 av_freep(&s->blk_info);
2433 4 av_freep(&s->top_str);
2434 4 av_freep(&s->left_str);
2435
2436
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
14 for (int i = 0; i < s->nb_progress; i++)
2437 10 ff_thread_progress_destroy(&s->progress[i]);
2438 4 av_freep(&s->progress);
2439
2440 4 return 0;
2441 }
2442
2443 const FFCodec ff_rv60_decoder = {
2444 .p.name = "rv60",
2445 CODEC_LONG_NAME("RealVideo 6.0"),
2446 .p.type = AVMEDIA_TYPE_VIDEO,
2447 .p.id = AV_CODEC_ID_RV60,
2448 .priv_data_size = sizeof(RV60Context),
2449 .init = rv60_decode_init,
2450 .close = rv60_decode_end,
2451 FF_CODEC_DECODE_CB(rv60_decode_frame),
2452 .flush = rv60_flush,
2453 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
2454 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2455 };
2456