GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/proresenc_anatoliy.c Lines: 340 437 77.8 %
Date: 2020-10-23 17:01:47 Branches: 135 198 68.2 %

Line Branch Exec 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
/**
25
 * @file
26
 * Apple ProRes encoder (Anatoliy Wasserman version)
27
 * Known FOURCCs: 'ap4h' (444), 'apch' (HQ), 'apcn' (422), 'apcs' (LT), 'acpo' (Proxy)
28
 */
29
30
#include "libavutil/opt.h"
31
#include "avcodec.h"
32
#include "dct.h"
33
#include "internal.h"
34
#include "profiles.h"
35
#include "proresdata.h"
36
#include "put_bits.h"
37
#include "bytestream.h"
38
#include "fdctdsp.h"
39
40
#define DEFAULT_SLICE_MB_WIDTH 8
41
42
static const AVProfile profiles[] = {
43
    { FF_PROFILE_PRORES_PROXY,    "apco"},
44
    { FF_PROFILE_PRORES_LT,       "apcs"},
45
    { FF_PROFILE_PRORES_STANDARD, "apcn"},
46
    { FF_PROFILE_PRORES_HQ,       "apch"},
47
    { FF_PROFILE_PRORES_4444,     "ap4h"},
48
    { FF_PROFILE_PRORES_XQ,       "ap4x"},
49
    { FF_PROFILE_UNKNOWN }
50
};
51
52
static const int qp_start_table[] = {  8, 3, 2, 1, 1, 1};
53
static const int qp_end_table[]   = { 13, 9, 6, 6, 5, 4};
54
static const int bitrate_table[]  = { 1000, 2100, 3500, 5400, 7000, 10000};
55
56
static const int valid_primaries[]  = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG,
57
                                        AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432, INT_MAX };
58
static const int valid_trc[]        = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_SMPTE2084,
59
                                        AVCOL_TRC_ARIB_STD_B67, INT_MAX };
60
static const int valid_colorspace[] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M,
61
                                        AVCOL_SPC_BT2020_NCL, INT_MAX };
