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

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

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

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

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

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

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

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

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

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

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

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