Coverage Report

Created: 2026-05-16 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/proresenc_kostya.c
Line
Count
Source
1
/*
2
 * Apple ProRes encoder
3
 *
4
 * Copyright (c) 2011 Anatoliy Wasserman
5
 * Copyright (c) 2012 Konstantin Shishkov
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
#include "libavutil/mem.h"
25
#include "libavutil/mem_internal.h"
26
#include "libavutil/opt.h"
27
#include "libavutil/pixdesc.h"
28
#include "avcodec.h"
29
#include "codec_internal.h"
30
#include "encode.h"
31
#include "fdctdsp.h"
32
#include "put_bits.h"
33
#include "profiles.h"
34
#include "bytestream.h"
35
#include "proresdata.h"
36
#include "proresenc_kostya_common.h"
37
38
178k
#define TRELLIS_WIDTH 16
39
3.65M
#define SCORE_LIMIT   INT_MAX / 2
40
41
struct TrellisNode {
42
    int prev_node;
43
    int quant;
44
    int bits;
45
    int score;
46
};
47
48
typedef struct ProresThreadData {
49
    DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
50
    DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
51
    int16_t custom_q[64];
52
    int16_t custom_chroma_q[64];
53
    struct TrellisNode *nodes;
54
} ProresThreadData;
55
56
static void get_slice_data(ProresContext *ctx, const uint16_t *src,
57
                           ptrdiff_t linesize, int x, int y, int w, int h,
58
                           int16_t *blocks, uint16_t *emu_buf,
59
                           int mbs_per_slice, int blocks_per_mb, int is_chroma)
60
133k
{
61
133k
    const uint16_t *esrc;
62
133k
    const int mb_width = 4 * blocks_per_mb;
63
133k
    ptrdiff_t elinesize;
64
133k
    int i, j, k;
65
66
456k
    for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
67
326k
        if (x >= w) {
68
3.14k
            memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
69
3.14k
                              * sizeof(*blocks));
70
3.14k
            return;
71
3.14k
        }
72
323k
        if (x + mb_width <= w && y + 16 <= h) {
73
62.7k
            esrc      = src;
74
62.7k
            elinesize = linesize;
75
260k
        } else {
76
260k
            int bw, bh, pix;
77
78
260k
            esrc      = emu_buf;
79
260k
            elinesize = 16 * sizeof(*emu_buf);
80
81
260k
            bw = FFMIN(w - x, mb_width);
82
260k
            bh = FFMIN(h - y, 16);
83
84
2.05M
            for (j = 0; j < bh; j++) {
85
1.79M
                memcpy(emu_buf + j * 16,
86
1.79M
                       (const uint8_t*)src + j * linesize,
87
1.79M
                       bw * sizeof(*src));
88
1.79M
                pix = emu_buf[j * 16 + bw - 1];
89
12.5M
                for (k = bw; k < mb_width; k++)
90
10.7M
                    emu_buf[j * 16 + k] = pix;
91
1.79M
            }
92
2.63M
            for (; j < 16; j++)
93
2.37M
                memcpy(emu_buf + j * 16,
94
2.37M
                       emu_buf + (bh - 1) * 16,
95
2.37M
                       mb_width * sizeof(*emu_buf));
96
260k
        }
97
323k
        if (!is_chroma) {
98
108k
            ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
99
108k
            blocks += 64;
100
108k
            if (blocks_per_mb > 2) {
101
108k
                ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
102
108k
                blocks += 64;
103
108k
            }
104
108k
            ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
105
108k
            blocks += 64;
106
108k
            if (blocks_per_mb > 2) {
107
108k
                ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
108
108k
                blocks += 64;
109
108k
            }
110
214k
        } else {
111
214k
            ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
112
214k
            blocks += 64;
113
214k
            ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
114
214k
            blocks += 64;
115
214k
            if (blocks_per_mb > 2) {
116
91.3k
                ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
117
91.3k
                blocks += 64;
118
91.3k
                ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
119
91.3k
                blocks += 64;
120
91.3k
            }
121
214k
        }
122
123
323k
        x += mb_width;
124
323k
    }
125
133k
}
126
127
static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
128
                           ptrdiff_t linesize, int x, int y, int w, int h,
129
                           uint16_t *blocks, int mbs_per_slice, int abits)
130
22.7k
{
131
22.7k
    const int slice_width = 16 * mbs_per_slice;
132
22.7k
    int i, j, copy_w, copy_h;
133
134
22.7k
    copy_w = FFMIN(w - x, slice_width);
135
22.7k
    copy_h = FFMIN(h - y, 16);
136
349k
    for (i = 0; i < copy_h; i++) {
137
326k
        memcpy(blocks, src, copy_w * sizeof(*src));
138
326k
        if (abits == 8)
139
0
            for (j = 0; j < copy_w; j++)
140
0
                blocks[j] >>= 2;
141
326k
        else
142
5.43M
            for (j = 0; j < copy_w; j++)
143
5.10M
                blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
144
3.13M
        for (j = copy_w; j < slice_width; j++)
145
2.80M
            blocks[j] = blocks[copy_w - 1];
146
326k
        blocks += slice_width;
147
326k
        src    += linesize >> 1;
148
326k
    }
149
59.2k
    for (; i < 16; i++) {
150
36.5k
        memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
151
36.5k
        blocks += slice_width;
152
36.5k
    }
153
22.7k
}
154
155
/**
156
 * Write an unsigned rice/exp golomb codeword.
157
 */