62
63
static const uint8_t QMAT_LUMA[6][64] = {
64
    {
65
         4,  7,  9, 11, 13, 14, 15, 63,
66
         7,  7, 11, 12, 14, 15, 63, 63,
67
         9, 11, 13, 14, 15, 63, 63, 63,
68
        11, 11, 13, 14, 63, 63, 63, 63,
69
        11, 13, 14, 63, 63, 63, 63, 63,
70
        13, 14, 63, 63, 63, 63, 63, 63,
71
        13, 63, 63, 63, 63, 63, 63, 63,
72
        63, 63, 63, 63, 63, 63, 63, 63
73
    }, {
74
         4,  5,  6,  7,  9, 11, 13, 15,
75
         5,  5,  7,  8, 11, 13, 15, 17,
76
         6,  7,  9, 11, 13, 15, 15, 17,
77
         7,  7,  9, 11, 13, 15, 17, 19,
78
         7,  9, 11, 13, 14, 16, 19, 23,
79
         9, 11, 13, 14, 16, 19, 23, 29,
80
         9, 11, 13, 15, 17, 21, 28, 35,
81
        11, 13, 16, 17, 21, 28, 35, 41
82
    }, {
83
         4,  4,  5,  5,  6,  7,  7,  9,
84
         4,  4,  5,  6,  7,  7,  9,  9,
85
         5,  5,  6,  7,  7,  9,  9, 10,
86
         5,  5,  6,  7,  7,  9,  9, 10,
87
         5,  6,  7,  7,  8,  9, 10, 12,
88
         6,  7,  7,  8,  9, 10, 12, 15,
89
         6,  7,  7,  9, 10, 11, 14, 17,
90
         7,  7,  9, 10, 11, 14, 17, 21
91
    }, {
92
         4,  4,  4,  4,  4,  4,  4,  4,
93
         4,  4,  4,  4,  4,  4,  4,  4,
94
         4,  4,  4,  4,  4,  4,  4,  4,
95
         4,  4,  4,  4,  4,  4,  4,  5,
96
         4,  4,  4,  4,  4,  4,  5,  5,
97
         4,  4,  4,  4,  4,  5,  5,  6,
98
         4,  4,  4,  4,  5,  5,  6,  7,
99
         4,  4,  4,  4,  5,  6,  7,  7
100
    }, { /* 444 */
101
        4,  4,  4,  4,  4,  4,  4,  4,
102
        4,  4,  4,  4,  4,  4,  4,  4,
103
        4,  4,  4,  4,  4,  4,  4,  4,
104
        4,  4,  4,  4,  4,  4,  4,  5,
105
        4,  4,  4,  4,  4,  4,  5,  5,
106
        4,  4,  4,  4,  4,  5,  5,  6,
107
        4,  4,  4,  4,  5,  5,  6,  7,
108
        4,  4,  4,  4,  5,  6,  7,  7
109
    }, { /* 444 XQ */
110
        2,  2,  2,  2,  2,  2,  2,  2,
111
        2,  2,  2,  2,  2,  2,  2,  2,
112
        2,  2,  2,  2,  2,  2,  2,  2,
113
        2,  2,  2,  2,  2,  2,  2,  3,
114
        2,  2,  2,  2,  2,  2,  3,  3,
115
        2,  2,  2,  2,  2,  3,  3,  3,
116
        2,  2,  2,  2,  3,  3,  3,  4,
117
        2,  2,  2,  2,  3,  3,  4,  4,
118
    }
119
};
120
121
static const uint8_t QMAT_CHROMA[6][64] = {
122
    {
123
         4,  7,  9, 11, 13, 14, 63, 63,
124
         7,  7, 11, 12, 14, 63, 63, 63,
125
         9, 11, 13, 14, 63, 63, 63, 63,
126
        11, 11, 13, 14, 63, 63, 63, 63,
127
        11, 13, 14, 63, 63, 63, 63, 63,
128
        13, 14, 63, 63, 63, 63, 63, 63,
129
        13, 63, 63, 63, 63, 63, 63, 63,
130
        63, 63, 63, 63, 63, 63, 63, 63
131
    }, {
132
         4,  5,  6,  7,  9, 11, 13, 15,
133
         5,  5,  7,  8, 11, 13, 15, 17,
134
         6,  7,  9, 11, 13, 15, 15, 17,
135
         7,  7,  9, 11, 13, 15, 17, 19,
136
         7,  9, 11, 13, 14, 16, 19, 23,
137
         9, 11, 13, 14, 16, 19, 23, 29,
138
         9, 11, 13, 15, 17, 21, 28, 35,
139
        11, 13, 16, 17, 21, 28, 35, 41
140
    }, {
141
         4,  4,  5,  5,  6,  7,  7,  9,
142
         4,  4,  5,  6,  7,  7,  9,  9,
143
         5,  5,  6,  7,  7,  9,  9, 10,
144
         5,  5,  6,  7,  7,  9,  9, 10,
145
         5,  6,  7,  7,  8,  9, 10, 12,
146
         6,  7,  7,  8,  9, 10, 12, 15,
147
         6,  7,  7,  9, 10, 11, 14, 17,
148
         7,  7,  9, 10, 11, 14, 17, 21
149
    }, {
150
         4,  4,  4,  4,  4,  4,  4,  4,
151
         4,  4,  4,  4,  4,  4,  4,  4,
152
         4,  4,  4,  4,  4,  4,  4,  4,
153
         4,  4,  4,  4,  4,  4,  4,  5,
154
         4,  4,  4,  4,  4,  4,  5,  5,
155
         4,  4,  4,  4,  4,  5,  5,  6,
156
         4,  4,  4,  4,  5,  5,  6,  7,
157
         4,  4,  4,  4,  5,  6,  7,  7
158
    }, { /* 444 */
159
        4,  4,  4,  4,  4,  4,  4,  4,
160
        4,  4,  4,  4,  4,  4,  4,  4,
161
        4,  4,  4,  4,  4,  4,  4,  4,
162
        4,  4,  4,  4,  4,  4,  4,  5,
163
        4,  4,  4,  4,  4,  4,  5,  5,
164
        4,  4,  4,  4,  4,  5,  5,  6,
165
        4,  4,  4,  4,  5,  5,  6,  7,
166
        4,  4,  4,  4,  5,  6,  7,  7
167
    }, { /* 444 xq */
168
        4,  4,  4,  4,  4,  4,  4,  4,
169
        4,  4,  4,  4,  4,  4,  4,  4,
170
        4,  4,  4,  4,  4,  4,  4,  4,
171
        4,  4,  4,  4,  4,  4,  4,  5,
172
        4,  4,  4,  4,  4,  4,  5,  5,
173
        4,  4,  4,  4,  4,  5,  5,  6,
174
        4,  4,  4,  4,  5,  5,  6,  7,
175
        4,  4,  4,  4,  5,  6,  7,  7
176
    }
177
};
178
179
180
typedef struct {
181
    AVClass *class;
182
    FDCTDSPContext fdsp;
183
    uint8_t* fill_y;
184
    uint8_t* fill_u;
185
    uint8_t* fill_v;
186
    uint8_t* fill_a;
187
188
    int qmat_luma[16][64];
189
    int qmat_chroma[16][64];
190
    const uint8_t *scantable;
191
192
    int is_422;
193
    int need_alpha;
194
    int is_interlaced;
195
196
    char *vendor;
197
} ProresContext;
198
199
182338360
static void encode_codeword(PutBitContext *pb, int val, int codebook)
200
{
201
    unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
202
203
    /* number of bits to switch between rice and exp golomb */
204
182338360
    switch_bits = codebook & 3;
205
182338360
    rice_order  = codebook >> 5;
206
182338360
    exp_order   = (codebook >> 2) & 7;
207
208
182338360
    first_exp = ((switch_bits + 1) << rice_order);
209
210
182338360
    if (val >= first_exp) { /* exp golomb */
211
60600805
        val -= first_exp;
212
60600805
        val += (1 << exp_order);
213
60600805
        exp = av_log2(val);
214
60600805
        zeros = exp - exp_order + switch_bits + 1;
215
60600805
        put_bits(pb, zeros, 0);
216
60600805
        put_bits(pb, exp + 1, val);
217
121737555
    } else if (rice_order) {
218
12633930
        put_bits(pb, (val >> rice_order), 0);
219
12633930
        put_bits(pb, 1, 1);
220
12633930
        put_sbits(pb, rice_order, val);
221
    } else {
222
109103625
        put_bits(pb, val, 0);
223
109103625
        put_bits(pb, 1, 1);
224
    }
225
182338360
}
226
227
#define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
228
#define TO_GOLOMB(val) (((val) * 2) ^ ((val) >> 31))
229
#define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
230
#define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
231
#define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
232
233
95520236
static av_always_inline int get_level(int val)
234
{
235
95520236
    int sign = (val >> 31);
236
95520236
    return (val ^ sign) - sign;
237
}
238
239
#define FIRST_DC_CB 0xB8
240
241
static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
242
243
174174
static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
244
        int blocks_per_slice, int *qmat)
