Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/proresenc_anatoliy.c
Line
Count
Source (jump to first uncovered line)
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.h"
31
#include "libavutil/mem_internal.h"
32
#include "libavutil/opt.h"
33
#include "avcodec.h"
34
#include "codec_internal.h"
35
#include "encode.h"
36
#include "profiles.h"
37
#include "proresdata.h"
38
#include "put_bits.h"
39
#include "bytestream.h"
40
#include "fdctdsp.h"
41
42
266k
#define DEFAULT_SLICE_MB_WIDTH 8
43
44
static const AVProfile profiles[] = {
45
    { AV_PROFILE_PRORES_PROXY,    "apco"},
46
    { AV_PROFILE_PRORES_LT,       "apcs"},
47
    { AV_PROFILE_PRORES_STANDARD, "apcn"},
48
    { AV_PROFILE_PRORES_HQ,       "apch"},
49
    { AV_PROFILE_PRORES_4444,     "ap4h"},
50
    { AV_PROFILE_PRORES_XQ,       "ap4x"},
51
    { AV_PROFILE_UNKNOWN }
52
};
53
54
static const int qp_start_table[] = {  8, 3, 2, 1, 1, 1};
55
static const int qp_end_table[]   = { 13, 9, 6, 6, 5, 4};
56
static const int bitrate_table[]  = { 1000, 2100, 3500, 5400, 7000, 10000};
57
58
static const int valid_primaries[]  = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG,
59
                                        AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432, INT_MAX };
60
static const int valid_trc[]        = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_SMPTE2084,
61
                                        AVCOL_TRC_ARIB_STD_B67, INT_MAX };
62
static const int valid_colorspace[] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M,
63
                                        AVCOL_SPC_BT2020_NCL, INT_MAX };