158
static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
159
17.9M
{
160
17.9M
    unsigned int rice_order, exp_order, switch_bits, switch_val;
161
17.9M
    int exponent;
162
163
    /* number of prefix bits to switch between Rice and expGolomb */
164
17.9M
    switch_bits = (codebook & 3) + 1;
165
17.9M
    rice_order  =  codebook >> 5;       /* rice code order */
166
17.9M
    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
167
168
17.9M
    switch_val  = switch_bits << rice_order;
169
170
17.9M
    if (val >= switch_val) {
171
8.86M
        val -= switch_val - (1 << exp_order);
172
8.86M
        exponent = av_log2(val);
173
174
8.86M
        put_bits(pb, exponent - exp_order + switch_bits, 0);
175
8.86M
        put_bits(pb, exponent + 1, val);
176
9.13M
    } else {
177
9.13M
        exponent = val >> rice_order;
178
179
9.13M
        if (exponent)
180
2.02M
            put_bits(pb, exponent, 0);
181
9.13M
        put_bits(pb, 1, 1);
182
9.13M
        if (rice_order)
183
840k
            put_sbits(pb, rice_order, val);
184
9.13M
    }
185
17.9M
}
186
187
35.2M
#define GET_SIGN(x)  ((x) >> 31)
188
13.9M
#define MAKE_CODE(x) (((x) * 2) ^ GET_SIGN(x))
189
190
static void encode_dcs(PutBitContext *pb, int16_t *blocks,
191
                       int blocks_per_slice, int scale)
192
66.7k
{
193
66.7k
    int i;
194
66.7k
    int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
195
196
66.7k
    prev_dc = (blocks[0] - 0x4000) / scale;
197
66.7k
    encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
198
66.7k
    sign     = 0;
199
66.7k
    blocks  += 64;
200
201
526k
    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
202
460k
        dc       = (blocks[0] - 0x4000) / scale;
203
460k
        delta    = dc - prev_dc;
204
460k
        new_sign = GET_SIGN(delta);
205
460k
        delta    = (delta ^ sign) - sign;
206
460k
        code     = MAKE_CODE(delta);
207
460k
        encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
208
460k
        codebook = FFMIN(code, 6);
209
460k
        sign     = new_sign;
210
460k
        prev_dc  = dc;
211
460k
    }
212
66.7k
}
213
214
static void encode_acs(PutBitContext *pb, int16_t *blocks,
215
                       int blocks_per_slice,
216
                       const uint8_t *scan, const int16_t *qmat)
217
66.7k
{
218
66.7k
    int idx, i;
219
66.7k
    int prev_run = 4;
220
66.7k
    int prev_level = 2;
221
66.7k
    int run = 0, level;
222
66.7k
    int max_coeffs, abs_level;
223
66.7k
    max_coeffs = blocks_per_slice << 6;
224
225
4.27M
    for (i = 1; i < 64; i++) {
226
37.3M
        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
227
33.1M
            level = blocks[idx] / qmat[scan[i]];
228
33.1M
            if (level) {
229
8.73M
                abs_level = FFABS(level);
230
8.73M
                encode_vlc_codeword(pb, ff_prores_run_to_cb[prev_run], run);
231
8.73M
                encode_vlc_codeword(pb, ff_prores_level_to_cb[prev_level], abs_level - 1);
232
8.73M
                put_sbits(pb, 1, GET_SIGN(level));
233
234
8.73M
                prev_run   = FFMIN(run, 15);
235
8.73M
                prev_level = FFMIN(abs_level, 9);
236
8.73M
                run        = 0;
237
24.4M
            } else {
238
24.4M
                run++;
239
24.4M
            }
240
33.1M
        }
241
4.20M
    }
242
66.7k
}
243
244
static void encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
245
                              const uint16_t *src, ptrdiff_t linesize,
246
                              int mbs_per_slice, int16_t *blocks,
247
                              int blocks_per_mb,
248
                              const int16_t *qmat)
249
66.7k
{
250
66.7k
    int blocks_per_slice = mbs_per_slice * blocks_per_mb;
251
252
66.7k
    encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
253
66.7k
    encode_acs(pb, blocks, blocks_per_slice, ctx->scantable, qmat);
254
66.7k
}
255
256
static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
257
368k
{
258
368k
    const int dbits = (abits == 8) ? 4 : 7;
259
368k
    const int dsize = 1 << dbits - 1;
260
368k
    int diff = cur - prev;
261
262
368k
    diff = av_zero_extend(diff, abits);
263
368k
    if (diff >= (1 << abits) - dsize)
264
19.0k
        diff -= 1 << abits;
265
368k
    if (diff < -dsize || diff > dsize || !diff) {
266
321k
        put_bits(pb, 1, 1);
267
321k
        put_bits(pb, abits, diff);
268
321k
    } else {
269
46.4k
        put_bits(pb, 1, 0);
270
46.4k
        put_bits(pb, dbits - 1, FFABS(diff) - 1);
271
46.4k
        put_bits(pb, 1, diff < 0);
272
46.4k
    }
273
368k
}
274
275
static void put_alpha_run(PutBitContext *pb, int run)
276
368k
{
277
368k
    if (run) {
278
139k
        put_bits(pb, 1, 0);
279
139k
        if (run < 0x10)
280
127k
            put_bits(pb, 4, run);
281
12.5k
        else
282
12.5k
            put_bits(pb, 15, run);
283
228k
    } else {
284
228k
        put_bits(pb, 1, 1);
285
228k
    }
286
368k
}
287
288
// todo alpha quantisation for high quants
289
static void encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
290
                              int mbs_per_slice, uint16_t *blocks,