245
{
246
    int prev_dc, code;
247
    int i, sign, idx;
248
    int new_dc, delta, diff_sign, new_code;
249
250
174174
    prev_dc = QSCALE(qmat, 0, in[0] - 16384);
251
174174
    code = TO_GOLOMB(prev_dc);
252
174174
    encode_codeword(pb, code, FIRST_DC_CB);
253
254
174174
    code = 5; sign = 0; idx = 64;
255
3149224
    for (i = 1; i < blocks_per_slice; i++, idx += 64) {
256
2975050
        new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
257
2975050
        delta     = new_dc - prev_dc;
258
2975050
        diff_sign = DIFF_SIGN(delta, sign);
259
2975050
        new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
260
261
2975050
        encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
262
263
2975050
        code      = new_code;
264
2975050
        sign      = delta >> 31;
265
2975050
        prev_dc   = new_dc;
266
    }
267
174174
}
268
269
static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
270
        0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
271
static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
272
        0x28, 0x28, 0x28, 0x4C };
273
274
174174
static void encode_ac_coeffs(PutBitContext *pb,
275
        int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
276
{
277
174174
    int prev_run = 4;
278
174174
    int prev_level = 2;
279
280
174174
    int run = 0, level, code, i, j;
281
11147136
    for (i = 1; i < 64; i++) {
282
10972962
        int indp = ff_prores_scan[i];
283
209374074
        for (j = 0; j < blocks_per_slice; j++) {
284
198401112
            int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
285
198401112
            if (val) {
286
89594568
                encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
287
288
89594568
                prev_run   = run;
289
89594568
                run        = 0;
290
89594568
                level      = get_level(val);
291
89594568
                code       = level - 1;
292
293
89594568
                encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
294
295
89594568
                prev_level = level;
296
297
89594568
                put_bits(pb, 1, IS_NEGATIVE(val));
298
            } else {
299
108806544
                ++run;
300
            }
301
        }
302
    }
303
174174
}
304
305
2397000
static void get(uint8_t *pixels, int stride, int16_t* block)
306
{
307
    int i;
308
309
21573000
    for (i = 0; i < 8; i++) {
310
19176000
        AV_WN64(block, AV_RN64(pixels));
311
19176000
        AV_WN64(block+4, AV_RN64(pixels+8));
312
19176000
        pixels += stride;
313
19176000
        block += 8;
314
    }
315
2397000
}
316
317
2397000
static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
318
{
319
2397000
    get(pixels, stride, block);
320
2397000
    fdsp->fdct(block);
321
2397000
}
322
323
133800
static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
324
{
325
    int16_t *block;
326
    int i;
327
328
133800
    block = blocks;
329
330
133800
    if (!chroma) { /* Luma plane */
331
284300
        for (i = 0; i < mb_count; i++) {
332
239700
            fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
333
239700
            fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
334
239700
            fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (2 << 6));
335
239700
            fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
336
337
239700
            block += 256;
338
239700
            src   += 32;
339
        }
340

89200
    } else if (chroma && is_422){ /* chroma plane 422 */
341
284300
        for (i = 0; i < mb_count; i++) {
342
239700
            fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
343
239700
            fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
344
239700
            block += (256 >> 1);
345
239700
            src   += (32  >> 1);
346
        }
347
    } else { /* chroma plane 444 */
348
284300
        for (i = 0; i < mb_count; i++) {
349
239700
            fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
350
239700
            fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (1 << 6));
351
239700
            fdct_get(fdsp, src + 16,                  src_stride, block + (2 << 6));
352
239700
            fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
353
354
239700
            block += 256;
355
239700
            src   += 32;
356
        }
357
    }
