avformat/mpeg: demux ivtv captions
[ffmpeg.git] / libavcodec / librav1e.c
blob546d00297d92f4487956fa13d88b8ada18d2426e
1 /*
2 * librav1e encoder
4 * Copyright (c) 2019 Derek Buitenhuis
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
23 #include <rav1e.h>
25 #include "libavutil/buffer.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/base64.h"
29 #include "libavutil/common.h"
30 #include "libavutil/mathematics.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/pixdesc.h"
34 #include "avcodec.h"
35 #include "codec_internal.h"
36 #include "encode.h"
37 #include "internal.h"
39 typedef struct librav1eContext {
40 const AVClass *class;
42 RaContext *ctx;
43 AVFrame *frame;
44 RaFrame *rframe;
46 uint8_t *pass_data;
47 size_t pass_pos;
48 int pass_size;
50 AVDictionary *rav1e_opts;
51 int quantizer;
52 int speed;
53 int tiles;
54 int tile_rows;
55 int tile_cols;
56 } librav1eContext;
58 typedef struct FrameData {
59 int64_t pts;
60 int64_t duration;
62 void *frame_opaque;
63 AVBufferRef *frame_opaque_ref;
64 } FrameData;
66 static inline RaPixelRange range_map(enum AVPixelFormat pix_fmt, enum AVColorRange range)
68 switch (pix_fmt) {
69 case AV_PIX_FMT_YUVJ420P:
70 case AV_PIX_FMT_YUVJ422P:
71 case AV_PIX_FMT_YUVJ444P:
72 return RA_PIXEL_RANGE_FULL;
75 switch (range) {
76 case AVCOL_RANGE_JPEG:
77 return RA_PIXEL_RANGE_FULL;
78 case AVCOL_RANGE_MPEG:
79 default:
80 return RA_PIXEL_RANGE_LIMITED;
84 static inline RaChromaSampling pix_fmt_map(enum AVPixelFormat pix_fmt)
86 switch (pix_fmt) {
87 case AV_PIX_FMT_YUV420P:
88 case AV_PIX_FMT_YUVJ420P:
89 case AV_PIX_FMT_YUV420P10:
90 case AV_PIX_FMT_YUV420P12:
91 return RA_CHROMA_SAMPLING_CS420;
92 case AV_PIX_FMT_YUV422P:
93 case AV_PIX_FMT_YUVJ422P:
94 case AV_PIX_FMT_YUV422P10:
95 case AV_PIX_FMT_YUV422P12:
96 return RA_CHROMA_SAMPLING_CS422;
97 case AV_PIX_FMT_YUV444P:
98 case AV_PIX_FMT_YUVJ444P:
99 case AV_PIX_FMT_YUV444P10:
100 case AV_PIX_FMT_YUV444P12:
101 return RA_CHROMA_SAMPLING_CS444;
102 default:
103 av_assert0(0);
107 static inline RaChromaSamplePosition chroma_loc_map(enum AVChromaLocation chroma_loc)
109 switch (chroma_loc) {
110 case AVCHROMA_LOC_LEFT:
111 return RA_CHROMA_SAMPLE_POSITION_VERTICAL;
112 case AVCHROMA_LOC_TOPLEFT:
113 return RA_CHROMA_SAMPLE_POSITION_COLOCATED;
114 default:
115 return RA_CHROMA_SAMPLE_POSITION_UNKNOWN;
119 static int get_stats(AVCodecContext *avctx, int eos)
121 librav1eContext *ctx = avctx->priv_data;
122 RaData* buf = rav1e_twopass_out(ctx->ctx);
123 if (!buf)
124 return 0;
126 if (!eos) {
127 uint8_t *tmp = av_fast_realloc(ctx->pass_data, &ctx->pass_size,
128 ctx->pass_pos + buf->len);
129 if (!tmp) {
130 rav1e_data_unref(buf);
131 return AVERROR(ENOMEM);
134 ctx->pass_data = tmp;
135 memcpy(ctx->pass_data + ctx->pass_pos, buf->data, buf->len);
136 ctx->pass_pos += buf->len;
137 } else {
138 size_t b64_size = AV_BASE64_SIZE(ctx->pass_pos);
140 memcpy(ctx->pass_data, buf->data, buf->len);
142 avctx->stats_out = av_malloc(b64_size);
143 if (!avctx->stats_out) {
144 rav1e_data_unref(buf);
145 return AVERROR(ENOMEM);
148 av_base64_encode(avctx->stats_out, b64_size, ctx->pass_data, ctx->pass_pos);
150 av_freep(&ctx->pass_data);
153 rav1e_data_unref(buf);
155 return 0;
158 static int set_stats(AVCodecContext *avctx)
160 librav1eContext *ctx = avctx->priv_data;
161 int ret = 1;
163 while (ret > 0 && ctx->pass_size - ctx->pass_pos > 0) {
164 ret = rav1e_twopass_in(ctx->ctx, ctx->pass_data + ctx->pass_pos, ctx->pass_size);
165 if (ret < 0)
166 return AVERROR_EXTERNAL;
167 ctx->pass_pos += ret;
170 return 0;
173 static av_cold int librav1e_encode_close(AVCodecContext *avctx)
175 librav1eContext *ctx = avctx->priv_data;
177 if (ctx->ctx) {
178 rav1e_context_unref(ctx->ctx);
179 ctx->ctx = NULL;
181 if (ctx->rframe) {
182 rav1e_frame_unref(ctx->rframe);
183 ctx->rframe = NULL;
186 av_frame_free(&ctx->frame);
187 av_freep(&ctx->pass_data);
189 return 0;
192 static av_cold int librav1e_encode_init(AVCodecContext *avctx)
194 librav1eContext *ctx = avctx->priv_data;
195 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
196 RaConfig *cfg = NULL;
197 int rret;
198 int ret = 0;
200 ctx->frame = av_frame_alloc();
201 if (!ctx->frame)
202 return AVERROR(ENOMEM);
204 cfg = rav1e_config_default();
205 if (!cfg) {
206 av_log(avctx, AV_LOG_ERROR, "Could not allocate rav1e config.\n");
207 return AVERROR_EXTERNAL;
211 * Rav1e currently uses the time base given to it only for ratecontrol... where
212 * the inverse is taken and used as a framerate. So, do what we do in other wrappers
213 * and use the framerate if we can.
215 if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
216 rav1e_config_set_time_base(cfg, (RaRational) {
217 avctx->framerate.den, avctx->framerate.num
219 } else {
220 FF_DISABLE_DEPRECATION_WARNINGS
221 rav1e_config_set_time_base(cfg, (RaRational) {
222 avctx->time_base.num
223 #if FF_API_TICKS_PER_FRAME
224 * avctx->ticks_per_frame
225 #endif
226 , avctx->time_base.den
228 FF_ENABLE_DEPRECATION_WARNINGS
231 if ((avctx->flags & AV_CODEC_FLAG_PASS1 || avctx->flags & AV_CODEC_FLAG_PASS2) && !avctx->bit_rate) {
232 av_log(avctx, AV_LOG_ERROR, "A bitrate must be set to use two pass mode.\n");
233 ret = AVERROR_INVALIDDATA;
234 goto end;
237 if (avctx->flags & AV_CODEC_FLAG_PASS2) {
238 if (!avctx->stats_in) {
239 av_log(avctx, AV_LOG_ERROR, "No stats file provided for second pass.\n");
240 ret = AVERROR(EINVAL);
241 goto end;
244 ctx->pass_size = (strlen(avctx->stats_in) * 3) / 4;
245 ctx->pass_data = av_malloc(ctx->pass_size);
246 if (!ctx->pass_data) {
247 av_log(avctx, AV_LOG_ERROR, "Could not allocate stats buffer.\n");
248 ret = AVERROR(ENOMEM);
249 goto end;
252 ctx->pass_size = av_base64_decode(ctx->pass_data, avctx->stats_in, ctx->pass_size);
253 if (ctx->pass_size < 0) {
254 av_log(avctx, AV_LOG_ERROR, "Invalid pass file.\n");
255 ret = AVERROR(EINVAL);
256 goto end;
261 const AVDictionaryEntry *en = NULL;
262 while ((en = av_dict_iterate(ctx->rav1e_opts, en))) {
263 if (rav1e_config_parse(cfg, en->key, en->value) < 0)
264 av_log(avctx, AV_LOG_WARNING, "Invalid value for %s: %s.\n", en->key, en->value);
268 rret = rav1e_config_parse_int(cfg, "width", avctx->width);
269 if (rret < 0) {
270 av_log(avctx, AV_LOG_ERROR, "Invalid width passed to rav1e.\n");
271 ret = AVERROR_INVALIDDATA;
272 goto end;
275 rret = rav1e_config_parse_int(cfg, "height", avctx->height);
276 if (rret < 0) {
277 av_log(avctx, AV_LOG_ERROR, "Invalid height passed to rav1e.\n");
278 ret = AVERROR_INVALIDDATA;
279 goto end;
282 if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
283 rav1e_config_set_sample_aspect_ratio(cfg, (RaRational) {
284 avctx->sample_aspect_ratio.num,
285 avctx->sample_aspect_ratio.den
288 rret = rav1e_config_parse_int(cfg, "threads", avctx->thread_count);
289 if (rret < 0)
290 av_log(avctx, AV_LOG_WARNING, "Invalid number of threads, defaulting to auto.\n");
292 if (ctx->speed >= 0) {
293 rret = rav1e_config_parse_int(cfg, "speed", ctx->speed);
294 if (rret < 0) {
295 av_log(avctx, AV_LOG_ERROR, "Could not set speed preset.\n");
296 ret = AVERROR_EXTERNAL;
297 goto end;
301 /* rav1e handles precedence between 'tiles' and cols/rows for us. */
302 if (ctx->tiles > 0) {
303 rret = rav1e_config_parse_int(cfg, "tiles", ctx->tiles);
304 if (rret < 0) {
305 av_log(avctx, AV_LOG_ERROR, "Could not set number of tiles to encode with.\n");
306 ret = AVERROR_EXTERNAL;
307 goto end;
310 if (ctx->tile_rows > 0) {
311 rret = rav1e_config_parse_int(cfg, "tile_rows", ctx->tile_rows);
312 if (rret < 0) {
313 av_log(avctx, AV_LOG_ERROR, "Could not set number of tile rows to encode with.\n");
314 ret = AVERROR_EXTERNAL;
315 goto end;
318 if (ctx->tile_cols > 0) {
319 rret = rav1e_config_parse_int(cfg, "tile_cols", ctx->tile_cols);
320 if (rret < 0) {
321 av_log(avctx, AV_LOG_ERROR, "Could not set number of tile cols to encode with.\n");
322 ret = AVERROR_EXTERNAL;
323 goto end;
327 if (avctx->gop_size > 0) {
328 rret = rav1e_config_parse_int(cfg, "key_frame_interval", avctx->gop_size);
329 if (rret < 0) {
330 av_log(avctx, AV_LOG_ERROR, "Could not set max keyint.\n");
331 ret = AVERROR_EXTERNAL;
332 goto end;
336 if (avctx->keyint_min > 0) {
337 rret = rav1e_config_parse_int(cfg, "min_key_frame_interval", avctx->keyint_min);
338 if (rret < 0) {
339 av_log(avctx, AV_LOG_ERROR, "Could not set min keyint.\n");
340 ret = AVERROR_EXTERNAL;
341 goto end;
345 if (avctx->bit_rate && ctx->quantizer < 0) {
346 int max_quantizer = avctx->qmax >= 0 ? avctx->qmax : 255;
348 rret = rav1e_config_parse_int(cfg, "quantizer", max_quantizer);
349 if (rret < 0) {
350 av_log(avctx, AV_LOG_ERROR, "Could not set max quantizer.\n");
351 ret = AVERROR_EXTERNAL;
352 goto end;
355 if (avctx->qmin >= 0) {
356 rret = rav1e_config_parse_int(cfg, "min_quantizer", avctx->qmin);
357 if (rret < 0) {
358 av_log(avctx, AV_LOG_ERROR, "Could not set min quantizer.\n");
359 ret = AVERROR_EXTERNAL;
360 goto end;
364 rret = rav1e_config_parse_int(cfg, "bitrate", avctx->bit_rate);
365 if (rret < 0) {
366 av_log(avctx, AV_LOG_ERROR, "Could not set bitrate.\n");
367 ret = AVERROR_INVALIDDATA;
368 goto end;
370 } else if (ctx->quantizer >= 0) {
371 if (avctx->bit_rate)
372 av_log(avctx, AV_LOG_WARNING, "Both bitrate and quantizer specified. Using quantizer mode.");
374 rret = rav1e_config_parse_int(cfg, "quantizer", ctx->quantizer);
375 if (rret < 0) {
376 av_log(avctx, AV_LOG_ERROR, "Could not set quantizer.\n");
377 ret = AVERROR_EXTERNAL;
378 goto end;
382 rret = rav1e_config_set_pixel_format(cfg, desc->comp[0].depth,
383 pix_fmt_map(avctx->pix_fmt),
384 chroma_loc_map(avctx->chroma_sample_location),
385 range_map(avctx->pix_fmt, avctx->color_range));
386 if (rret < 0) {
387 av_log(avctx, AV_LOG_ERROR, "Failed to set pixel format properties.\n");
388 ret = AVERROR_INVALIDDATA;
389 goto end;
392 /* rav1e's colorspace enums match standard values. */
393 rret = rav1e_config_set_color_description(cfg, (RaMatrixCoefficients) avctx->colorspace,
394 (RaColorPrimaries) avctx->color_primaries,
395 (RaTransferCharacteristics) avctx->color_trc);
396 if (rret < 0) {
397 av_log(avctx, AV_LOG_WARNING, "Failed to set color properties.\n");
398 if (avctx->err_recognition & AV_EF_EXPLODE) {
399 ret = AVERROR_INVALIDDATA;
400 goto end;
404 ctx->ctx = rav1e_context_new(cfg);
405 if (!ctx->ctx) {
406 av_log(avctx, AV_LOG_ERROR, "Failed to create rav1e encode context.\n");
407 ret = AVERROR_EXTERNAL;
408 goto end;
411 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
412 RaData *seq_hdr = rav1e_container_sequence_header(ctx->ctx);
414 if (seq_hdr)
415 avctx->extradata = av_mallocz(seq_hdr->len + AV_INPUT_BUFFER_PADDING_SIZE);
416 if (!seq_hdr || !avctx->extradata) {
417 rav1e_data_unref(seq_hdr);
418 av_log(avctx, AV_LOG_ERROR, "Failed to get extradata.\n");
419 ret = seq_hdr ? AVERROR(ENOMEM) : AVERROR_EXTERNAL;
420 goto end;
423 memcpy(avctx->extradata, seq_hdr->data, seq_hdr->len);
424 avctx->extradata_size = seq_hdr->len;
425 rav1e_data_unref(seq_hdr);
428 ret = 0;
430 end:
432 rav1e_config_unref(cfg);
434 return ret;
437 static void frame_data_free(void *data)
439 FrameData *fd = data;
441 if (!fd)
442 return;
444 av_buffer_unref(&fd->frame_opaque_ref);
445 av_free(data);
448 static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
450 librav1eContext *ctx = avctx->priv_data;
451 RaFrame *rframe = ctx->rframe;
452 RaPacket *rpkt = NULL;
453 FrameData *fd;
454 int ret;
456 if (!rframe) {
457 AVFrame *frame = ctx->frame;
459 ret = ff_encode_get_frame(avctx, frame);
460 if (ret < 0 && ret != AVERROR_EOF)
461 return ret;
463 if (frame->buf[0]) {
464 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
466 fd = av_mallocz(sizeof(*fd));
467 if (!fd) {
468 av_log(avctx, AV_LOG_ERROR, "Could not allocate PTS buffer.\n");
469 return AVERROR(ENOMEM);
471 fd->pts = frame->pts;
472 fd->duration = frame->duration;
474 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
475 fd->frame_opaque = frame->opaque;
476 fd->frame_opaque_ref = frame->opaque_ref;
477 frame->opaque_ref = NULL;
480 rframe = rav1e_frame_new(ctx->ctx);
481 if (!rframe) {
482 av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n");
483 av_frame_unref(frame);
484 frame_data_free(fd);
485 return AVERROR(ENOMEM);
488 for (int i = 0; i < desc->nb_components; i++) {
489 int shift = i ? desc->log2_chroma_h : 0;
490 int bytes = desc->comp[0].depth == 8 ? 1 : 2;
491 rav1e_frame_fill_plane(rframe, i, frame->data[i],
492 (frame->height >> shift) * frame->linesize[i],
493 frame->linesize[i], bytes);
495 av_frame_unref(frame);
496 rav1e_frame_set_opaque(rframe, fd, frame_data_free);
500 ret = rav1e_send_frame(ctx->ctx, rframe);
501 if (rframe)
502 if (ret == RA_ENCODER_STATUS_ENOUGH_DATA) {
503 ctx->rframe = rframe; /* Queue is full. Store the RaFrame to retry next call */
504 } else {
505 rav1e_frame_unref(rframe); /* No need to unref if flushing. */
506 ctx->rframe = NULL;
509 switch (ret) {
510 case RA_ENCODER_STATUS_SUCCESS:
511 case RA_ENCODER_STATUS_ENOUGH_DATA:
512 break;
513 case RA_ENCODER_STATUS_FAILURE:
514 av_log(avctx, AV_LOG_ERROR, "Could not send frame: %s\n", rav1e_status_to_str(ret));
515 return AVERROR_EXTERNAL;
516 default:
517 av_log(avctx, AV_LOG_ERROR, "Unknown return code %d from rav1e_send_frame: %s\n", ret, rav1e_status_to_str(ret));
518 return AVERROR_UNKNOWN;
521 retry:
523 if (avctx->flags & AV_CODEC_FLAG_PASS1) {
524 int sret = get_stats(avctx, 0);
525 if (sret < 0)
526 return sret;
527 } else if (avctx->flags & AV_CODEC_FLAG_PASS2) {
528 int sret = set_stats(avctx);
529 if (sret < 0)
530 return sret;
533 ret = rav1e_receive_packet(ctx->ctx, &rpkt);
534 switch (ret) {
535 case RA_ENCODER_STATUS_SUCCESS:
536 break;
537 case RA_ENCODER_STATUS_LIMIT_REACHED:
538 if (avctx->flags & AV_CODEC_FLAG_PASS1) {
539 int sret = get_stats(avctx, 1);
540 if (sret < 0)
541 return sret;
543 return AVERROR_EOF;
544 case RA_ENCODER_STATUS_ENCODED:
545 goto retry;
546 case RA_ENCODER_STATUS_NEED_MORE_DATA:
547 if (avctx->internal->draining) {
548 av_log(avctx, AV_LOG_ERROR, "Unexpected error when receiving packet after EOF.\n");
549 return AVERROR_EXTERNAL;
551 return AVERROR(EAGAIN);
552 case RA_ENCODER_STATUS_FAILURE:
553 av_log(avctx, AV_LOG_ERROR, "Could not encode frame: %s\n", rav1e_status_to_str(ret));
554 return AVERROR_EXTERNAL;
555 default:
556 av_log(avctx, AV_LOG_ERROR, "Unknown return code %d from rav1e_receive_packet: %s\n", ret, rav1e_status_to_str(ret));
557 return AVERROR_UNKNOWN;
560 ret = ff_get_encode_buffer(avctx, pkt, rpkt->len, 0);
561 if (ret < 0) {
562 av_log(avctx, AV_LOG_ERROR, "Could not allocate packet.\n");
563 rav1e_packet_unref(rpkt);
564 return ret;
567 memcpy(pkt->data, rpkt->data, rpkt->len);
569 if (rpkt->frame_type == RA_FRAME_TYPE_KEY)
570 pkt->flags |= AV_PKT_FLAG_KEY;
572 fd = rpkt->opaque;
573 pkt->pts = pkt->dts = fd->pts;
574 pkt->duration = fd->duration;
576 if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) {
577 pkt->opaque = fd->frame_opaque;
578 pkt->opaque_ref = fd->frame_opaque_ref;
579 fd->frame_opaque_ref = NULL;
582 frame_data_free(fd);
584 if (avctx->flags & AV_CODEC_FLAG_RECON_FRAME) {
585 AVCodecInternal *avci = avctx->internal;
586 AVFrame *frame = avci->recon_frame;
587 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
589 av_frame_unref(frame);
591 frame->format = avctx->pix_fmt;
592 frame->width = avctx->width;
593 frame->height = avctx->height;
595 ret = ff_encode_alloc_frame(avctx, frame);
596 if (ret < 0) {
597 rav1e_packet_unref(rpkt);
598 return ret;
601 for (int i = 0; i < desc->nb_components; i++) {
602 int shift = i ? desc->log2_chroma_h : 0;
603 rav1e_frame_extract_plane(rpkt->rec, i, frame->data[i],
604 (frame->height >> shift) * frame->linesize[i],
605 frame->linesize[i], desc->comp[i].step);
609 rav1e_packet_unref(rpkt);
611 return 0;
614 #define OFFSET(x) offsetof(librav1eContext, x)
615 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
617 static const AVOption options[] = {
618 { "qp", "use constant quantizer mode", OFFSET(quantizer), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, VE },
619 { "speed", "what speed preset to use", OFFSET(speed), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 10, VE },
620 { "tiles", "number of tiles encode with", OFFSET(tiles), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT64_MAX, VE },
621 { "tile-rows", "number of tiles rows to encode with", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT64_MAX, VE },
622 { "tile-columns", "number of tiles columns to encode with", OFFSET(tile_cols), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT64_MAX, VE },
623 { "rav1e-params", "set the rav1e configuration using a :-separated list of key=value parameters", OFFSET(rav1e_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE },
624 { NULL }
627 static const FFCodecDefault librav1e_defaults[] = {
628 { "b", "0" },
629 { "g", "0" },
630 { "keyint_min", "0" },
631 { "qmax", "-1" },
632 { "qmin", "-1" },
633 { NULL }
636 const enum AVPixelFormat librav1e_pix_fmts[] = {
637 AV_PIX_FMT_YUV420P,
638 AV_PIX_FMT_YUVJ420P,
639 AV_PIX_FMT_YUV420P10,
640 AV_PIX_FMT_YUV420P12,
641 AV_PIX_FMT_YUV422P,
642 AV_PIX_FMT_YUVJ422P,
643 AV_PIX_FMT_YUV422P10,
644 AV_PIX_FMT_YUV422P12,
645 AV_PIX_FMT_YUV444P,
646 AV_PIX_FMT_YUVJ444P,
647 AV_PIX_FMT_YUV444P10,
648 AV_PIX_FMT_YUV444P12,
649 AV_PIX_FMT_NONE
652 static const AVClass class = {
653 .class_name = "librav1e",
654 .item_name = av_default_item_name,
655 .option = options,
656 .version = LIBAVUTIL_VERSION_INT,
659 const FFCodec ff_librav1e_encoder = {
660 .p.name = "librav1e",
661 CODEC_LONG_NAME("librav1e AV1"),
662 .p.type = AVMEDIA_TYPE_VIDEO,
663 .p.id = AV_CODEC_ID_AV1,
664 .init = librav1e_encode_init,
665 FF_CODEC_RECEIVE_PACKET_CB(librav1e_receive_packet),
666 .close = librav1e_encode_close,
667 .priv_data_size = sizeof(librav1eContext),
668 .p.priv_class = &class,
669 .defaults = librav1e_defaults,
670 .p.pix_fmts = librav1e_pix_fmts,
671 .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
672 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS |
673 AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_RECON_FRAME |
674 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
675 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
676 FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_AUTO_THREADS,
677 .p.wrapper_name = "librav1e",