291
                              int quant)
292
11.3k
{
293
11.3k
    const int abits = ctx->alpha_bits;
294
11.3k
    const int mask  = (1 << abits) - 1;
295
11.3k
    const int num_coeffs = mbs_per_slice * 256;
296
11.3k
    int prev = mask, cur;
297
11.3k
    int idx = 0;
298
11.3k
    int run = 0;
299
300
11.3k
    cur = blocks[idx++];
301
11.3k
    put_alpha_diff(pb, cur, prev, abits);
302
11.3k
    prev = cur;
303
4.91M
    do {
304
4.91M
        cur = blocks[idx++];
305
4.91M
        if (cur != prev) {
306
356k
            put_alpha_run (pb, run);
307
356k
            put_alpha_diff(pb, cur, prev, abits);
308
356k
            prev = cur;
309
356k
            run  = 0;
310
4.55M
        } else {
311
4.55M
            run++;
312
4.55M
        }
313
4.91M
    } while (idx < num_coeffs);
314
11.3k
    put_alpha_run(pb, run);
315
11.3k
}
316
317
static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
318
                        PutBitContext *pb,
319
                        int sizes[4], int x, int y, int quant,
320
                        int mbs_per_slice)
321
22.2k
{
322
22.2k
    ProresContext *ctx = avctx->priv_data;
323
22.2k
    int i, xp, yp;
324
22.2k
    int total_size = 0;
325
22.2k
    const uint16_t *src;
326
22.2k
    int num_cblocks, pwidth, line_add;
327
22.2k
    ptrdiff_t linesize;
328
22.2k
    int is_chroma;
329
22.2k
    uint16_t *qmat;
330
22.2k
    uint16_t *qmat_chroma;
331
332
22.2k
    if (ctx->pictures_per_frame == 1)
333
22.2k
        line_add = 0;
334
0
    else
335
0
        line_add = ctx->cur_picture_idx ^ !(pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
336
337
22.2k
    if (ctx->force_quant) {
338
0
        qmat = ctx->quants[0];
339
0
        qmat_chroma = ctx->quants_chroma[0];
340
22.2k
    } else if (quant < MAX_STORED_Q) {
341
18.1k
        qmat = ctx->quants[quant];
342
18.1k
        qmat_chroma = ctx->quants_chroma[quant];
343
18.1k
    } else {
344
4.07k
        qmat = ctx->custom_q;
345
4.07k
        qmat_chroma = ctx->custom_chroma_q;
346
264k
        for (i = 0; i < 64; i++) {
347
260k
            qmat[i] = ctx->quant_mat[i] * quant;
348
260k
            qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
349
260k
        }
350
4.07k
    }
351
352
100k
    for (i = 0; i < ctx->num_planes; i++) {
353
78.0k
        is_chroma    = (i == 1 || i == 2);
354
78.0k
        if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
355
60.8k
            xp          = x << 4;
356
60.8k
            yp          = y << 4;
357
60.8k
            num_cblocks = 4;
358
60.8k
            pwidth      = avctx->width;
359
60.8k
        } else {
360
17.2k
            xp          = x << 3;
361
17.2k
            yp          = y << 4;
362
17.2k
            num_cblocks = 2;
363
17.2k
            pwidth      = avctx->width >> 1;
364
17.2k
        }
365
366
78.0k
        linesize = pic->linesize[i] * ctx->pictures_per_frame;
367
78.0k
        src = (const uint16_t*)(pic->data[i] + yp * linesize +
368
78.0k
                                line_add * pic->linesize[i]) + xp;
369
370
78.0k
        if (i < 3) {
371
66.7k
            get_slice_data(ctx, src, linesize, xp, yp,
372
66.7k
                           pwidth, avctx->height / ctx->pictures_per_frame,
373
66.7k
                           ctx->blocks[0], ctx->emu_buf,
374
66.7k
                           mbs_per_slice, num_cblocks, is_chroma);
375
66.7k
            if (!is_chroma) {/* luma quant */
376
22.2k
                encode_slice_plane(ctx, pb, src, linesize,
377
22.2k
                                   mbs_per_slice, ctx->blocks[0],
378
22.2k
                                   num_cblocks, qmat);
379
44.4k
            } else { /* chroma plane */
380
44.4k
                encode_slice_plane(ctx, pb, src, linesize,
381
44.4k
                                   mbs_per_slice, ctx->blocks[0],
382
44.4k
                                   num_cblocks, qmat_chroma);
383
44.4k
            }
384
66.7k
        } else {
385
11.3k
            get_alpha_data(ctx, src, linesize, xp, yp,
386
11.3k
                           pwidth, avctx->height / ctx->pictures_per_frame,
387
11.3k
                           ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
388
11.3k
            encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
389
11.3k
        }
390
78.0k
        flush_put_bits(pb);
391
78.0k
        sizes[i]   = put_bytes_output(pb) - total_size;
392
78.0k
        total_size = put_bytes_output(pb);
393
78.0k
    }
394
22.2k
    return total_size;
395
22.2k
}
396
397
static inline int estimate_vlc(unsigned codebook, int val)
398
760M
{
399
760M
    unsigned int rice_order, exp_order, switch_bits, switch_val;
400
760M
    int exponent;
401
402
    /* number of prefix bits to switch between Rice and expGolomb */
403
760M
    switch_bits = (codebook & 3) + 1;
404
760M
    rice_order  =  codebook >> 5;       /* rice code order */
405
760M
    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
406
407
760M
    switch_val  = switch_bits << rice_order;
408
409
760M
    if (val >= switch_val) {
410
363M
        val -= switch_val - (1 << exp_order);
411
363M
        exponent = av_log2(val);
412
413
363M
        return exponent * 2 - exp_order + switch_bits + 1;
414
397M
    } else {
415
397M
        return (val >> rice_order) + rice_order + 1;
416
397M
    }
417
760M
}
418
419
static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
420
                        int scale)