358
133800
}
359
360
174174
static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
361
                              const uint8_t ff_prores_scan[64])
362
{
363
    int blocks_per_slice;
364
    PutBitContext pb;
365
366
174174
    blocks_per_slice = mb_count << (2 - sub_sample_chroma);
367
174174
    init_put_bits(&pb, buf, buf_size);
368
369
174174
    encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
370
174174
    encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat, ff_prores_scan);
371
372
174174
    flush_put_bits(&pb);
373
174174
    return put_bits_ptr(&pb) - pb.buf;
374
}
375
376
58058
static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
377
                                                   int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
378
                                                   unsigned mb_count, uint8_t *buf, unsigned data_size,
379
                                                   unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
380
                                                   int qp)
381
{
382
58058
    ProresContext* ctx = avctx->priv_data;
383
384
116116
    *y_data_size = encode_slice_plane(blocks_y, mb_count,
385
58058
                                      buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
386
387
58058
    if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
388
116116
        *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
389
58058
                                          ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
390
391
58058
        *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
392
58058
                                          data_size - *y_data_size - *u_data_size,
393
58058
                                          ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
394
    }
395
396
58058
    return *y_data_size + *u_data_size + *v_data_size;
397
}
398
399
static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
400
{
401
    const int abits = 16;
402
    const int dbits = 7;
403
    const int dsize = 1 << dbits - 1;
404
    int diff = cur - prev;
405
406
    diff = av_mod_uintp2(diff, abits);
407
    if (diff >= (1 << abits) - dsize)
408
        diff -= 1 << abits;
409
    if (diff < -dsize || diff > dsize || !diff) {
410
        put_bits(pb, 1, 1);
411
        put_bits(pb, abits, diff);
412
    } else {
413
        put_bits(pb, 1, 0);
414
        put_bits(pb, dbits - 1, FFABS(diff) - 1);
415
        put_bits(pb, 1, diff < 0);
416
    }
417
}
418
419
static inline void put_alpha_run(PutBitContext *pb, int run)
420
{
421
    if (run) {
422
        put_bits(pb, 1, 0);
423
        if (run < 0x10)
424
            put_bits(pb, 4, run);
425
        else
426
            put_bits(pb, 15, run);
427
    } else {
428
        put_bits(pb, 1, 1);
429
    }
430
}
431
432
static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
433
                                                   unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
434
{
435
    const int abits = 16;
436
    const int mask  = (1 << abits) - 1;
437
    const int num_coeffs = mb_count * 256;
438
    int prev = mask, cur;
439
    int idx = 0;
440
    int run = 0;
441
    int16_t * blocks = (int16_t *)src_a;
442
    PutBitContext pb;
443
    init_put_bits(&pb, buf, data_size);
444
445
    cur = blocks[idx++];
446
    put_alpha_diff(&pb, cur, prev);
447
    prev = cur;
448
    do {
449
        cur = blocks[idx++];
450
        if (cur != prev) {
451
            put_alpha_run (&pb, run);
452
            put_alpha_diff(&pb, cur, prev);
453
            prev = cur;
454
            run  = 0;
455
        } else {
456
            run++;
457
        }
458
    } while (idx < num_coeffs);
459
    if (run)
460
        put_alpha_run(&pb, run);
461
    flush_put_bits(&pb);
462
    *a_data_size = put_bits_count(&pb) >> 3;
463
464
    if (put_bits_left(&pb) < 0) {
465
        av_log(avctx, AV_LOG_ERROR,
466
               "Underestimated required buffer size.\n");
467
        return AVERROR_BUG;
468
    } else {
469
        return 0;
470
    }
471
}
472
473
3000
static inline void subimage_with_fill_template(uint16_t *src, unsigned x, unsigned y,
474
                                               unsigned stride, unsigned width, unsigned height, uint16_t *dst,
475
                                               unsigned dst_width, unsigned dst_height, int is_alpha_plane,
476
                                               int is_interlaced, int is_top_field)
