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

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

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

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

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

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

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

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

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

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

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

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