421
1.37M
{
422
1.37M
    int i;
423
1.37M
    int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
424
1.37M
    int bits;
425
426
1.37M
    prev_dc  = (blocks[0] - 0x4000) / scale;
427
1.37M
    bits     = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
428
1.37M
    sign     = 0;
429
1.37M
    blocks  += 64;
430
1.37M
    *error  += FFABS(blocks[0] - 0x4000) % scale;
431
432
13.4M
    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
433
12.0M
        dc       = (blocks[0] - 0x4000) / scale;
434
12.0M
        *error  += FFABS(blocks[0] - 0x4000) % scale;
435
12.0M
        delta    = dc - prev_dc;
436
12.0M
        new_sign = GET_SIGN(delta);
437
12.0M
        delta    = (delta ^ sign) - sign;
438
12.0M
        code     = MAKE_CODE(delta);
439
12.0M
        bits    += estimate_vlc(ff_prores_dc_codebook[codebook], code);
440
12.0M
        codebook = FFMIN(code, 6);
441
12.0M
        sign     = new_sign;
442
12.0M
        prev_dc  = dc;
443
12.0M
    }
444
445
1.37M
    return bits;
446
1.37M
}
447
448
static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
449
                        const uint8_t *scan, const int16_t *qmat)
450
1.37M
{
451
1.37M
    int idx, i;
452
1.37M
    int prev_run = 4;
453
1.37M
    int prev_level = 2;
454
1.37M
    int run, level;
455
1.37M
    int max_coeffs, abs_level;
456
1.37M
    int bits = 0;
457
458
1.37M
    max_coeffs = blocks_per_slice << 6;
459
1.37M
    run        = 0;
460
461
87.7M
    for (i = 1; i < 64; i++) {
462
932M
        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
463
845M
            level   = blocks[idx] / qmat[scan[i]];
464
845M
            *error += FFABS(blocks[idx]) % qmat[scan[i]];
465
845M
            if (level) {
466
373M
                abs_level = FFABS(level);
467
373M
                bits += estimate_vlc(ff_prores_run_to_cb[prev_run], run);
468
373M
                bits += estimate_vlc(ff_prores_level_to_cb[prev_level],
469
373M
                                     abs_level - 1) + 1;
470
373M
                prev_run   = FFMIN(run, 15);
471
373M
                prev_level = FFMIN(abs_level, 9);
472
373M
                run    = 0;
473
472M
            } else {
474
472M
                run++;
475
472M
            }
476
845M
        }
477
86.3M
    }
478
479
1.37M
    return bits;
480
1.37M
}
481
482
static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
483
                                const uint16_t *src, ptrdiff_t linesize,
484
                                int mbs_per_slice,
485
                                int blocks_per_mb,
486
                                const int16_t *qmat, ProresThreadData *td)
487
1.37M
{
488
1.37M
    int blocks_per_slice;
489
1.37M
    int bits;
490
491
1.37M
    blocks_per_slice = mbs_per_slice * blocks_per_mb;
492
493
1.37M
    bits  = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
494
1.37M
    bits += estimate_acs(error, td->blocks[plane], blocks_per_slice, ctx->scantable, qmat);
495
496
1.37M
    return FFALIGN(bits, 8);
497
1.37M
}
498
499
static int est_alpha_diff(int cur, int prev, int abits)
500
368k
{
501
368k
    const int dbits = (abits == 8) ? 4 : 7;
502
368k
    const int dsize = 1 << dbits - 1;
503
368k
    int diff = cur - prev;
504
505
368k
    diff = av_zero_extend(diff, abits);
506
368k
    if (diff >= (1 << abits) - dsize)
507
19.0k
        diff -= 1 << abits;
508
368k
    if (diff < -dsize || diff > dsize || !diff)
509
321k
        return abits + 1;
510
46.4k
    else
511
46.4k
        return dbits + 1;
512
368k
}
513
514
static int estimate_alpha_plane(ProresContext *ctx,
515
                                const uint16_t *src, ptrdiff_t linesize,
516
                                int mbs_per_slice, int16_t *blocks)
517
11.3k
{
518
11.3k
    const int abits = ctx->alpha_bits;
519
11.3k
    const int mask  = (1 << abits) - 1;
520
11.3k
    const int num_coeffs = mbs_per_slice * 256;
521
11.3k
    int prev = mask, cur;
522
11.3k
    int idx = 0;
523
11.3k
    int run = 0;
524
11.3k
    int bits;
525
526
11.3k
    cur = blocks[idx++];
527
11.3k
    bits = est_alpha_diff(cur, prev, abits);
528
11.3k
    prev = cur;
529
4.91M
    do {
530
4.91M
        cur = blocks[idx++];
531
4.91M
        if (cur != prev) {
532
356k
            if (!run)
533
227k
                bits++;
534
128k
            else if (run < 0x10)
535
125k
                bits += 4;
536
2.96k
            else
537
2.96k
                bits += 15;
538
356k
            bits += est_alpha_diff(cur, prev, abits);
539
356k
            prev = cur;
540
356k
            run  = 0;
541
4.55M
        } else {
542
4.55M
            run++;
543
4.55M
        }
544
4.91M
    } while (idx < num_coeffs);
545
546
11.3k
    if (run) {
547
10.6k
        if (run < 0x10)
548
1.11k
            bits += 4;
549
9.56k
        else
550
9.56k
            bits += 15;
551
10.6k
    }
552
553
11.3k
    return bits;
554
11.3k
}
555
556
static int find_slice_quant(AVCodecContext *avctx,
557
                            int trellis_node, int x, int y, int mbs_per_slice,
558
                            ProresThreadData *td)
