Coverage Report

Created: 2025-08-28 07:12

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