477
{
478
3000
    int box_width = FFMIN(width - x, dst_width);
479
    int i, j, src_stride, box_height;
480
    uint16_t last_pix, *last_line;
481
482
3000
    if (!is_interlaced) {
483
1200
        src_stride = stride >> 1;
484
1200
        src += y * src_stride + x;
485
1200
        box_height = FFMIN(height - y, dst_height);
486
    } else {
487
1800
        src_stride = stride; /* 2 lines stride */
488
1800
        src += y * src_stride + x;
489
1800
        box_height = FFMIN(height/2 - y, dst_height);
490
1800
        if (!is_top_field)
491
900
            src += stride >> 1;
492
    }
493
494
24600
    for (i = 0; i < box_height; ++i) {
495
87600
        for (j = 0; j < box_width; ++j) {
496
66000
            if (!is_alpha_plane) {
497
66000
                dst[j] = src[j];
498
            } else {
499
                dst[j] = src[j] << 6; /* alpha 10b to 16b */
500
            }
501
        }
502
21600
        if (!is_alpha_plane) {
503
21600
            last_pix = dst[j - 1];
504
        } else {
505
            last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
506
        }
507
259600
        for (; j < dst_width; j++)
508
238000
            dst[j] = last_pix;
509
21600
        src += src_stride;
510
21600
        dst += dst_width;
511
    }
512
3000
    last_line = dst - dst_width;
513
29400
    for (; i < dst_height; i++) {
514
554400
        for (j = 0; j < dst_width; ++j) {
515
528000
            dst[j] = last_line[j];
516
        }
517
26400
        dst += dst_width;
518
    }
519
3000
}
520
521
3000
static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
522
        unsigned stride, unsigned width, unsigned height, uint16_t *dst,
523
        unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
524
{
525
3000
    subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
526
3000
}
527
528
/* reorganize alpha data and convert 10b -> 16b */
529
static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
530
                               unsigned stride, unsigned width, unsigned height, uint16_t *dst,
531
                               unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
532
{
533
    subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
534
}
535
536
44600
static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
537
        int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
538
        int unsafe, int *qp, int is_interlaced, int is_top_field)
539
{
540
44600
    int luma_stride, chroma_stride, alpha_stride = 0;
541
44600
    ProresContext* ctx = avctx->priv_data;
542
44600
    int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
543
44600
    int ret = 0, slice_size;
544
    uint8_t *dest_y, *dest_u, *dest_v;
545
44600
    unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
546
44600
    FDCTDSPContext *fdsp = &ctx->fdsp;
547
44600
    int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
548
44600
    int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
549
44600
    int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
550
551
44600
    LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
552
44600
    LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
553
44600
    LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
554
555
44600
    luma_stride   = pic->linesize[0];
556
44600
    chroma_stride = pic->linesize[1];
557
558
44600
    if (ctx->need_alpha)
559
        alpha_stride = pic->linesize[3];
560
561
44600
    if (!is_interlaced) {
562
22200
        dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
563
22200
        dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
564
22200
        dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
565
    } else {
566
22400
        dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2   + (mb_x << 5);
567
22400
        dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
568
22400
        dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
569
22400
        if (!is_top_field){ /* bottom field, offset dest */
570
11200
            dest_y += luma_stride;
571
11200
            dest_u += chroma_stride;
572
11200
            dest_v += chroma_stride;
573
        }
574
    }
575
576
44600
    if (unsafe) {
577
1000
        subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
578
1000
                luma_stride, avctx->width, avctx->height,
579
1000
                (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
580
1000
        subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
581
1000
                           chroma_stride, avctx->width >> ctx->is_422, avctx->height,
582
1000
                           (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
583
1000
        subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
584
1000
                           chroma_stride, avctx->width >> ctx->is_422, avctx->height,
585
1000
                           (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
586
587
        /* no need for interlaced special case, data already reorganized in subimage_with_fill */
588
1000
        calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count <<  5,                mb_count, 0, 0);
589
1000
        calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
590
1000
        calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
591
592
1000
        slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
593
                          mb_count, buf + hdr_size, data_size - hdr_size,
594
                          &y_data_size, &u_data_size, &v_data_size,
595
                          *qp);
596
    } else {
597
43600
        if (!is_interlaced) {
598
21800
            calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
599
21800
            calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
600
21800
            calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
601
        } else {
602
21800
            calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride   * 2, mb_count, 0, 0);
603
21800
            calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
604
21800
            calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
605
        }
606
607
43600
        slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
608
                          mb_count, buf + hdr_size, data_size - hdr_size,
609
                          &y_data_size, &u_data_size, &v_data_size,
610
                          *qp);
611
612

43600
        if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
613
            do {
614
8982
                *qp += 1;
615
8982
                slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
616
                                               mb_count, buf + hdr_size, data_size - hdr_size,
617
                                               &y_data_size, &u_data_size, &v_data_size,
618
                                               *qp);
619

8982
            } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