559
22.2k
{
560
22.2k
    ProresContext *ctx = avctx->priv_data;
561
22.2k
    int i, q, pq, xp, yp;
562
22.2k
    const uint16_t *src;
563
22.2k
    int num_cblocks[MAX_PLANES], pwidth;
564
22.2k
    int is_chroma[MAX_PLANES];
565
22.2k
    const int min_quant = ctx->profile_info->min_quant;
566
22.2k
    const int max_quant = ctx->profile_info->max_quant;
567
22.2k
    int error, bits, bits_limit;
568
22.2k
    int mbs, prev, cur, new_score;
569
22.2k
    int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
570
22.2k
    int overquant;
571
22.2k
    uint16_t *qmat;
572
22.2k
    uint16_t *qmat_chroma;
573
22.2k
    int linesize[4], line_add;
574
22.2k
    int alpha_bits = 0;
575
576
22.2k
    if (ctx->pictures_per_frame == 1)
577
22.2k
        line_add = 0;
578
0
    else
579
0
        line_add = ctx->cur_picture_idx ^ !(ctx->pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
580
22.2k
    mbs = x + mbs_per_slice;
581
582
100k
    for (i = 0; i < ctx->num_planes; i++) {
583
78.0k
        is_chroma[i]    = (i == 1 || i == 2);
584
78.0k
        if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
585
60.8k
            xp             = x << 4;
586
60.8k
            yp             = y << 4;
587
60.8k
            num_cblocks[i] = 4;
588
60.8k
            pwidth         = avctx->width;
589
60.8k
        } else {
590
17.2k
            xp             = x << 3;
591
17.2k
            yp             = y << 4;
592
17.2k
            num_cblocks[i] = 2;
593
17.2k
            pwidth         = avctx->width >> 1;
594
17.2k
        }
595
596
78.0k
        linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
597
78.0k
        src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
598
78.0k
                                 line_add * ctx->pic->linesize[i]) + xp;
599
600
78.0k
        if (i < 3) {
601
66.7k
            get_slice_data(ctx, src, linesize[i], xp, yp,
602
66.7k
                           pwidth, avctx->height / ctx->pictures_per_frame,
603
66.7k
                           td->blocks[i], td->emu_buf,
604
66.7k
                           mbs_per_slice, num_cblocks[i], is_chroma[i]);
605
66.7k
        } else {
606
11.3k
            get_alpha_data(ctx, src, linesize[i], xp, yp,
607
11.3k
                           pwidth, avctx->height / ctx->pictures_per_frame,
608
11.3k
                           td->blocks[i], mbs_per_slice, ctx->alpha_bits);
609
11.3k
        }
610
78.0k
    }
611
612
177k
    for (q = min_quant; q < max_quant + 2; q++) {
613
155k
        td->nodes[trellis_node + q].prev_node = -1;
614
155k
        td->nodes[trellis_node + q].quant     = q;
615
155k
    }
616
617
22.2k
    if (ctx->alpha_bits)
618
11.3k
        alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
619
11.3k
                                          mbs_per_slice, td->blocks[3]);
620
    // todo: maybe perform coarser quantising to fit into frame size when needed
621
155k
    for (q = min_quant; q <= max_quant; q++) {
622
133k
        bits  = alpha_bits;
623
133k
        error = 0;
624
133k
        bits += estimate_slice_plane(ctx, &error, 0,
625
133k
                                     src, linesize[0],
626
133k
                                     mbs_per_slice,
627
133k
                                     num_cblocks[0],
628
133k
                                     ctx->quants[q], td); /* estimate luma plane */
629
400k
        for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
630
266k
            bits += estimate_slice_plane(ctx, &error, i,
631
266k
                                         src, linesize[i],
632
266k
                                         mbs_per_slice,
633
266k
                                         num_cblocks[i],
634
266k
                                         ctx->quants_chroma[q], td);
635
266k
        }
636
133k
        if (bits > 65000 * 8)
637
0
            error = SCORE_LIMIT;
638
639
133k
        slice_bits[q]  = bits;
640
133k
        slice_score[q] = error;
641
133k
    }
642
22.2k
    if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
643
17.2k
        slice_bits[max_quant + 1]  = slice_bits[max_quant];
644
17.2k
        slice_score[max_quant + 1] = slice_score[max_quant] + 1;
645
17.2k
        overquant = max_quant;