64
65
static const uint8_t QMAT_LUMA[6][64] = {
66
    {
67
         4,  7,  9, 11, 13, 14, 15, 63,
68
         7,  7, 11, 12, 14, 15, 63, 63,
69
         9, 11, 13, 14, 15, 63, 63, 63,
70
        11, 11, 13, 14, 63, 63, 63, 63,
71
        11, 13, 14, 63, 63, 63, 63, 63,
72
        13, 14, 63, 63, 63, 63, 63, 63,
73
        13, 63, 63, 63, 63, 63, 63, 63,
74
        63, 63, 63, 63, 63, 63, 63, 63
75
    }, {
76
         4,  5,  6,  7,  9, 11, 13, 15,
77
         5,  5,  7,  8, 11, 13, 15, 17,
78
         6,  7,  9, 11, 13, 15, 15, 17,
79
         7,  7,  9, 11, 13, 15, 17, 19,
80
         7,  9, 11, 13, 14, 16, 19, 23,
81
         9, 11, 13, 14, 16, 19, 23, 29,
82
         9, 11, 13, 15, 17, 21, 28, 35,
83
        11, 13, 16, 17, 21, 28, 35, 41
84
    }, {
85
         4,  4,  5,  5,  6,  7,  7,  9,
86
         4,  4,  5,  6,  7,  7,  9,  9,
87
         5,  5,  6,  7,  7,  9,  9, 10,
88
         5,  5,  6,  7,  7,  9,  9, 10,
89
         5,  6,  7,  7,  8,  9, 10, 12,
90
         6,  7,  7,  8,  9, 10, 12, 15,
91
         6,  7,  7,  9, 10, 11, 14, 17,
92
         7,  7,  9, 10, 11, 14, 17, 21
93
    }, {
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,  4,
97
         4,  4,  4,  4,  4,  4,  4,  5,
98
         4,  4,  4,  4,  4,  4,  5,  5,
99
         4,  4,  4,  4,  4,  5,  5,  6,
100
         4,  4,  4,  4,  5,  5,  6,  7,
101
         4,  4,  4,  4,  5,  6,  7,  7
102
    }, { /* 444 */
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,  4,
106
        4,  4,  4,  4,  4,  4,  4,  5,
107
        4,  4,  4,  4,  4,  4,  5,  5,
108
        4,  4,  4,  4,  4,  5,  5,  6,
109
        4,  4,  4,  4,  5,  5,  6,  7,
110
        4,  4,  4,  4,  5,  6,  7,  7
111
    }, { /* 444 XQ */
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,  2,
115
        2,  2,  2,  2,  2,  2,  2,  3,
116
        2,  2,  2,  2,  2,  2,  3,  3,
117
        2,  2,  2,  2,  2,  3,  3,  3,
118
        2,  2,  2,  2,  3,  3,  3,  4,
119
        2,  2,  2,  2,  3,  3,  4,  4,
120
    }
121
};
122
123
static const uint8_t QMAT_CHROMA[6][64] = {
124
    {
125
         4,  7,  9, 11, 13, 14, 63, 63,
126
         7,  7, 11, 12, 14, 63, 63, 63,
127
         9, 11, 13, 14, 63, 63, 63, 63,
128
        11, 11, 13, 14, 63, 63, 63, 63,
129
        11, 13, 14, 63, 63, 63, 63, 63,
130
        13, 14, 63, 63, 63, 63, 63, 63,
131
        13, 63, 63, 63, 63, 63, 63, 63,
132
        63, 63, 63, 63, 63, 63, 63, 63
133
    }, {
134
         4,  5,  6,  7,  9, 11, 13, 15,
135
         5,  5,  7,  8, 11, 13, 15, 17,
136
         6,  7,  9, 11, 13, 15, 15, 17,
137
         7,  7,  9, 11, 13, 15, 17, 19,
138
         7,  9, 11, 13, 14, 16, 19, 23,
139
         9, 11, 13, 14, 16, 19, 23, 29,
140
         9, 11, 13, 15, 17, 21, 28, 35,
141
        11, 13, 16, 17, 21, 28, 35, 41
142
    }, {
143
         4,  4,  5,  5,  6,  7,  7,  9,
144
         4,  4,  5,  6,  7,  7,  9,  9,
145
         5,  5,  6,  7,  7,  9,  9, 10,
146
         5,  5,  6,  7,  7,  9,  9, 10,
147
         5,  6,  7,  7,  8,  9, 10, 12,
148
         6,  7,  7,  8,  9, 10, 12, 15,
149
         6,  7,  7,  9, 10, 11, 14, 17,
150
         7,  7,  9, 10, 11, 14, 17, 21
151
    }, {
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,  4,
155
         4,  4,  4,  4,  4,  4,  4,  5,
156
         4,  4,  4,  4,  4,  4,  5,  5,
157
         4,  4,  4,  4,  4,  5,  5,  6,
158
         4,  4,  4,  4,  5,  5,  6,  7,
159
         4,  4,  4,  4,  5,  6,  7,  7
160
    }, { /* 444 */
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,  4,
164
        4,  4,  4,  4,  4,  4,  4,  5,
165
        4,  4,  4,  4,  4,  4,  5,  5,
166
        4,  4,  4,  4,  4,  5,  5,  6,
167
        4,  4,  4,  4,  5,  5,  6,  7,
168
        4,  4,  4,  4,  5,  6,  7,  7
169
    }, { /* 444 xq */
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,  4,
173
        4,  4,  4,  4,  4,  4,  4,  5,
174
        4,  4,  4,  4,  4,  4,  5,  5,
175
        4,  4,  4,  4,  4,  5,  5,  6,
176
        4,  4,  4,  4,  5,  5,  6,  7,
177
        4,  4,  4,  4,  5,  6,  7,  7
178
    }
179
};
180
181
182
typedef struct {
183
    AVClass *class;
184
    FDCTDSPContext fdsp;
185
    uint8_t* fill_y;
186
    uint8_t* fill_u;
187
    uint8_t* fill_v;
188
    uint8_t* fill_a;
189
190
    int qmat_luma[16][64];
191
    int qmat_chroma[16][64];
192
    const uint8_t *scantable;
193
194
    int is_422;
195
    int need_alpha;
196
    int is_interlaced;
197
198
    char *vendor;
199
} ProresContext;
200
201
/**
202
 * Check if a value is in the list. If not, return the default value
203
 *
204
 * @param ctx                Context for the log msg
205
 * @param val_name           Name of the checked value, for log msg
206
 * @param array_valid_values Array of valid int, ended with INT_MAX
207
 * @param default_value      Value return if checked value is not in the array
208
 * @return                   Value or default_value.
209
 */
210
static int int_from_list_or_default(void *ctx, const char *val_name, int val,
211
                                    const int *array_valid_values, int default_value)
212
19.6k
{
213
19.6k
    int i = 0;
214
215
52.4k
    while (1) {
216
52.4k
        int ref_val = array_valid_values[i];
217
52.4k
        if (ref_val == INT_MAX)
218
0
            break;
219
52.4k
        if (val == ref_val)
220
19.6k
            return val;
221
32.7k
        i++;
222
32.7k
    }
223
    /* val is not a valid value */
224
0
    av_log(ctx, AV_LOG_DEBUG,
225
0
           "%s %d are not supported. Set to default value : %d\n",
226
0
           val_name, val, default_value);
227
0
    return default_value;
228
19.6k
}
229
230
static void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
231
61.1M
{
232
61.1M
    unsigned int rice_order, exp_order, switch_bits, switch_val;
233
61.1M
    int exponent;
234
235
    /* number of prefix bits to switch between Rice and expGolomb */
236
61.1M
    switch_bits = (codebook & 3) + 1;
237
61.1M
    rice_order  =  codebook >> 5;       /* rice code order */
238
61.1M
    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
239
240
61.1M
    switch_val  = switch_bits << rice_order;
241
242
61.1M
    if (val >= switch_val) {
243
28.3M
        val -= switch_val - (1 << exp_order);
244
28.3M
        exponent = av_log2(val);
245
246
28.3M
        put_bits(pb, exponent - exp_order + switch_bits, 0);
247
28.3M
        put_bits(pb, exponent + 1, val);
248
32.7M
    } else {
249
32.7M
        exponent = val >> rice_order;
250
251
32.7M
        if (exponent)
252
4.85M
            put_bits(pb, exponent, 0);
253
32.7M
        put_bits(pb, 1, 1);
254
32.7M
        if (rice_order)
255
1.88M
            put_sbits(pb, rice_order, val);
256
32.7M
    }
257
61.1M
}
258
259
44.0M
#define GET_SIGN(x)  ((x) >> 31)
260
9.69M
#define MAKE_CODE(x) (((x) * 2) ^ GET_SIGN(x))
261
262
static void encode_dcs(PutBitContext *pb, int16_t *blocks,
263
                       int blocks_per_slice, int scale)