620
39948
        } else if (slice_size < low_bytes && *qp
621
2317
                > qp_start_table[avctx->profile]) {
622
            do {
623
4476
                *qp -= 1;
624
4476
                slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
625
                                               mb_count, buf + hdr_size, data_size - hdr_size,
626
                                               &y_data_size, &u_data_size, &v_data_size,
627
                                               *qp);
628

4476
            } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
629
        }
630
    }
631
632
44600
    buf[0] = hdr_size << 3;
633
44600
    buf[1] = *qp;
634
44600
    AV_WB16(buf + 2, y_data_size);
635
44600
    AV_WB16(buf + 4, u_data_size);
636
637
44600
    if (ctx->need_alpha) {
638
        AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
639
640
        subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
641
                           alpha_stride, avctx->width, avctx->height,
642
                           (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
643
        ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
644
                                      buf + hdr_size + slice_size,
645
                                      data_size - hdr_size - slice_size, &a_data_size);
646
    }
647
648
44600
    if (ret != 0) {
649
        return ret;
650
    }
651
44600
    return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
652
}
653
654
1200
static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
655
        uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
656
{
657
1200
    ProresContext *ctx = avctx->priv_data;
658
1200
    int mb_width = (avctx->width + 15) >> 4;
659
    int hdr_size, sl_size, i;
660
    int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
661
    int unsafe_bot, unsafe_right;
662
    uint8_t *sl_data, *sl_data_sizes;
663
1200
    int slice_per_line = 0, rem = mb_width;
664
665
1200
    if (!ctx->is_interlaced) { /* progressive encoding */
666
400
        mb_height = (avctx->height + 15) >> 4;
667
400
        unsafe_mb_height_limit = mb_height;
668
    } else {
669
800
        if (is_top_field) {
670
400
            picture_height = (avctx->height + 1) / 2;
671
        } else {
672
400
            picture_height = avctx->height / 2;
673
        }
674
800
        mb_height = (picture_height + 15) >> 4;
675
800
        unsafe_mb_height_limit = mb_height;
676
    }
677
678
6000
    for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
679
4800
        slice_per_line += rem >> i;
680
4800
        rem &= (1 << i) - 1;
681
    }
682
683
1200
    qp = qp_start_table[avctx->profile];
684
1200
    hdr_size = 8; sl_data_size = buf_size - hdr_size;
685
1200
    sl_data_sizes = buf + hdr_size;
686
1200
    sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
687
12700
    for (mb_y = 0; mb_y < mb_height; mb_y++) {
688
11500
        int mb_x = 0;
689
11500
        int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
690
56100
        while (mb_x < mb_width) {
691
68300
            while (mb_width - mb_x < slice_mb_count)
692
23700
                slice_mb_count >>= 1;
693
694

44600
            unsafe_bot = (avctx->height & 0xf) && (mb_y == unsafe_mb_height_limit - 1);
695

44600
            unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
696
697

44600
            sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
698
                    sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
699
44600
            if (sl_size < 0){
700
                return sl_size;
701
            }
702
703
44600
            bytestream_put_be16(&sl_data_sizes, sl_size);
704
44600
            sl_data           += sl_size;
705
44600
            sl_data_size      -= sl_size;
706
44600
            mb_x              += slice_mb_count;
707
        }
708
    }
709
710
1200
    buf[0] = hdr_size << 3;
711
1200
    AV_WB32(buf + 1, sl_data - buf);
712
1200
    AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
713
1200
    buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
714
715
1200
    return sl_data - buf;
716
}
717
718
800
static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
719
                               const AVFrame *pict, int *got_packet)