646
17.2k
    } else {
647
325k
        for (q = max_quant + 1; q < 128; q++) {
648
323k
            bits  = alpha_bits;
649
323k
            error = 0;
650
323k
            if (q < MAX_STORED_Q) {
651
41.7k
                qmat = ctx->quants[q];
652
41.7k
                qmat_chroma = ctx->quants_chroma[q];
653
281k
            } else {
654
281k
                qmat = td->custom_q;
655
281k
                qmat_chroma = td->custom_chroma_q;
656
18.3M
                for (i = 0; i < 64; i++) {
657
18.0M
                    qmat[i] = ctx->quant_mat[i] * q;
658
18.0M
                    qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
659
18.0M
                }
660
281k
            }
661
323k
            bits += estimate_slice_plane(ctx, &error, 0,
662
323k
                                         src, linesize[0],
663
323k
                                         mbs_per_slice,
664
323k
                                         num_cblocks[0],
665
323k
                                         qmat, td);/* estimate luma plane */
666
970k
            for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
667
646k
                bits += estimate_slice_plane(ctx, &error, i,
668
646k
                                             src, linesize[i],
669
646k
                                             mbs_per_slice,
670
646k
                                             num_cblocks[i],
671
646k
                                             qmat_chroma, td);
672
646k
            }
673
323k
            if (bits <= ctx->bits_per_mb * mbs_per_slice)
674
3.28k
                break;
675
323k
        }
676
677
4.98k
        slice_bits[max_quant + 1]  = bits;
678
4.98k
        slice_score[max_quant + 1] = error;
679
4.98k
        overquant = q;
680
4.98k
    }
681
22.2k
    td->nodes[trellis_node + max_quant + 1].quant = overquant;
682
683
22.2k
    bits_limit = mbs * ctx->bits_per_mb;
684
177k
    for (pq = min_quant; pq < max_quant + 2; pq++) {
685
155k
        prev = trellis_node - TRELLIS_WIDTH + pq;
686
687
1.24M
        for (q = min_quant; q < max_quant + 2; q++) {
688
1.08M
            cur = trellis_node + q;
689
1.08M
            bits  = td->nodes[prev].bits + slice_bits[q];
690
1.08M
            error = slice_score[q];
691
1.08M
            if (bits > bits_limit)
692
233k
                error = SCORE_LIMIT;
693
694
1.08M
            if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
695
855k
                new_score = td->nodes[prev].score + error;
696
234k
            else
697
234k
                new_score = SCORE_LIMIT;
698
1.08M
            if (td->nodes[cur].prev_node == -1 ||
699
1.02M
                td->nodes[cur].score >= new_score) {
700
701
1.02M
                td->nodes[cur].bits      = bits;
702
1.02M
                td->nodes[cur].score     = new_score;
703
1.02M
                td->nodes[cur].prev_node = prev;
704
1.02M
            }
705
1.08M
        }
706
155k
    }
707
708
22.2k
    error = td->nodes[trellis_node + min_quant].score;
709
22.2k
    pq    = trellis_node + min_quant;
710
155k
    for (q = min_quant + 1; q < max_quant + 2; q++) {
711
133k
        if (td->nodes[trellis_node + q].score <= error) {
712
44.5k
            error = td->nodes[trellis_node + q].score;
713
44.5k
            pq    = trellis_node + q;
714
44.5k
        }
715
133k
    }
716
717
22.2k
    return pq;
718
22.2k
}
719
720
static int find_quant_thread(AVCodecContext *avctx, void *arg,
721
                             int jobnr, int threadnr)
722
18.4k
{
723
18.4k
    ProresContext *ctx = avctx->priv_data;
724
18.4k
    ProresThreadData *td = ctx->tdata + threadnr;
725
18.4k
    int mbs_per_slice = ctx->mbs_per_slice;
726
18.4k
    int x, y = jobnr, mb, q = 0;
727
728
40.6k
    for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
729
72.7k
        while (ctx->mb_width - x < mbs_per_slice)
730
50.4k
            mbs_per_slice >>= 1;
731
22.2k
        q = find_slice_quant(avctx,
732
22.2k
                             (mb + 1) * TRELLIS_WIDTH, x, y,
733
22.2k
                             mbs_per_slice, td);
734
22.2k
    }
735
736
40.6k
    for (x = ctx->slices_width - 1; x >= 0; x--) {
737
22.2k
        ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
738
22.2k
        q = td->nodes[q].prev_node;
739
22.2k
    }
740
741
18.4k
    return 0;
742
18.4k
}
743
744
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
745
                        const AVFrame *pic, int *got_packet)