264
1.06M
{
265
1.06M
    int i;
266
1.06M
    int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
267
268
1.06M
    prev_dc = (blocks[0] - 0x4000) / scale;
269
1.06M
    encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
270
1.06M
    sign     = 0;
271
1.06M
    blocks  += 64;
272
273
9.69M
    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
274
8.63M
        dc       = (blocks[0] - 0x4000) / scale;
275
8.63M
        delta    = dc - prev_dc;
276
8.63M
        new_sign = GET_SIGN(delta);
277
8.63M
        delta    = (delta ^ sign) - sign;
278
8.63M
        code     = MAKE_CODE(delta);
279
8.63M
        encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
280
8.63M
        codebook = FFMIN(code, 6);
281
8.63M
        sign     = new_sign;
282
8.63M
        prev_dc  = dc;
283
8.63M
    }
284
1.06M
}
285
286
static void encode_acs(PutBitContext *pb, int16_t *blocks,
287
                       int blocks_per_slice,
288
                       int *qmat, const uint8_t *scan)
289
1.06M
{
290
1.06M
    int idx, i;
291
1.06M
    int prev_run = 4;
292
1.06M
    int prev_level = 2;
293
1.06M
    int run = 0, level;
294
1.06M
    int max_coeffs, abs_level;
295
296
1.06M
    max_coeffs = blocks_per_slice << 6;
297
298
67.9M
    for (i = 1; i < 64; i++) {
299
677M
        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
300
610M
            level = blocks[idx] / qmat[scan[i]];
301
610M
            if (level) {
302
25.7M
                abs_level = FFABS(level);
303
25.7M
                encode_vlc_codeword(pb, ff_prores_run_to_cb[prev_run], run);
304
25.7M
                encode_vlc_codeword(pb, ff_prores_level_to_cb[prev_level], abs_level - 1);
305
25.7M
                put_sbits(pb, 1, GET_SIGN(level));
306
307
25.7M
                prev_run   = FFMIN(run, 15);
308
25.7M
                prev_level = FFMIN(abs_level, 9);
309
25.7M
                run        = 0;
310
585M
            } else {
311
585M
                run++;
312
585M
            }
313
610M
        }
314
66.9M
    }
315
1.06M
}
316
317
static void get(const uint8_t *pixels, int stride, int16_t* block)
318
9.21M
{
319
9.21M
    int i;
320
321
82.9M
    for (i = 0; i < 8; i++) {
322
73.7M
        AV_WN64(block, AV_RN64(pixels));
323
73.7M
        AV_WN64(block+4, AV_RN64(pixels+8));
324
73.7M
        pixels += stride;
325
73.7M
        block += 8;
326
73.7M
    }
327
9.21M
}
328
329
static void fdct_get(FDCTDSPContext *fdsp, const uint8_t *pixels, int stride, int16_t* block)
330
9.21M
{
331
9.21M
    get(pixels, stride, block);
332
9.21M
    fdsp->fdct(block);
333
9.21M
}
334
335
static void calc_plane_dct(FDCTDSPContext *fdsp, const uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
336
1.01M
{
337
1.01M
    int16_t *block;
338
1.01M
    int i;
339
340
1.01M
    block = blocks;
341
342
1.01M
    if (!chroma) { /* Luma plane */
343
1.22M
        for (i = 0; i < mb_count; i++) {
344
881k
            fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
345
881k
            fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
346
881k
            fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (2 << 6));
347
881k
            fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
348
349
881k
            block += 256;
350
881k
            src   += 32;
351
881k
        }
352
678k
    } else if (chroma && is_422){ /* chroma plane 422 */
353
902k
        for (i = 0; i < mb_count; i++) {
354
680k
            fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
355
680k
            fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
356
680k
            block += (256 >> 1);
357
680k
            src   += (32  >> 1);
358
680k
        }
359
456k
    } else { /* chroma plane 444 */
360
1.53M
        for (i = 0; i < mb_count; i++) {
361
1.08M
            fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
362
1.08M
            fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (1 << 6));
363
1.08M
            fdct_get(fdsp, src + 16,                  src_stride, block + (2 << 6));
364
1.08M
            fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
365
366
1.08M
            block += 256;
367
1.08M
            src   += 32;
368
1.08M
        }
369
456k
    }