720
{
721
800
    ProresContext *ctx = avctx->priv_data;
722
800
    int header_size = 148;
723
    uint8_t *buf;
724
800
    int compress_frame_size, pic_size, ret, is_top_field_first = 0;
725
    uint8_t frame_flags;
726
800
    int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
727
728
729
800
    if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
730
        return ret;
731
732
800
    buf = pkt->data;
733
800
    compress_frame_size = 8 + header_size;
734
735
800
    bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
736
800
    bytestream_put_buffer(&buf, "icpf", 4);
737
738
800
    bytestream_put_be16(&buf, header_size);
739
800
    bytestream_put_be16(&buf, 0); /* version */
740
800
    bytestream_put_buffer(&buf, ctx->vendor, 4);
741
800
    bytestream_put_be16(&buf, avctx->width);
742
800
    bytestream_put_be16(&buf, avctx->height);
743
800
    frame_flags = 0x82; /* 422 not interlaced */
744
800
    if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
745
400
        frame_flags |= 0x40; /* 444 chroma */
746
800
    if (ctx->is_interlaced) {
747

400
        if (pict->top_field_first || !pict->interlaced_frame) { /* tff frame or progressive frame interpret as tff */
748
400
            av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
749
400
            frame_flags |= 0x04; /* interlaced tff */
750
400
            is_top_field_first = 1;
751
        } else {
752
            av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
753
            frame_flags |= 0x08; /* interlaced bff */
754
        }
755
    } else {
756
400
        av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
757
    }
758
800
    *buf++ = frame_flags;
759
800
    *buf++ = 0; /* reserved */
760
    /* only write color properties, if valid value. set to unspecified otherwise */
761
800
    *buf++ = ff_int_from_list_or_default(avctx, "frame color primaries", pict->color_primaries, valid_primaries, 0);
762
800
    *buf++ = ff_int_from_list_or_default(avctx, "frame color trc", pict->color_trc, valid_trc, 0);
763
800
    *buf++ = ff_int_from_list_or_default(avctx, "frame colorspace", pict->colorspace, valid_colorspace, 0);
764
800
    if (avctx->profile >= FF_PROFILE_PRORES_4444) {
765
400
        if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
766
400
            *buf++ = 0xA0;/* src b64a and no alpha */
767
        } else {
768
            *buf++ = 0xA2;/* src b64a and 16b alpha */
769
        }
770
    } else {
771
400
        *buf++ = 32;/* src v210 and no alpha */
772
    }
773
800
    *buf++ = 0; /* reserved */
774
800
    *buf++ = 3; /* luma and chroma matrix present */
775
776
800
    bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
777
800
    bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
778
779
800
    pic_size = prores_encode_picture(avctx, pict, buf,
780
800
                                     pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
781
800
    if (pic_size < 0) {
782
        return pic_size;
783
    }
784
800
    compress_frame_size += pic_size;
785
786
800
    if (ctx->is_interlaced) { /* encode second field */
787
400
        pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
788
400
                                         pkt->size - compress_frame_size, 1, !is_top_field_first);
789
400
        if (pic_size < 0) {
790
            return pic_size;
791
        }
792
400
        compress_frame_size += pic_size;
793
    }
794
795
800
    AV_WB32(pkt->data, compress_frame_size);/* update frame size */
796
800
    pkt->flags |= AV_PKT_FLAG_KEY;
797
800
    pkt->size = compress_frame_size;
798
800
    *got_packet = 1;
799
800
800
    return 0;
801
}
802
803
512
static void scale_mat(const uint8_t* src, int* dst, int scale)
804
{
805
    int i;
806
33280
    for (i = 0; i < 64; i++)
807
32768
        dst[i] = src[i] * scale;
808
512
}
809
810
16
static av_cold int prores_encode_init(AVCodecContext *avctx)
811
{
812
    int i;
813
16
    ProresContext* ctx = avctx->priv_data;
814
815
16
    avctx->bits_per_raw_sample = 10;
816
16
    ctx->need_alpha = 0;
817
16
    ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
818
16
    if (ctx->is_interlaced) {
819
8
        ctx->scantable = ff_prores_interlaced_scan;
820
    } else {
821
8
        ctx->scantable = ff_prores_progressive_scan;
822
    }
823
824
16
    if (avctx->width & 0x1) {
825
        av_log(avctx, AV_LOG_ERROR,
826
                "frame width needs to be multiple of 2\n");
827
        return AVERROR(EINVAL);
828
    }
829
830

16
    if (avctx->width > 65534 || avctx->height > 65535) {
831
        av_log(avctx, AV_LOG_ERROR,
832
                "The maximum dimensions are 65534x65535\n");
833
        return AVERROR(EINVAL);
834
    }
835
836
16
    if (strlen(ctx->vendor) != 4) {
837
        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
838
        return AVERROR(EINVAL);
839
    }
840
841
16
    if (avctx->profile == FF_PROFILE_UNKNOWN) {
842
16
        if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
843
8
            avctx->profile = FF_PROFILE_PRORES_STANDARD;
844
8
            av_log(avctx, AV_LOG_INFO,
845
                "encoding with ProRes standard (apcn) profile\n");
846
8
        } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
847
8
            avctx->profile = FF_PROFILE_PRORES_4444;
848
8
            av_log(avctx, AV_LOG_INFO,
849
                   "encoding with ProRes 4444 (ap4h) profile\n");
850
        } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