746
6.38k
{
747
6.38k
    ProresContext *ctx = avctx->priv_data;
748
6.38k
    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
749
6.38k
    uint8_t *picture_size_pos;
750
6.38k
    PutBitContext pb;
751
6.38k
    int x, y, i, mb, q = 0;
752
6.38k
    int sizes[4] = { 0 };
753
6.38k
    int slice_hdr_size = 2 * ctx->num_planes;
754
6.38k
    int frame_size, picture_size, slice_size;
755
6.38k
    int pkt_size, ret;
756
6.38k
    int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
757
6.38k
    uint8_t frame_flags;
758
759
6.38k
    ctx->pic = pic;
760
6.38k
    pkt_size = ctx->frame_size_upper_bound;
761
762
6.38k
    if ((ret = ff_alloc_packet(avctx, pkt, pkt_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
763
0
        return ret;
764
765
6.38k
    orig_buf = pkt->data;
766
767
    // frame atom
768
6.38k
    orig_buf += 4;                              // frame size
769
6.38k
    bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID
770
6.38k
    buf = orig_buf;
771
772
    // frame header
773
6.38k
    tmp = buf;
774
6.38k
    buf += 2;                                   // frame header size will be stored here
775
6.38k
    bytestream_put_be16  (&buf, ctx->chroma_factor != CFACTOR_Y422 || ctx->alpha_bits ? 1 : 0);
776
6.38k
    bytestream_put_buffer(&buf, ctx->vendor, 4);
777
6.38k
    bytestream_put_be16  (&buf, avctx->width);
778
6.38k
    bytestream_put_be16  (&buf, avctx->height);
779
780
6.38k
    frame_flags = ctx->chroma_factor << 6;
781
6.38k
    if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
782
0
        frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
783
6.38k
    bytestream_put_byte  (&buf, frame_flags);
784
785
6.38k
    bytestream_put_byte  (&buf, 0);             // reserved
786
6.38k
    bytestream_put_byte  (&buf, pic->color_primaries);
787
6.38k
    bytestream_put_byte  (&buf, pic->color_trc);
788
6.38k
    bytestream_put_byte  (&buf, pic->colorspace);
789
6.38k
    bytestream_put_byte  (&buf, ctx->alpha_bits >> 3);
790
6.38k
    bytestream_put_byte  (&buf, 0);             // reserved
791
6.38k
    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
792
6.38k
        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
793
6.38k
        bytestream_put_buffer(&buf, ctx->quant_mat, 64);        // luma quantisation matrix
794
6.38k
        bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
795
6.38k
    } else {
796
0
        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
797
0
    }
798
6.38k
    bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size
799
800
6.38k
    for (ctx->cur_picture_idx = 0;
801
12.7k
         ctx->cur_picture_idx < ctx->pictures_per_frame;
802
6.38k
         ctx->cur_picture_idx++) {
803
        // picture header
804
6.38k
        picture_size_pos = buf + 1;
805
6.38k
        bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)
806
6.38k
        buf += 4;                                   // picture data size will be stored here
807
6.38k
        bytestream_put_be16  (&buf, ctx->slices_per_picture);
808
6.38k
        bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
809
810
        // seek table - will be filled during slice encoding
811
6.38k
        slice_sizes = buf;
812
6.38k
        buf += ctx->slices_per_picture * 2;
813
814
        // slices
815
6.38k
        if (!ctx->force_quant) {
816
6.38k
            ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
817
6.38k
                                  ctx->mb_height);
818
6.38k
            if (ret)
819
0
                return ret;
820
6.38k
        }
821
822
24.8k
        for (y = 0; y < ctx->mb_height; y++) {
823
18.4k
            int mbs_per_slice = ctx->mbs_per_slice;
824
40.6k
            for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
825
22.2k
                q = ctx->force_quant ? ctx->force_quant
826
22.2k
                                     : ctx->slice_q[mb + y * ctx->slices_width];
827
828
72.7k
                while (ctx->mb_width - x < mbs_per_slice)
829
50.4k
                    mbs_per_slice >>= 1;
830
831
22.2k
                bytestream_put_byte(&buf, slice_hdr_size << 3);
832
22.2k
                slice_hdr = buf;
833
22.2k
                buf += slice_hdr_size - 1;
834
22.2k
                if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
835
49
                    uint8_t *start = pkt->data;
836
                    // Recompute new size according to max_slice_size
837
                    // and deduce delta
838
49
                    int delta = 200 + (ctx->pictures_per_frame *
839
49
                                ctx->slices_per_picture + 1) *
840
49
                                max_slice_size - pkt_size;
841
842
49
                    delta = FFMAX(delta, 2 * max_slice_size);
843
49
                    ctx->frame_size_upper_bound += delta;
844
845
49
                    if (!ctx->warn) {
846
25
                        avpriv_request_sample(avctx,
847
25
                                              "Packet too small: is %i,"
848
25
                                              " needs %i (slice: %i). "
849
25
                                              "Correct allocation",
850
25
                                              pkt_size, delta, max_slice_size);
851
25
                        ctx->warn = 1;
852
25
                    }
853
854
49
                    ret = av_grow_packet(pkt, delta);
855
49
                    if (ret < 0)
856
0
                        return ret;
857
858
49
                    pkt_size += delta;
859
49
                    orig_buf         = pkt->data + (orig_buf         - start);
860
49
                    buf              = pkt->data + (buf              - start);
861
49
                    picture_size_pos = pkt->data + (picture_size_pos - start);
862
49
                    slice_sizes      = pkt->data + (slice_sizes      - start);
863
49
                    slice_hdr        = pkt->data + (slice_hdr        - start);
864
49
                    tmp              = pkt->data + (tmp              - start);
865
49
                }
866
22.2k
                init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
867
22.2k
                ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
868
22.2k
                                   mbs_per_slice);
869
22.2k
                if (ret < 0)
870
0
                    return ret;
871
872
22.2k
                bytestream_put_byte(&slice_hdr, q);
873
22.2k
                slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
874
78.0k
                for (i = 0; i < ctx->num_planes - 1; i++) {
875
55.8k
                    bytestream_put_be16(&slice_hdr, sizes[i]);
876
55.8k
                    slice_size += sizes[i];
877
55.8k
                }
878
22.2k
                bytestream_put_be16(&slice_sizes, slice_size);
879
22.2k
                buf += slice_size - slice_hdr_size;
880
22.2k
                if (max_slice_size < slice_size)
881
174
                    max_slice_size = slice_size;
882
22.2k
            }
883
18.4k
        }
884
885
6.38k
        picture_size = buf - (picture_size_pos - 1);
886
6.38k
        bytestream_put_be32(&picture_size_pos, picture_size);
887
6.38k
    }
888
889
6.38k
    orig_buf -= 8;
890
6.38k
    frame_size = buf - orig_buf;
891
6.38k
    bytestream_put_be32(&orig_buf, frame_size);
892
893
6.38k
    pkt->size   = frame_size;
894
6.38k
    *got_packet = 1;
895
896
6.38k
    return 0;