370
1.01M
}
371
372
static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
373
                              const uint8_t *scan)
374
1.06M
{
375
1.06M
    int blocks_per_slice;
376
1.06M
    PutBitContext pb;
377
378
1.06M
    blocks_per_slice = mb_count << (2 - sub_sample_chroma);
379
1.06M
    init_put_bits(&pb, buf, buf_size);
380
381
1.06M
    encode_dcs(&pb, blocks, blocks_per_slice, qmat[0]);
382
1.06M
    encode_acs(&pb, blocks, blocks_per_slice, qmat, scan);
383
384
1.06M
    flush_put_bits(&pb);
385
1.06M
    return put_bits_ptr(&pb) - pb.buf;
386
1.06M
}
387
388
static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
389
                                                   int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
390
                                                   unsigned mb_count, uint8_t *buf, unsigned data_size,
391
                                                   unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
392
                                                   int qp)
393
354k
{
394
354k
    ProresContext* ctx = avctx->priv_data;
395
396
354k
    *y_data_size = encode_slice_plane(blocks_y, mb_count,
397
354k
                                      buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
398
399
354k
    if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
400
354k
        *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
401
354k
                                          ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
402
403
354k
        *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
404
354k
                                          data_size - *y_data_size - *u_data_size,
405
354k
                                          ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
406
354k
    }
407
408
354k
    return *y_data_size + *u_data_size + *v_data_size;
409
354k
}
410
411
static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
412
1.19M
{
413
1.19M
    const int abits = 16;
414
1.19M
    const int dbits = 7;
415
1.19M
    const int dsize = 1 << dbits - 1;
416
1.19M
    int diff = cur - prev;
417
418
1.19M
    diff = av_zero_extend(diff, abits);
419
1.19M
    if (diff >= (1 << abits) - dsize)
420
54.7k
        diff -= 1 << abits;
421
1.19M
    if (diff < -dsize || diff > dsize || !diff) {
422
932k
        put_bits(pb, 1, 1);
423
932k
        put_bits(pb, abits, diff);
424
932k
    } else {
425
259k
        put_bits(pb, 1, 0);
426
259k
        put_bits(pb, dbits - 1, FFABS(diff) - 1);
427
259k
        put_bits(pb, 1, diff < 0);
428
259k
    }
429
1.19M
}
430
431
static inline void put_alpha_run(PutBitContext *pb, int run)
432
1.19M
{
433
1.19M
    if (run) {
434
318k
        put_bits(pb, 1, 0);
435
318k
        if (run < 0x10)
436
144k
            put_bits(pb, 4, run);
437
174k
        else
438
174k
            put_bits(pb, 15, run);
439
872k
    } else {
440
872k
        put_bits(pb, 1, 1);
441
872k
    }
442
1.19M
}
443
444
static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
445
                                                   unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
446
166k
{
447
166k
    const int abits = 16;
448
166k
    const int mask  = (1 << abits) - 1;
449
166k
    const int num_coeffs = mb_count * 256;
450
166k
    int prev = mask, cur;
451
166k
    int idx = 0;
452
166k
    int run = 0;
453
166k
    int16_t * blocks = (int16_t *)src_a;
454
166k
    PutBitContext pb;
455
166k
    init_put_bits(&pb, buf, data_size);
456
457
166k
    cur = blocks[idx++];
458
166k
    put_alpha_diff(&pb, cur, prev);
459
166k
    prev = cur;
460
110M
    do {
461
110M
        cur = blocks[idx++];
462
110M
        if (cur != prev) {
463
1.02M
            put_alpha_run (&pb, run);
464
1.02M
            put_alpha_diff(&pb, cur, prev);
465
1.02M
            prev = cur;
466
1.02M
            run  = 0;
467
109M
        } else {
468
109M
            run++;
469
109M
        }
470
110M
    } while (idx < num_coeffs);
471
166k
    put_alpha_run(&pb, run);
472
166k
    flush_put_bits(&pb);
473
166k
    *a_data_size = put_bytes_output(&pb);
474
475
166k
    if (put_bits_left(&pb) < 0) {
476
0
        av_log(avctx, AV_LOG_ERROR,
477
0
               "Underestimated required buffer size.\n");
478
0
        return AVERROR_BUG;
479
166k
    } else {
480
166k
        return 0;
481
166k
    }
482
166k
}
483
484
static inline void subimage_with_fill_template(const uint16_t *src, unsigned x, unsigned y,
485
                                               unsigned stride, unsigned width, unsigned height, uint16_t *dst,
486
                                               unsigned dst_width, unsigned dst_height, int is_alpha_plane,
487
                                               int is_interlaced, int is_top_field)
