4 * Copyright (c) 2011 Anatoliy Wasserman
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * Apple ProRes encoder (Anatoliy Wasserman version)
26 * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
32 #include "proresdata.h"
34 #include "bytestream.h"
37 #define DEFAULT_SLICE_MB_WIDTH 8
39 #define FF_PROFILE_PRORES_PROXY 0
40 #define FF_PROFILE_PRORES_LT 1
41 #define FF_PROFILE_PRORES_STANDARD 2
42 #define FF_PROFILE_PRORES_HQ 3
44 static const AVProfile profiles[] = {
45 { FF_PROFILE_PRORES_PROXY, "apco"},
46 { FF_PROFILE_PRORES_LT, "apcs"},
47 { FF_PROFILE_PRORES_STANDARD, "apcn"},
48 { FF_PROFILE_PRORES_HQ, "apch"},
49 { FF_PROFILE_UNKNOWN }
52 static const int qp_start_table[4] = { 8, 3, 2, 1 };
53 static const int qp_end_table[4] = { 13, 9, 6, 6 };
54 static const int bitrate_table[5] = { 1000, 2100, 3500, 5400 };
56 static const uint8_t QMAT_LUMA[4][64] = {
58 4, 7, 9, 11, 13, 14, 15, 63,
59 7, 7, 11, 12, 14, 15, 63, 63,
60 9, 11, 13, 14, 15, 63, 63, 63,
61 11, 11, 13, 14, 63, 63, 63, 63,
62 11, 13, 14, 63, 63, 63, 63, 63,
63 13, 14, 63, 63, 63, 63, 63, 63,
64 13, 63, 63, 63, 63, 63, 63, 63,
65 63, 63, 63, 63, 63, 63, 63, 63
67 4, 5, 6, 7, 9, 11, 13, 15,
68 5, 5, 7, 8, 11, 13, 15, 17,
69 6, 7, 9, 11, 13, 15, 15, 17,
70 7, 7, 9, 11, 13, 15, 17, 19,
71 7, 9, 11, 13, 14, 16, 19, 23,
72 9, 11, 13, 14, 16, 19, 23, 29,
73 9, 11, 13, 15, 17, 21, 28, 35,
74 11, 13, 16, 17, 21, 28, 35, 41
76 4, 4, 5, 5, 6, 7, 7, 9,
77 4, 4, 5, 6, 7, 7, 9, 9,
78 5, 5, 6, 7, 7, 9, 9, 10,
79 5, 5, 6, 7, 7, 9, 9, 10,
80 5, 6, 7, 7, 8, 9, 10, 12,
81 6, 7, 7, 8, 9, 10, 12, 15,
82 6, 7, 7, 9, 10, 11, 14, 17,
83 7, 7, 9, 10, 11, 14, 17, 21
85 4, 4, 4, 4, 4, 4, 4, 4,
86 4, 4, 4, 4, 4, 4, 4, 4,
87 4, 4, 4, 4, 4, 4, 4, 4,
88 4, 4, 4, 4, 4, 4, 4, 5,
89 4, 4, 4, 4, 4, 4, 5, 5,
90 4, 4, 4, 4, 4, 5, 5, 6,
91 4, 4, 4, 4, 5, 5, 6, 7,
92 4, 4, 4, 4, 5, 6, 7, 7
96 static const uint8_t QMAT_CHROMA[4][64] = {
98 4, 7, 9, 11, 13, 14, 63, 63,
99 7, 7, 11, 12, 14, 63, 63, 63,
100 9, 11, 13, 14, 63, 63, 63, 63,
101 11, 11, 13, 14, 63, 63, 63, 63,
102 11, 13, 14, 63, 63, 63, 63, 63,
103 13, 14, 63, 63, 63, 63, 63, 63,
104 13, 63, 63, 63, 63, 63, 63, 63,
105 63, 63, 63, 63, 63, 63, 63, 63
107 4, 5, 6, 7, 9, 11, 13, 15,
108 5, 5, 7, 8, 11, 13, 15, 17,
109 6, 7, 9, 11, 13, 15, 15, 17,
110 7, 7, 9, 11, 13, 15, 17, 19,
111 7, 9, 11, 13, 14, 16, 19, 23,
112 9, 11, 13, 14, 16, 19, 23, 29,
113 9, 11, 13, 15, 17, 21, 28, 35,
114 11, 13, 16, 17, 21, 28, 35, 41
116 4, 4, 5, 5, 6, 7, 7, 9,
117 4, 4, 5, 6, 7, 7, 9, 9,
118 5, 5, 6, 7, 7, 9, 9, 10,
119 5, 5, 6, 7, 7, 9, 9, 10,
120 5, 6, 7, 7, 8, 9, 10, 12,
121 6, 7, 7, 8, 9, 10, 12, 15,
122 6, 7, 7, 9, 10, 11, 14, 17,
123 7, 7, 9, 10, 11, 14, 17, 21
125 4, 4, 4, 4, 4, 4, 4, 4,
126 4, 4, 4, 4, 4, 4, 4, 4,
127 4, 4, 4, 4, 4, 4, 4, 4,
128 4, 4, 4, 4, 4, 4, 4, 5,
129 4, 4, 4, 4, 4, 4, 5, 5,
130 4, 4, 4, 4, 4, 5, 5, 6,
131 4, 4, 4, 4, 5, 5, 6, 7,
132 4, 4, 4, 4, 5, 6, 7, 7
143 int qmat_luma[16][64];
144 int qmat_chroma[16][64];
147 static void encode_codeword(PutBitContext *pb, int val, int codebook)
149 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
151 /* number of bits to switch between rice and exp golomb */
152 switch_bits = codebook & 3;
153 rice_order = codebook >> 5;
154 exp_order = (codebook >> 2) & 7;
156 first_exp = ((switch_bits + 1) << rice_order);
158 if (val >= first_exp) { /* exp golomb */
160 val += (1 << exp_order);
162 zeros = exp - exp_order + switch_bits + 1;
163 put_bits(pb, zeros, 0);
164 put_bits(pb, exp + 1, val);
165 } else if (rice_order) {
166 put_bits(pb, (val >> rice_order), 0);
168 put_sbits(pb, rice_order, val);
170 put_bits(pb, val, 0);
175 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
176 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
177 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
178 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
179 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
181 static av_always_inline int get_level(int val)
183 int sign = (val >> 31);
184 return (val ^ sign) - sign;
187 #define FIRST_DC_CB 0xB8
189 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
191 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
192 int blocks_per_slice, int *qmat)
196 int new_dc, delta, diff_sign, new_code;
198 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
199 code = TO_GOLOMB(prev_dc);
200 encode_codeword(pb, code, FIRST_DC_CB);
202 code = 5; sign = 0; idx = 64;
203 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
204 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
205 delta = new_dc - prev_dc;
206 diff_sign = DIFF_SIGN(delta, sign);
207 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
209 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
217 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
218 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
219 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
220 0x28, 0x28, 0x28, 0x4C };
222 static void encode_ac_coeffs(PutBitContext *pb,
223 int16_t *in, int blocks_per_slice, int *qmat)
228 int run = 0, level, code, i, j;
229 for (i = 1; i < 64; i++) {
230 int indp = ff_prores_progressive_scan[i];
231 for (j = 0; j < blocks_per_slice; j++) {
232 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
234 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
238 level = get_level(val);
241 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
245 put_bits(pb, 1, IS_NEGATIVE(val));
253 static void get(uint8_t *pixels, int stride, int16_t* block)
257 for (i = 0; i < 8; i++) {
258 AV_WN64(block, AV_RN64(pixels));
259 AV_WN64(block+4, AV_RN64(pixels+8));
265 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
267 get(pixels, stride, block);
271 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma)
277 for (i = 0; i < mb_count; i++) {
278 fdct_get(fdsp, src, src_stride, block + (0 << 6));
279 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
281 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
282 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
285 block += (256 >> chroma);
286 src += (32 >> chroma);
290 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int chroma)
292 int blocks_per_slice;
295 blocks_per_slice = mb_count << (2 - chroma);
296 init_put_bits(&pb, buf, buf_size);
298 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
299 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat);
302 return put_bits_ptr(&pb) - pb.buf;
305 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
306 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
307 unsigned mb_count, uint8_t *buf, unsigned data_size,
308 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
311 ProresContext* ctx = avctx->priv_data;
313 *y_data_size = encode_slice_plane(blocks_y, mb_count,
314 buf, data_size, ctx->qmat_luma[qp - 1], 0);
316 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
317 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
318 ctx->qmat_chroma[qp - 1], 1);
320 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
321 data_size - *y_data_size - *u_data_size,
322 ctx->qmat_chroma[qp - 1], 1);
325 return *y_data_size + *u_data_size + *v_data_size;
328 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
329 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
330 unsigned dst_width, unsigned dst_height)
333 int box_width = FFMIN(width - x, dst_width);
334 int box_height = FFMIN(height - y, dst_height);
335 int i, j, src_stride = stride >> 1;
336 uint16_t last_pix, *last_line;
338 src += y * src_stride + x;
339 for (i = 0; i < box_height; ++i) {
340 for (j = 0; j < box_width; ++j) {
343 last_pix = dst[j - 1];
344 for (; j < dst_width; j++)
349 last_line = dst - dst_width;
350 for (; i < dst_height; i++) {
351 for (j = 0; j < dst_width; ++j) {
352 dst[j] = last_line[j];
358 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
359 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
362 int luma_stride, chroma_stride;
363 int hdr_size = 6, slice_size;
364 uint8_t *dest_y, *dest_u, *dest_v;
365 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
366 ProresContext* ctx = avctx->priv_data;
367 FDCTDSPContext *fdsp = &ctx->fdsp;
368 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
369 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
370 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
372 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
373 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
374 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
376 luma_stride = pic->linesize[0];
377 chroma_stride = pic->linesize[1];
379 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
380 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
381 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
385 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
386 luma_stride, avctx->width, avctx->height,
387 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
388 subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
389 chroma_stride, avctx->width >> 1, avctx->height,
390 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
391 subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
392 chroma_stride, avctx->width >> 1, avctx->height,
393 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
395 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0);
396 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << 4, mb_count, 1);
397 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << 4, mb_count, 1);
399 encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
400 mb_count, buf + hdr_size, data_size - hdr_size,
401 &y_data_size, &u_data_size, &v_data_size,
404 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0);
405 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1);
406 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1);
408 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
409 mb_count, buf + hdr_size, data_size - hdr_size,
410 &y_data_size, &u_data_size, &v_data_size,
413 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
416 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
417 mb_count, buf + hdr_size, data_size - hdr_size,
418 &y_data_size, &u_data_size, &v_data_size,
420 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
421 } else if (slice_size < low_bytes && *qp
422 > qp_start_table[avctx->profile]) {
425 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
426 mb_count, buf + hdr_size, data_size - hdr_size,
427 &y_data_size, &u_data_size, &v_data_size,
429 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
433 buf[0] = hdr_size << 3;
435 AV_WB16(buf + 2, y_data_size);
436 AV_WB16(buf + 4, u_data_size);
438 return hdr_size + y_data_size + u_data_size + v_data_size;
441 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
442 uint8_t *buf, const int buf_size)
444 int mb_width = (avctx->width + 15) >> 4;
445 int mb_height = (avctx->height + 15) >> 4;
446 int hdr_size, sl_size, i;
447 int mb_y, sl_data_size, qp;
448 int unsafe_bot, unsafe_right;
449 uint8_t *sl_data, *sl_data_sizes;
450 int slice_per_line = 0, rem = mb_width;
452 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
453 slice_per_line += rem >> i;
457 qp = qp_start_table[avctx->profile];
458 hdr_size = 8; sl_data_size = buf_size - hdr_size;
459 sl_data_sizes = buf + hdr_size;
460 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
461 for (mb_y = 0; mb_y < mb_height; mb_y++) {
463 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
464 while (mb_x < mb_width) {
465 while (mb_width - mb_x < slice_mb_count)
466 slice_mb_count >>= 1;
468 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
469 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
471 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
472 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
474 bytestream_put_be16(&sl_data_sizes, sl_size);
476 sl_data_size -= sl_size;
477 mb_x += slice_mb_count;
481 buf[0] = hdr_size << 3;
482 AV_WB32(buf + 1, sl_data - buf);
483 AV_WB16(buf + 5, slice_per_line * mb_height);
484 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
486 return sl_data - buf;
489 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
490 const AVFrame *pict, int *got_packet)
492 int header_size = 148;
495 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
498 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
502 pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
503 pkt->size - header_size - 8);
505 bytestream_put_be32(&buf, pic_size + 8 + header_size);
506 bytestream_put_buffer(&buf, "icpf", 4);
508 bytestream_put_be16(&buf, header_size);
509 bytestream_put_be16(&buf, 0);
510 bytestream_put_buffer(&buf, "fmpg", 4);
511 bytestream_put_be16(&buf, avctx->width);
512 bytestream_put_be16(&buf, avctx->height);
513 *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
515 *buf++ = pict->color_primaries;
516 *buf++ = pict->color_trc;
517 *buf++ = pict->colorspace;
522 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
523 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
525 pkt->flags |= AV_PKT_FLAG_KEY;
526 pkt->size = pic_size + 8 + header_size;
532 static void scale_mat(const uint8_t* src, int* dst, int scale)
535 for (i = 0; i < 64; i++)
536 dst[i] = src[i] * scale;
539 static av_cold int prores_encode_init(AVCodecContext *avctx)
542 ProresContext* ctx = avctx->priv_data;
544 if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
545 av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
546 return AVERROR_PATCHWELCOME;
548 avctx->bits_per_raw_sample = 10;
550 if (avctx->width & 0x1) {
551 av_log(avctx, AV_LOG_ERROR,
552 "frame width needs to be multiple of 2\n");
553 return AVERROR(EINVAL);
556 if (avctx->width > 65534 || avctx->height > 65535) {
557 av_log(avctx, AV_LOG_ERROR,
558 "The maximum dimensions are 65534x65535\n");
559 return AVERROR(EINVAL);
562 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
563 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
565 return AVERROR(ENOMEM);
566 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
567 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
570 if (avctx->profile == FF_PROFILE_UNKNOWN) {
571 avctx->profile = FF_PROFILE_PRORES_STANDARD;
572 av_log(avctx, AV_LOG_INFO,
573 "encoding with ProRes standard (apcn) profile\n");
575 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
576 || avctx->profile > FF_PROFILE_PRORES_HQ) {
580 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
582 return AVERROR(EINVAL);
585 ff_fdctdsp_init(&ctx->fdsp, avctx);
587 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
589 for (i = 1; i <= 16; i++) {
590 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
591 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
597 static av_cold int prores_encode_close(AVCodecContext *avctx)
599 ProresContext* ctx = avctx->priv_data;
600 av_freep(&ctx->fill_y);
605 AVCodec ff_prores_aw_encoder = {
607 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
608 .type = AVMEDIA_TYPE_VIDEO,
609 .id = AV_CODEC_ID_PRORES,
610 .priv_data_size = sizeof(ProresContext),
611 .init = prores_encode_init,
612 .close = prores_encode_close,
613 .encode2 = prores_encode_frame,
614 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
615 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
619 AVCodec ff_prores_encoder = {
621 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
622 .type = AVMEDIA_TYPE_VIDEO,
623 .id = AV_CODEC_ID_PRORES,
624 .priv_data_size = sizeof(ProresContext),
625 .init = prores_encode_init,
626 .close = prores_encode_close,
627 .encode2 = prores_encode_frame,
628 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
629 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,