897
6.38k
}
898
899
static av_cold int encode_close(AVCodecContext *avctx)
900
126
{
901
126
    ProresContext *ctx = avctx->priv_data;
902
126
    int i;
903
904
126
    if (ctx->tdata) {
905
252
        for (i = 0; i < avctx->thread_count; i++)
906
126
            av_freep(&ctx->tdata[i].nodes);
907
126
    }
908
126
    av_freep(&ctx->tdata);
909
126
    av_freep(&ctx->slice_q);
910
911
126
    return 0;
912
126
}
913
914
static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
915
                        ptrdiff_t linesize, int16_t *block)
916
1.04M
{
917
1.04M
    int x, y;
918
1.04M
    const uint16_t *tsrc = src;
919
920
9.42M
    for (y = 0; y < 8; y++) {
921
75.3M
        for (x = 0; x < 8; x++)
922
67.0M
            block[y * 8 + x] = tsrc[x];
923
8.37M
        tsrc += linesize >> 1;
924
8.37M
    }
925
1.04M
    fdsp->fdct(block);
926
1.04M
}
927
928
static av_cold int encode_init(AVCodecContext *avctx)
929
126
{
930
126
    ProresContext *ctx = avctx->priv_data;
931
126
    int err = 0, i, j, min_quant, max_quant;
932
933
126
    err = ff_prores_kostya_encode_init(avctx, ctx, avctx->pix_fmt);
934
126
    if (err < 0)
935
0
        return err;
936
937
126
    ctx->fdct      = prores_fdct;
938
126
    ff_fdctdsp_init(&ctx->fdsp, avctx);
939
940
126
    if (!ctx->force_quant) {
941
126
        min_quant = ctx->profile_info->min_quant;
942
126
        max_quant = ctx->profile_info->max_quant;
943
944
126
        ctx->slice_q = av_malloc_array(ctx->slices_per_picture, sizeof(*ctx->slice_q));
945
126
        if (!ctx->slice_q)
946
0
            return AVERROR(ENOMEM);
947
948
126
        ctx->tdata = av_calloc(avctx->thread_count, sizeof(*ctx->tdata));
949
126
        if (!ctx->tdata)
950
0
            return AVERROR(ENOMEM);
951
952
252
        for (j = 0; j < avctx->thread_count; j++) {
953
126
            ctx->tdata[j].nodes = av_malloc_array(ctx->slices_width + 1,
954
126
                                                  TRELLIS_WIDTH
955
126
                                                  * sizeof(*ctx->tdata->nodes));
956
126
            if (!ctx->tdata[j].nodes)
957
0
                return AVERROR(ENOMEM);
958
1.00k
            for (i = min_quant; i < max_quant + 2; i++) {
959
882
                ctx->tdata[j].nodes[i].prev_node = -1;
960
882
                ctx->tdata[j].nodes[i].bits      = 0;
961
882
                ctx->tdata[j].nodes[i].score     = 0;
962
882
            }
963
126
        }
964
126
    }
965
966
126
    return 0;
967
126
}
968
969
#define OFFSET(x) offsetof(ProresContext, x)
970
#define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
971
972
static const AVOption options[] = {
973
    { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
974
        AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
975
    { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
976
        { .i64 = PRORES_PROFILE_AUTO },
977
        PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, .unit = "profile" },
978
    { "auto",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
979
        0, 0, VE, .unit = "profile" },
980
    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
981
        0, 0, VE, .unit = "profile" },
982
    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
983
        0, 0, VE, .unit = "profile" },
984
    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
985
        0, 0, VE, .unit = "profile" },
986
    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
987
        0, 0, VE, .unit = "profile" },
988
    { "4444",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
989
        0, 0, VE, .unit = "profile" },
990
    { "4444xq",        NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
991
        0, 0, VE, .unit = "profile" },
992
    { "vendor", "vendor ID", OFFSET(vendor),
993
        AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
994
    { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
995
        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
996
    { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
997
        { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, .unit = "quant_mat" },
998
    { "auto",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
999
        0, 0, VE, .unit = "quant_mat" },
1000
    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1001
        0, 0, VE, .unit = "quant_mat" },
1002
    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1003
        0, 0, VE, .unit = "quant_mat" },
1004
    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1005
        0, 0, VE, .unit = "quant_mat" },
1006
    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1007
        0, 0, VE, .unit = "quant_mat" },
1008
    { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1009
        0, 0, VE, .unit = "quant_mat" },
1010
    { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1011
        { .i64 = 16 }, 0, 16, VE },
1012
    { NULL }
1013
};
1014
1015
static const AVClass proresenc_class = {
1016
    .class_name = "ProRes encoder",
1017
    .item_name  = av_default_item_name,
1018
    .option     = options,
1019
    .version    = LIBAVUTIL_VERSION_INT,
1020
};
1021
1022
const FFCodec ff_prores_ks_encoder = {
1023
    .p.name         = "prores_ks",
1024
    CODEC_LONG_NAME("Apple ProRes (iCodec Pro)"),
1025
    .p.type         = AVMEDIA_TYPE_VIDEO,
1026
    .p.id           = AV_CODEC_ID_PRORES,
1027
    .priv_data_size = sizeof(ProresContext),
1028
    .init           = encode_init,
1029
    .close          = encode_close,
1030
    FF_CODEC_ENCODE_CB(encode_frame),
1031
    .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
1032
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1033
    CODEC_PIXFMTS(AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10),
1034
    .color_ranges   = AVCOL_RANGE_MPEG,
1035
    .p.priv_class   = &proresenc_class,
1036
    .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
1037
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1038
};