488
1.10M
{
489
1.10M
    int box_width = FFMIN(width - x, dst_width);
490
1.10M
    int i, j, src_stride, box_height;
491
1.10M
    uint16_t last_pix, *last_line;
492
493
1.10M
    if (!is_interlaced) {
494
1.10M
        src_stride = stride >> 1;
495
1.10M
        src += y * src_stride + x;
496
1.10M
        box_height = FFMIN(height - y, dst_height);
497
1.10M
    } else {
498
0
        src_stride = stride; /* 2 lines stride */
499
0
        src += y * src_stride + x;
500
0
        box_height = FFMIN(height/2 - y, dst_height);
501
0
        if (!is_top_field)
502
0
            src += stride >> 1;
503
0
    }
504
505
15.4M
    for (i = 0; i < box_height; ++i) {
506
150M
        for (j = 0; j < box_width; ++j) {
507
135M
            if (!is_alpha_plane) {
508
104M
                dst[j] = src[j];
509
104M
            } else {
510
31.2M
                dst[j] = src[j] << 6; /* alpha 10b to 16b */
511
31.2M
            }
512
135M
        }
513
14.3M
        if (!is_alpha_plane) {
514
12.1M
            last_pix = dst[j - 1];
515
12.1M
        } else {
516
2.20M
            last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
517
2.20M
        }
518
165M
        for (; j < dst_width; j++)
519
150M
            dst[j] = last_pix;
520
14.3M
        src += src_stride;
521
14.3M
        dst += dst_width;
522
14.3M
    }
523
1.10M
    last_line = dst - dst_width;
524
4.35M
    for (; i < dst_height; i++) {
525
348M
        for (j = 0; j < dst_width; ++j) {
526
344M
            dst[j] = last_line[j];
527
344M
        }
528
3.24M
        dst += dst_width;
529
3.24M
    }
530
1.10M
}
531
532
static void subimage_with_fill(const uint16_t *src, unsigned x, unsigned y,
533
        unsigned stride, unsigned width, unsigned height, uint16_t *dst,
534
        unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
535
936k
{
536
936k
    subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
537
936k
}
538
539
/* reorganize alpha data and convert 10b -> 16b */
540
static void subimage_alpha_with_fill(const uint16_t *src, unsigned x, unsigned y,
541
                               unsigned stride, unsigned width, unsigned height, uint16_t *dst,
542
                               unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
543
166k
{
544
166k
    subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
545
166k
}
546
547
static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
548
        int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
549
        int unsafe, int *qp, int is_interlaced, int is_top_field)
550
339k
{
551
339k
    int luma_stride, chroma_stride, alpha_stride = 0;
552
339k
    ProresContext* ctx = avctx->priv_data;
553
339k
    int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
554
339k
    int ret = 0, slice_size;
555
339k
    const uint8_t *dest_y, *dest_u, *dest_v;
556
339k
    unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
557
339k
    FDCTDSPContext *fdsp = &ctx->fdsp;
558
339k
    int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
559
339k
    int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
560
339k
    int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
561
562
339k
    LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
563
339k
    LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
564
339k
    LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
565
566
339k
    luma_stride   = pic->linesize[0];
567
339k
    chroma_stride = pic->linesize[1];
568
569
339k
    if (ctx->need_alpha)
570
166k
        alpha_stride = pic->linesize[3];
571
572
339k
    if (!is_interlaced) {
573
339k
        dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
574
339k
        dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
575
339k
        dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
576
339k
    } else {
577
0
        dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2   + (mb_x << 5);
578
0
        dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
579
0
        dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
580
0
        if (!is_top_field){ /* bottom field, offset dest */
581
0
            dest_y += luma_stride;
582
0
            dest_u += chroma_stride;
583
0
            dest_v += chroma_stride;
584
0
        }
585
0
    }
586
587
339k
    if (unsafe) {
588
312k
        subimage_with_fill((const uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
589
312k
                luma_stride, avctx->width, avctx->height,
590
312k
                (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
591
312k
        subimage_with_fill((const uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
592
312k
                           chroma_stride, avctx->width >> ctx->is_422, avctx->height,
593
312k
                           (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
594
312k
        subimage_with_fill((const uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
595
312k
                           chroma_stride, avctx->width >> ctx->is_422, avctx->height,
596
312k
                           (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
597
598
        /* no need for interlaced special case, data already reorganized in subimage_with_fill */
599
312k
        calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count <<  5,                mb_count, 0, 0);
600
312k
        calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
601
312k
        calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
602
603
312k
        slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
604
312k
                          mb_count, buf + hdr_size, data_size - hdr_size,
605
312k
                          &y_data_size, &u_data_size, &v_data_size,
606
312k
                          *qp);
607
312k
    } else {
608
26.8k
        if (!is_interlaced) {
609
26.8k
            calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
610
26.8k
            calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
611
26.8k
            calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
612
26.8k
        } else {
613
0
            calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride   * 2, mb_count, 0, 0);
614
0
            calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
615
0
            calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
616
0
        }
617
618
26.8k
        slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
619
26.8k
                          mb_count, buf + hdr_size, data_size - hdr_size,
620
26.8k
                          &y_data_size, &u_data_size, &v_data_size,
621
26.8k
                          *qp);
622
623
26.8k
        if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
624
8.46k
            do {
625
8.46k
                *qp += 1;
626
8.46k
                slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
627
8.46k
                                               mb_count, buf + hdr_size, data_size - hdr_size,
628
8.46k
                                               &y_data_size, &u_data_size, &v_data_size,
629
8.46k
                                               *qp);
630
8.46k
            } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
631
24.3k
        } else if (slice_size < low_bytes && *qp
632
20.0k
                > qp_start_table[avctx->profile]) {
633
6.40k
            do {
634
6.40k
                *qp -= 1;
635
6.40k
                slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
636
6.40k
                                               mb_count, buf + hdr_size, data_size - hdr_size,
637
6.40k
                                               &y_data_size, &u_data_size, &v_data_size,
638
6.40k
                                               *qp);
639
6.40k
            } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
640
2.03k
        }
641
26.8k
    }
642
643
339k
    buf[0] = hdr_size << 3;
644
339k
    buf[1] = *qp;
645
339k
    AV_WB16(buf + 2, y_data_size);
646
339k
    AV_WB16(buf + 4, u_data_size);
647
648
339k
    if (ctx->need_alpha) {
649
166k
        AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
650
651
166k
        subimage_alpha_with_fill((const uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
652
166k
                           alpha_stride, avctx->width, avctx->height,
653
166k
                           (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
654
166k
        ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
655
166k
                                      buf + hdr_size + slice_size,
656
166k
                                      data_size - hdr_size - slice_size, &a_data_size);
657
166k
    }
658
659
339k
    if (ret != 0) {
660
0
        return ret;
661
0
    }
662
339k
    return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
663
339k
}
664
665
static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
666
        uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
667
6.55k
{
668
6.55k
    ProresContext *ctx = avctx->priv_data;
669
6.55k
    int mb_width = (avctx->width + 15) >> 4;
670
6.55k
    int hdr_size, sl_size, i;
671
6.55k
    int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
672
6.55k
    int unsafe_bot, unsafe_right;
673
6.55k
    uint8_t *sl_data, *sl_data_sizes;
674
6.55k
    int slice_per_line = 0, rem = mb_width;
675
676
6.55k
    if (!ctx->is_interlaced) { /* progressive encoding */
677
6.55k
        mb_height = (avctx->height + 15) >> 4;
678
6.55k
        unsafe_mb_height_limit = mb_height;
679
6.55k
    } else {
680
0
        if (is_top_field) {
681
0
            picture_height = (avctx->height + 1) / 2;
682
0
        } else {
683
0
            picture_height = avctx->height / 2;
684
0
        }
685
0
        mb_height = (picture_height + 15) >> 4;
686
0
        unsafe_mb_height_limit = mb_height;
687
0
    }
688
689
32.7k
    for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
690
26.2k
        slice_per_line += rem >> i;
691
26.2k
        rem &= (1 << i) - 1;
692
26.2k
    }
693
694
6.55k
    qp = qp_start_table[avctx->profile];
695
6.55k
    hdr_size = 8; sl_data_size = buf_size - hdr_size;
696
6.55k
    sl_data_sizes = buf + hdr_size;
697
6.55k
    sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
698
270k
    for (mb_y = 0; mb_y < mb_height; mb_y++) {
699
263k
        int mb_x = 0;
700
263k
        int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
701
602k
        while (mb_x < mb_width) {
702
1.11M
            while (mb_width - mb_x < slice_mb_count)
703
777k
                slice_mb_count >>= 1;
704
705
339k
            unsafe_bot = (avctx->height & 0xf) && (mb_y == unsafe_mb_height_limit - 1);
706
339k
            unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
707
708
339k
            sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
709
339k
                    sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
710
339k
            if (sl_size < 0){
711
0
                return sl_size;
712
0
            }
713
714
339k
            bytestream_put_be16(&sl_data_sizes, sl_size);
715
339k
            sl_data           += sl_size;
716
339k
            sl_data_size      -= sl_size;
717
339k
            mb_x              += slice_mb_count;
718
339k
        }
719
263k
    }
720
721
6.55k
    buf[0] = hdr_size << 3;
722
6.55k
    AV_WB32(buf + 1, sl_data - buf);
723
6.55k
    AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
724
6.55k
    buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
725
726
6.55k
    return sl_data - buf;
727
6.55k
}
728
729
static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
730
                               const AVFrame *pict, int *got_packet)
731
6.55k
{
732
6.55k
    ProresContext *ctx = avctx->priv_data;
733
6.55k
    int header_size = 148;
734
6.55k
    uint8_t *buf;
735
6.55k
    int compress_frame_size, pic_size, ret, is_top_field_first = 0;
736
6.55k
    uint8_t frame_flags;
737
6.55k
    int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + FF_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
738
739
740
6.55k
    if ((ret = ff_alloc_packet(avctx, pkt, frame_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
741
0
        return ret;
742
743
6.55k
    buf = pkt->data;
744
6.55k
    compress_frame_size = 8 + header_size;
745
746
6.55k
    bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
747
6.55k
    bytestream_put_be32(&buf, FRAME_ID);
748
749
6.55k
    bytestream_put_be16(&buf, header_size);
750
6.55k
    bytestream_put_be16(&buf, avctx->pix_fmt != AV_PIX_FMT_YUV422P10 || ctx->need_alpha ? 1 : 0); /* version */
751
6.55k
    bytestream_put_buffer(&buf, ctx->vendor, 4);
752
6.55k
    bytestream_put_be16(&buf, avctx->width);
753
6.55k
    bytestream_put_be16(&buf, avctx->height);
754
6.55k
    frame_flags = 0x80; /* 422 not interlaced */
755
6.55k
    if (avctx->profile >= AV_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
756
2.19k
        frame_flags |= 0x40; /* 444 chroma */
757
6.55k
    if (ctx->is_interlaced) {
758
0
        if ((pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) || !(pict->flags & AV_FRAME_FLAG_INTERLACED)) {
759
            /* tff frame or progressive frame interpret as tff */
760
0
            av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
761
0
            frame_flags |= 0x04; /* interlaced tff */
762
0
            is_top_field_first = 1;
763
0
        } else {
764
0
            av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
765
0
            frame_flags |= 0x08; /* interlaced bff */
766
0
        }
767
6.55k
    } else {
768
6.55k
        av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
769
6.55k
    }
770
6.55k
    *buf++ = frame_flags;
771
6.55k
    *buf++ = 0; /* reserved */
772
    /* only write color properties, if valid value. set to unspecified otherwise */
773
6.55k
    *buf++ = int_from_list_or_default(avctx, "frame color primaries",
774
6.55k
                                      pict->color_primaries, valid_primaries, 0);
775
6.55k
    *buf++ = int_from_list_or_default(avctx, "frame color trc",
776
6.55k
                                      pict->color_trc, valid_trc, 0);
777
6.55k
    *buf++ = int_from_list_or_default(avctx, "frame colorspace",
778
6.55k
                                      pict->colorspace, valid_colorspace, 0);
779
6.55k
    *buf++ = ctx->need_alpha ? 0x2 /* 16-bit alpha */ : 0;
780
6.55k
    *buf++ = 0; /* reserved */
781
6.55k
    *buf++ = 3; /* luma and chroma matrix present */
782
783
6.55k
    bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
784
6.55k
    bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
785
786
6.55k
    pic_size = prores_encode_picture(avctx, pict, buf,
787
6.55k
                                     pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
788
6.55k
    if (pic_size < 0) {
789
0
        return pic_size;
790
0
    }
791
6.55k
    compress_frame_size += pic_size;
792
793
6.55k
    if (ctx->is_interlaced) { /* encode second field */
794
0
        pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
795
0
                                         pkt->size - compress_frame_size, 1, !is_top_field_first);
796
0
        if (pic_size < 0) {
797
0
            return pic_size;
798
0
        }
799
0
        compress_frame_size += pic_size;
800
0
    }
801
802
6.55k
    AV_WB32(pkt->data, compress_frame_size);/* update frame size */
803
6.55k
    pkt->size = compress_frame_size;
804
6.55k
    *got_packet = 1;
805
806
6.55k
    return 0;
807
6.55k
}
808
809
static void scale_mat(const uint8_t* src, int* dst, int scale)
810
39.4k
{
811
39.4k
    int i;
812
2.56M
    for (i = 0; i < 64; i++)
813
2.52M
        dst[i] = src[i] * scale;
814
39.4k
}
815
816
static av_cold int prores_encode_init(AVCodecContext *avctx)
817
1.25k
{
818
1.25k
    int i;
819
1.25k
    ProresContext* ctx = avctx->priv_data;
820
821
1.25k
    avctx->bits_per_raw_sample = 10;
822
1.25k
    ctx->need_alpha = 0;
823
1.25k
    ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
824
1.25k
    if (ctx->is_interlaced) {
825
0
        ctx->scantable = ff_prores_interlaced_scan;
826
1.25k
    } else {
827
1.25k
        ctx->scantable = ff_prores_progressive_scan;
828
1.25k
    }
829
830
1.25k
    if (avctx->width & 0x1) {
831
21
        av_log(avctx, AV_LOG_ERROR,
832
21
                "frame width needs to be multiple of 2\n");
833
21
        return AVERROR(EINVAL);
834
21
    }
835
836
1.23k
    if (avctx->width > 65534 || avctx->height > 65535) {
837
0
        av_log(avctx, AV_LOG_ERROR,
838
0
                "The maximum dimensions are 65534x65535\n");
839
0
        return AVERROR(EINVAL);
840
0
    }
841
842
1.23k
    if (strlen(ctx->vendor) != 4) {
843
0
        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
844
0
        return AVERROR(EINVAL);
845
0
    }
846
847
1.23k
    if (avctx->profile == AV_PROFILE_UNKNOWN) {
848
1.23k
        if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
849
428
            avctx->profile = AV_PROFILE_PRORES_STANDARD;
850
428
            av_log(avctx, AV_LOG_INFO,
851
428
                "encoding with ProRes standard (apcn) profile\n");
852
804
        } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
853
145
            avctx->profile = AV_PROFILE_PRORES_4444;
854
145
            av_log(avctx, AV_LOG_INFO,
855
145
                   "encoding with ProRes 4444 (ap4h) profile\n");
856
659
        } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
857
659
            avctx->profile = AV_PROFILE_PRORES_4444;
858
659
            av_log(avctx, AV_LOG_INFO,
859
659
                   "encoding with ProRes 4444+ (ap4h) profile\n");
860
659
        } else
861
0
            av_assert0(0);
862
1.23k
    } else if (avctx->profile < AV_PROFILE_PRORES_PROXY
863
0
            || avctx->profile > AV_PROFILE_PRORES_XQ) {
864
0
        av_log(
865
0
                avctx,
866
0
                AV_LOG_ERROR,
867
0
                "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
868
0
                avctx->profile);
869
0
        return AVERROR(EINVAL);
870
0
    } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > AV_PROFILE_PRORES_HQ)){
871
0
        av_log(avctx, AV_LOG_ERROR,
872
0
               "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
873
0
        return AVERROR(EINVAL);
874
0
    }  else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
875
0
                && (avctx->profile < AV_PROFILE_PRORES_4444)){
876
0
        av_log(avctx, AV_LOG_ERROR,
877
0
               "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
878
0
        return AVERROR(EINVAL);
879
0
    }
880
881
1.23k
    if (avctx->profile < AV_PROFILE_PRORES_4444) { /* 422 versions */
882
428
        ctx->is_422 = 1;
883
428
        if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
884
277
            ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
885
277
            if (!ctx->fill_y)
886
0
                return AVERROR(ENOMEM);
887
277
            ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
888
277
            ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
889
277
        }
890
804
    } else { /* 444 */
891
804
        ctx->is_422 = 0;
892
804
        if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
893
572
            ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
894
572
            if (!ctx->fill_y)
895
0
                return AVERROR(ENOMEM);
896
572
            ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
897
572
            ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
898
572
        }
899
804
        if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
900
659
            ctx->need_alpha = 1;
901
659
            ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
902
659
            if (!ctx->fill_a)
903
0
                return AVERROR(ENOMEM);
904
659
        }
905
804
    }
906
907
1.23k
    if (ctx->need_alpha)
908
659
        avctx->bits_per_coded_sample = 32;
909
910
1.23k
    ff_fdctdsp_init(&ctx->fdsp, avctx);
911
912
1.23k
    avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
913
914
20.9k
    for (i = 1; i <= 16; i++) {
915
19.7k
        scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
916
19.7k
        scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
917
19.7k
    }
918
919
1.23k
    return 0;
920
1.23k
}
921
922
static av_cold int prores_encode_close(AVCodecContext *avctx)
923
1.25k
{
924
1.25k
    ProresContext* ctx = avctx->priv_data;
925
1.25k
    av_freep(&ctx->fill_y);
926
1.25k
    av_freep(&ctx->fill_a);
927
928
1.25k
    return 0;
929
1.25k
}
930
931
#define OFFSET(x) offsetof(ProresContext, x)
932
#define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
933
934
static const AVOption options[] = {
935
    { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, 0, 0, VE },
936
    { NULL }
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
static const enum AVPixelFormat pix_fmts[] = {
947
    AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
948
    AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
949
};
950
951
const FFCodec ff_prores_aw_encoder = {
952
    .p.name         = "prores_aw",
953
    CODEC_LONG_NAME("Apple ProRes"),
954
    .p.type         = AVMEDIA_TYPE_VIDEO,
955
    .p.id           = AV_CODEC_ID_PRORES,
956
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
957
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
958
    .p.pix_fmts     = pix_fmts,
959
    .priv_data_size = sizeof(ProresContext),
960
    .init           = prores_encode_init,
961
    .close          = prores_encode_close,
962
    FF_CODEC_ENCODE_CB(prores_encode_frame),
963
    .p.priv_class   = &prores_enc_class,
964
    .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
965
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
966
};
967
968
const FFCodec ff_prores_encoder = {
969
    .p.name         = "prores",
970
    CODEC_LONG_NAME("Apple ProRes"),
971
    .p.type         = AVMEDIA_TYPE_VIDEO,
972
    .p.id           = AV_CODEC_ID_PRORES,
973
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
974
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
975
    .p.pix_fmts     = pix_fmts,
976
    .priv_data_size = sizeof(ProresContext),
977
    .init           = prores_encode_init,
978
    .close          = prores_encode_close,
979
    FF_CODEC_ENCODE_CB(prores_encode_frame),
980
    .p.priv_class   = &prores_enc_class,
981
    .p.profiles     = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
982
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
983
};