851
            avctx->profile = FF_PROFILE_PRORES_4444;
852
            av_log(avctx, AV_LOG_INFO,
853
                   "encoding with ProRes 4444+ (ap4h) profile\n");
854
        } else {
855
            av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
856
            return AVERROR(EINVAL);
857
        }
858
    } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
859
            || avctx->profile > FF_PROFILE_PRORES_XQ) {
860
        av_log(
861
                avctx,
862
                AV_LOG_ERROR,
863
                "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
864
                avctx->profile);
865
        return AVERROR(EINVAL);
866
    } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
867
        av_log(avctx, AV_LOG_ERROR,
868
               "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
869
        return AVERROR(EINVAL);
870
    }  else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
871
                && (avctx->profile < FF_PROFILE_PRORES_4444)){
872
        av_log(avctx, AV_LOG_ERROR,
873
               "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
874
        return AVERROR(EINVAL);
875
    }
876
877
16
    if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
878
8
        ctx->is_422 = 1;
879

8
        if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
880
2
            ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
881
2
            if (!ctx->fill_y)
882
                return AVERROR(ENOMEM);
883
2
            ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
884
2
            ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
885
        }
886
    } else { /* 444 */
887
8
        ctx->is_422 = 0;
888

8
        if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
889
2
            ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
890
2
            if (!ctx->fill_y)
891
                return AVERROR(ENOMEM);
892
2
            ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
893
2
            ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
894
        }
895
8
        if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
896
            ctx->need_alpha = 1;
897
            ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
898
            if (!ctx->fill_a)
899
                return AVERROR(ENOMEM);
900
        }
901
    }
902
903
16
    ff_fdctdsp_init(&ctx->fdsp, avctx);
904
905
16
    avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
906
907
272
    for (i = 1; i <= 16; i++) {
908
256
        scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
909
256
        scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
910
    }
911
912
16
    return 0;
913
}
914
915
16
static av_cold int prores_encode_close(AVCodecContext *avctx)
916
{
917
16
    ProresContext* ctx = avctx->priv_data;
918
16
    av_freep(&ctx->fill_y);
919
16
    av_freep(&ctx->fill_a);
920
921
16
    return 0;
922
}
923
924
#define OFFSET(x) offsetof(ProresContext, x)
925
#define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
926
927
static const AVOption options[] = {
928
    { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, 0, 0, VE },
929
    { NULL }
930
};
931
932
static const AVClass proresaw_enc_class = {
933
    .class_name = "ProResAw encoder",
934
    .item_name  = av_default_item_name,
935
    .option     = options,
936
    .version    = LIBAVUTIL_VERSION_INT,
937
};
938
939
static const AVClass prores_enc_class = {
940
    .class_name = "ProRes encoder",
941
    .item_name  = av_default_item_name,
942
    .option     = options,
943
    .version    = LIBAVUTIL_VERSION_INT,
944
};
945
946
AVCodec ff_prores_aw_encoder = {
947
    .name           = "prores_aw",
948
    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
949
    .type           = AVMEDIA_TYPE_VIDEO,
950
    .id             = AV_CODEC_ID_PRORES,
951
    .priv_data_size = sizeof(ProresContext),
952
    .init           = prores_encode_init,
953
    .close          = prores_encode_close,
954
    .encode2        = prores_encode_frame,
955
    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
956
    .capabilities   = AV_CODEC_CAP_FRAME_THREADS,
957
    .priv_class     = &proresaw_enc_class,
958
    .profiles       = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
959
};
960
961
AVCodec ff_prores_encoder = {
962
    .name           = "prores",
963
    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
964
    .type           = AVMEDIA_TYPE_VIDEO,
965
    .id             = AV_CODEC_ID_PRORES,
966
    .priv_data_size = sizeof(ProresContext),
967
    .init           = prores_encode_init,
968
    .close          = prores_encode_close,
969
    .encode2        = prores_encode_frame,
970
    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
971
    .capabilities   = AV_CODEC_CAP_FRAME_THREADS,
972
    .priv_class     = &prores_enc_class,
973
    .profiles       = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
974
};