2 * Copyright (c) 2010, Google, Inc.
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * AV1 encoder support via libaom
26 #define AOM_DISABLE_CTRL_TYPECHECKS 1
27 #include <aom/aom_encoder.h>
28 #include <aom/aomcx.h>
30 #include "libavutil/avassert.h"
31 #include "libavutil/base64.h"
32 #include "libavutil/common.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/pixdesc.h"
43 * Portion of struct aom_codec_cx_pkt from aom_encoder.h.
44 * One encoded frame returned from the library.
46 struct FrameListData {
47 void *buf; /**< compressed data buffer */
48 size_t sz; /**< length of compressed data */
49 int64_t pts; /**< time stamp to show frame
50 (in timebase units) */
51 unsigned long duration; /**< duration to show frame
52 (in timebase units) */
53 uint32_t flags; /**< flags for this frame */
55 int have_sse; /**< true if we have pending sse[] */
56 uint64_t frame_number;
57 struct FrameListData *next;
60 typedef struct AOMEncoderContext {
63 struct aom_codec_ctx encoder;
64 struct aom_image rawimg;
65 struct aom_fixed_buf twopass_stats;
66 struct FrameListData *coded_frame_list;
77 int denoise_noise_level;
78 int denoise_block_size;
80 int have_sse; /**< true if we have pending sse[] */
81 uint64_t frame_number;
82 int rc_undershoot_pct;
87 int tile_cols, tile_rows;
88 int tile_cols_log2, tile_rows_log2;
89 aom_superblock_size_t superblock_size;
93 int enable_global_motion;
95 int enable_restoration;
98 static const char *const ctlidstr[] = {
99 [AOME_SET_CPUUSED] = "AOME_SET_CPUUSED",
100 [AOME_SET_CQ_LEVEL] = "AOME_SET_CQ_LEVEL",
101 [AOME_SET_ENABLEAUTOALTREF] = "AOME_SET_ENABLEAUTOALTREF",
102 [AOME_SET_ARNR_MAXFRAMES] = "AOME_SET_ARNR_MAXFRAMES",
103 [AOME_SET_ARNR_STRENGTH] = "AOME_SET_ARNR_STRENGTH",
104 [AOME_SET_STATIC_THRESHOLD] = "AOME_SET_STATIC_THRESHOLD",
105 [AV1E_SET_COLOR_RANGE] = "AV1E_SET_COLOR_RANGE",
106 [AV1E_SET_COLOR_PRIMARIES] = "AV1E_SET_COLOR_PRIMARIES",
107 [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
108 [AV1E_SET_TRANSFER_CHARACTERISTICS] = "AV1E_SET_TRANSFER_CHARACTERISTICS",
109 [AV1E_SET_AQ_MODE] = "AV1E_SET_AQ_MODE",
110 [AV1E_SET_FRAME_PARALLEL_DECODING] = "AV1E_SET_FRAME_PARALLEL_DECODING",
111 [AV1E_SET_SUPERBLOCK_SIZE] = "AV1E_SET_SUPERBLOCK_SIZE",
112 [AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS",
113 [AV1E_SET_TILE_ROWS] = "AV1E_SET_TILE_ROWS",
114 [AV1E_SET_ENABLE_RESTORATION] = "AV1E_SET_ENABLE_RESTORATION",
115 #ifdef AOM_CTRL_AV1E_SET_ROW_MT
116 [AV1E_SET_ROW_MT] = "AV1E_SET_ROW_MT",
118 #ifdef AOM_CTRL_AV1E_SET_DENOISE_NOISE_LEVEL
119 [AV1E_SET_DENOISE_NOISE_LEVEL] = "AV1E_SET_DENOISE_NOISE_LEVEL",
121 #ifdef AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE
122 [AV1E_SET_DENOISE_BLOCK_SIZE] = "AV1E_SET_DENOISE_BLOCK_SIZE",
124 #ifdef AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES
125 [AV1E_SET_MAX_REFERENCE_FRAMES] = "AV1E_SET_MAX_REFERENCE_FRAMES",
127 #ifdef AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION
128 [AV1E_SET_ENABLE_GLOBAL_MOTION] = "AV1E_SET_ENABLE_GLOBAL_MOTION",
130 #ifdef AOM_CTRL_AV1E_SET_ENABLE_INTRABC
131 [AV1E_SET_ENABLE_INTRABC] = "AV1E_SET_ENABLE_INTRABC",
133 [AV1E_SET_ENABLE_CDEF] = "AV1E_SET_ENABLE_CDEF",
136 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
138 AOMContext *ctx = avctx->priv_data;
139 const char *error = aom_codec_error(&ctx->encoder);
140 const char *detail = aom_codec_error_detail(&ctx->encoder);
142 av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error);
144 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail);
147 static av_cold void dump_enc_cfg(AVCodecContext *avctx,
148 const struct aom_codec_enc_cfg *cfg)
151 int level = AV_LOG_DEBUG;
153 av_log(avctx, level, "aom_codec_enc_cfg\n");
154 av_log(avctx, level, "generic settings\n"
155 " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n"
157 " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n",
158 width, "g_usage:", cfg->g_usage,
159 width, "g_threads:", cfg->g_threads,
160 width, "g_profile:", cfg->g_profile,
161 width, "g_w:", cfg->g_w,
162 width, "g_h:", cfg->g_h,
163 width, "g_bit_depth:", cfg->g_bit_depth,
164 width, "g_input_bit_depth:", cfg->g_input_bit_depth,
165 width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den,
166 width, "g_error_resilient:", cfg->g_error_resilient,
167 width, "g_pass:", cfg->g_pass,
168 width, "g_lag_in_frames:", cfg->g_lag_in_frames);
169 av_log(avctx, level, "rate control settings\n"
170 " %*s%u\n %*s%d\n %*s%p(%"SIZE_SPECIFIER")\n %*s%u\n",
171 width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh,
172 width, "rc_end_usage:", cfg->rc_end_usage,
173 width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz,
174 width, "rc_target_bitrate:", cfg->rc_target_bitrate);
175 av_log(avctx, level, "quantizer settings\n"
177 width, "rc_min_quantizer:", cfg->rc_min_quantizer,
178 width, "rc_max_quantizer:", cfg->rc_max_quantizer);
179 av_log(avctx, level, "bitrate tolerance\n"
181 width, "rc_undershoot_pct:", cfg->rc_undershoot_pct,
182 width, "rc_overshoot_pct:", cfg->rc_overshoot_pct);
183 av_log(avctx, level, "decoder buffer model\n"
184 " %*s%u\n %*s%u\n %*s%u\n",
185 width, "rc_buf_sz:", cfg->rc_buf_sz,
186 width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz,
187 width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz);
188 av_log(avctx, level, "2 pass rate control settings\n"
189 " %*s%u\n %*s%u\n %*s%u\n",
190 width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct,
191 width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct,
192 width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct);
193 av_log(avctx, level, "keyframing settings\n"
194 " %*s%d\n %*s%u\n %*s%u\n",
195 width, "kf_mode:", cfg->kf_mode,
196 width, "kf_min_dist:", cfg->kf_min_dist,
197 width, "kf_max_dist:", cfg->kf_max_dist);
198 av_log(avctx, level, "tile settings\n"
200 width, "tile_width_count:", cfg->tile_width_count,
201 width, "tile_height_count:", cfg->tile_height_count);
202 av_log(avctx, level, "\n");
205 static void coded_frame_add(void *list, struct FrameListData *cx_frame)
207 struct FrameListData **p = list;
212 cx_frame->next = NULL;
215 static av_cold void free_coded_frame(struct FrameListData *cx_frame)
217 av_freep(&cx_frame->buf);
221 static av_cold void free_frame_list(struct FrameListData *list)
223 struct FrameListData *p = list;
232 static av_cold int codecctl_int(AVCodecContext *avctx,
234 aome_enc_control_id id,
236 enum aome_enc_control_id id,
240 AOMContext *ctx = avctx->priv_data;
245 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]);
246 av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val);
248 res = aom_codec_control(&ctx->encoder, id, val);
249 if (res != AOM_CODEC_OK) {
250 snprintf(buf, sizeof(buf), "Failed to set %s codec control",
252 log_encoder_error(avctx, buf);
253 return AVERROR(EINVAL);
259 static av_cold int aom_free(AVCodecContext *avctx)
261 AOMContext *ctx = avctx->priv_data;
263 aom_codec_destroy(&ctx->encoder);
264 av_freep(&ctx->twopass_stats.buf);
265 av_freep(&avctx->stats_out);
266 free_frame_list(ctx->coded_frame_list);
267 av_bsf_free(&ctx->bsf);
271 static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps,
272 struct aom_codec_enc_cfg *enccfg, aom_codec_flags_t *flags,
273 aom_img_fmt_t *img_fmt)
275 AOMContext av_unused *ctx = avctx->priv_data;
276 enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8;
277 switch (avctx->pix_fmt) {
278 case AV_PIX_FMT_YUV420P:
279 enccfg->g_profile = FF_PROFILE_AV1_MAIN;
280 *img_fmt = AOM_IMG_FMT_I420;
282 case AV_PIX_FMT_YUV422P:
283 enccfg->g_profile = FF_PROFILE_AV1_PROFESSIONAL;
284 *img_fmt = AOM_IMG_FMT_I422;
286 case AV_PIX_FMT_YUV444P:
287 enccfg->g_profile = FF_PROFILE_AV1_HIGH;
288 *img_fmt = AOM_IMG_FMT_I444;
290 case AV_PIX_FMT_YUV420P10:
291 case AV_PIX_FMT_YUV420P12:
292 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
293 enccfg->g_bit_depth = enccfg->g_input_bit_depth =
294 avctx->pix_fmt == AV_PIX_FMT_YUV420P10 ? 10 : 12;
296 enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_MAIN : FF_PROFILE_AV1_PROFESSIONAL;
297 *img_fmt = AOM_IMG_FMT_I42016;
298 *flags |= AOM_CODEC_USE_HIGHBITDEPTH;
302 case AV_PIX_FMT_YUV422P10:
303 case AV_PIX_FMT_YUV422P12:
304 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
305 enccfg->g_bit_depth = enccfg->g_input_bit_depth =
306 avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12;
307 enccfg->g_profile = FF_PROFILE_AV1_PROFESSIONAL;
308 *img_fmt = AOM_IMG_FMT_I42216;
309 *flags |= AOM_CODEC_USE_HIGHBITDEPTH;
313 case AV_PIX_FMT_YUV444P10:
314 case AV_PIX_FMT_YUV444P12:
315 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) {
316 enccfg->g_bit_depth = enccfg->g_input_bit_depth =
317 avctx->pix_fmt == AV_PIX_FMT_YUV444P10 ? 10 : 12;
319 enccfg->g_bit_depth == 10 ? FF_PROFILE_AV1_HIGH : FF_PROFILE_AV1_PROFESSIONAL;
320 *img_fmt = AOM_IMG_FMT_I44416;
321 *flags |= AOM_CODEC_USE_HIGHBITDEPTH;
328 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n");
329 return AVERROR_INVALIDDATA;
332 static void set_color_range(AVCodecContext *avctx)
334 aom_color_range_t aom_cr;
335 switch (avctx->color_range) {
336 case AVCOL_RANGE_UNSPECIFIED:
337 case AVCOL_RANGE_MPEG: aom_cr = AOM_CR_STUDIO_RANGE; break;
338 case AVCOL_RANGE_JPEG: aom_cr = AOM_CR_FULL_RANGE; break;
340 av_log(avctx, AV_LOG_WARNING, "Unsupported color range (%d)\n",
345 codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr);
348 static int count_uniform_tiling(int dim, int sb_size, int tiles_log2)
350 int sb_dim = (dim + sb_size - 1) / sb_size;
351 int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
352 av_assert0(tile_dim > 0);
353 return (sb_dim + tile_dim - 1) / tile_dim;
356 static int choose_tiling(AVCodecContext *avctx,
357 struct aom_codec_enc_cfg *enccfg)
359 AOMContext *ctx = avctx->priv_data;
360 int sb_128x128_possible, sb_size, sb_width, sb_height;
361 int uniform_rows, uniform_cols;
362 int uniform_64x64_possible, uniform_128x128_possible;
363 int tile_size, rounding, i;
365 if (ctx->tile_cols_log2 >= 0)
366 ctx->tile_cols = 1 << ctx->tile_cols_log2;
367 if (ctx->tile_rows_log2 >= 0)
368 ctx->tile_rows = 1 << ctx->tile_rows_log2;
370 if (ctx->tile_cols == 0) {
371 ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) /
373 if (ctx->tile_cols > 1) {
374 av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
375 "columns to fill width.\n", ctx->tile_cols);
378 av_assert0(ctx->tile_cols > 0);
379 if (ctx->tile_rows == 0) {
381 FFALIGN((FFALIGN(avctx->width, 128) +
382 ctx->tile_cols - 1) / ctx->tile_cols, 128);
384 (max_tile_width * FFALIGN(avctx->height, 128) +
385 AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA;
386 if (ctx->tile_rows > 1) {
387 av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
388 "rows to fill area.\n", ctx->tile_rows);
391 av_assert0(ctx->tile_rows > 0);
393 if ((avctx->width + 63) / 64 < ctx->tile_cols ||
394 (avctx->height + 63) / 64 < ctx->tile_rows) {
395 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not "
396 "large enough to fit specified tile arrangement.\n");
397 return AVERROR(EINVAL);
399 if (ctx->tile_cols > AV1_MAX_TILE_COLS ||
400 ctx->tile_rows > AV1_MAX_TILE_ROWS) {
401 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
402 "not allow more than %dx%d tiles.\n",
403 AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS);
404 return AVERROR(EINVAL);
406 if (avctx->width / ctx->tile_cols > AV1_MAX_TILE_WIDTH) {
407 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
408 "not allow tiles of width greater than %d.\n",
410 return AVERROR(EINVAL);
413 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC;
415 if (ctx->tile_cols == 1 && ctx->tile_rows == 1) {
416 av_log(avctx, AV_LOG_DEBUG, "Using a single tile.\n");
420 sb_128x128_possible =
421 (avctx->width + 127) / 128 >= ctx->tile_cols &&
422 (avctx->height + 127) / 128 >= ctx->tile_rows;
424 ctx->tile_cols_log2 = ctx->tile_cols == 1 ? 0 :
425 av_log2(ctx->tile_cols - 1) + 1;
426 ctx->tile_rows_log2 = ctx->tile_rows == 1 ? 0 :
427 av_log2(ctx->tile_rows - 1) + 1;
429 uniform_cols = count_uniform_tiling(avctx->width,
430 64, ctx->tile_cols_log2);
431 uniform_rows = count_uniform_tiling(avctx->height,
432 64, ctx->tile_rows_log2);
433 av_log(avctx, AV_LOG_DEBUG, "Uniform with 64x64 superblocks "
434 "-> %dx%d tiles.\n", uniform_cols, uniform_rows);
435 uniform_64x64_possible = uniform_cols == ctx->tile_cols &&
436 uniform_rows == ctx->tile_rows;
438 if (sb_128x128_possible) {
439 uniform_cols = count_uniform_tiling(avctx->width,
440 128, ctx->tile_cols_log2);
441 uniform_rows = count_uniform_tiling(avctx->height,
442 128, ctx->tile_rows_log2);
443 av_log(avctx, AV_LOG_DEBUG, "Uniform with 128x128 superblocks "
444 "-> %dx%d tiles.\n", uniform_cols, uniform_rows);
445 uniform_128x128_possible = uniform_cols == ctx->tile_cols &&
446 uniform_rows == ctx->tile_rows;
448 av_log(avctx, AV_LOG_DEBUG, "128x128 superblocks not possible.\n");
449 uniform_128x128_possible = 0;
452 ctx->uniform_tiles = 1;
453 if (uniform_64x64_possible && uniform_128x128_possible) {
454 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with dynamic "
455 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
456 ctx->tile_cols_log2, ctx->tile_rows_log2);
459 if (uniform_64x64_possible && !sb_128x128_possible) {
460 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with 64x64 "
461 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
462 ctx->tile_cols_log2, ctx->tile_rows_log2);
463 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
466 if (uniform_128x128_possible) {
467 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with 128x128 "
468 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n",
469 ctx->tile_cols_log2, ctx->tile_rows_log2);
470 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128;
473 ctx->uniform_tiles = 0;
475 if (sb_128x128_possible) {
477 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128;
480 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
482 av_log(avctx, AV_LOG_DEBUG, "Using fixed tiling with %dx%d "
483 "superblocks (tile_cols = %d, tile_rows = %d).\n",
484 sb_size, sb_size, ctx->tile_cols, ctx->tile_rows);
486 enccfg->tile_width_count = ctx->tile_cols;
487 enccfg->tile_height_count = ctx->tile_rows;
489 sb_width = (avctx->width + sb_size - 1) / sb_size;
490 sb_height = (avctx->height + sb_size - 1) / sb_size;
492 tile_size = sb_width / ctx->tile_cols;
493 rounding = sb_width % ctx->tile_cols;
494 for (i = 0; i < ctx->tile_cols; i++) {
495 enccfg->tile_widths[i] = tile_size +
497 i > ctx->tile_cols - 1 - (rounding + 1) / 2);
500 tile_size = sb_height / ctx->tile_rows;
501 rounding = sb_height % ctx->tile_rows;
502 for (i = 0; i < ctx->tile_rows; i++) {
503 enccfg->tile_heights[i] = tile_size +
505 i > ctx->tile_rows - 1 - (rounding + 1) / 2);
511 static av_cold int aom_init(AVCodecContext *avctx,
512 const struct aom_codec_iface *iface)
514 AOMContext *ctx = avctx->priv_data;
515 struct aom_codec_enc_cfg enccfg = { 0 };
516 #ifdef AOM_FRAME_IS_INTRAONLY
517 aom_codec_flags_t flags =
518 (avctx->flags & AV_CODEC_FLAG_PSNR) ? AOM_CODEC_USE_PSNR : 0;
520 aom_codec_flags_t flags = 0;
522 AVCPBProperties *cpb_props;
524 aom_img_fmt_t img_fmt;
525 aom_codec_caps_t codec_caps = aom_codec_get_caps(iface);
527 av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str());
528 av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config());
530 if ((res = aom_codec_enc_config_default(iface, &enccfg, 0)) != AOM_CODEC_OK) {
531 av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
532 aom_codec_err_to_string(res));
533 return AVERROR(EINVAL);
536 if (set_pix_fmt(avctx, codec_caps, &enccfg, &flags, &img_fmt))
537 return AVERROR(EINVAL);
540 if(avctx->rc_max_rate || avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
541 av_log( avctx, AV_LOG_ERROR, "Rate control parameters set without a bitrate\n");
542 return AVERROR(EINVAL);
545 dump_enc_cfg(avctx, &enccfg);
547 enccfg.g_w = avctx->width;
548 enccfg.g_h = avctx->height;
549 enccfg.g_timebase.num = avctx->time_base.num;
550 enccfg.g_timebase.den = avctx->time_base.den;
552 FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 64);
554 if (ctx->lag_in_frames >= 0)
555 enccfg.g_lag_in_frames = ctx->lag_in_frames;
557 if (avctx->flags & AV_CODEC_FLAG_PASS1)
558 enccfg.g_pass = AOM_RC_FIRST_PASS;
559 else if (avctx->flags & AV_CODEC_FLAG_PASS2)
560 enccfg.g_pass = AOM_RC_LAST_PASS;
562 enccfg.g_pass = AOM_RC_ONE_PASS;
564 if (avctx->rc_min_rate == avctx->rc_max_rate &&
565 avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate) {
566 enccfg.rc_end_usage = AOM_CBR;
567 } else if (ctx->crf >= 0) {
568 enccfg.rc_end_usage = AOM_CQ;
569 if (!avctx->bit_rate)
570 enccfg.rc_end_usage = AOM_Q;
573 if (avctx->bit_rate) {
574 enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
576 } else if (enccfg.rc_end_usage != AOM_Q) {
577 enccfg.rc_end_usage = AOM_Q;
579 av_log(avctx, AV_LOG_WARNING,
580 "Neither bitrate nor constrained quality specified, using default CRF of %d\n",
584 if (avctx->qmin >= 0)
585 enccfg.rc_min_quantizer = avctx->qmin;
586 if (avctx->qmax >= 0)
587 enccfg.rc_max_quantizer = avctx->qmax;
589 if (enccfg.rc_end_usage == AOM_CQ || enccfg.rc_end_usage == AOM_Q) {
590 if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) {
591 av_log(avctx, AV_LOG_ERROR,
592 "CQ level %d must be between minimum and maximum quantizer value (%d-%d)\n",
593 ctx->crf, enccfg.rc_min_quantizer, enccfg.rc_max_quantizer);
594 return AVERROR(EINVAL);
598 enccfg.rc_dropframe_thresh = ctx->drop_threshold;
600 // 0-100 (0 => CBR, 100 => VBR)
601 enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100);
602 if (ctx->minsection_pct >= 0)
603 enccfg.rc_2pass_vbr_minsection_pct = ctx->minsection_pct;
604 else if (avctx->bit_rate)
605 enccfg.rc_2pass_vbr_minsection_pct =
606 avctx->rc_min_rate * 100LL / avctx->bit_rate;
607 if (ctx->maxsection_pct >= 0)
608 enccfg.rc_2pass_vbr_maxsection_pct = ctx->maxsection_pct;
609 else if (avctx->rc_max_rate)
610 enccfg.rc_2pass_vbr_maxsection_pct =
611 avctx->rc_max_rate * 100LL / avctx->bit_rate;
613 if (avctx->rc_buffer_size)
615 avctx->rc_buffer_size * 1000LL / avctx->bit_rate;
616 if (avctx->rc_initial_buffer_occupancy)
617 enccfg.rc_buf_initial_sz =
618 avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate;
619 enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6;
621 if (ctx->rc_undershoot_pct >= 0)
622 enccfg.rc_undershoot_pct = ctx->rc_undershoot_pct;
623 if (ctx->rc_overshoot_pct >= 0)
624 enccfg.rc_overshoot_pct = ctx->rc_overshoot_pct;
626 // _enc_init() will balk if kf_min_dist differs from max w/AOM_KF_AUTO
627 if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
628 enccfg.kf_min_dist = avctx->keyint_min;
629 if (avctx->gop_size >= 0)
630 enccfg.kf_max_dist = avctx->gop_size;
632 if (enccfg.g_pass == AOM_RC_FIRST_PASS)
633 enccfg.g_lag_in_frames = 0;
634 else if (enccfg.g_pass == AOM_RC_LAST_PASS) {
635 int decode_size, ret;
637 if (!avctx->stats_in) {
638 av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
639 return AVERROR_INVALIDDATA;
642 ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4;
643 ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz);
645 av_log(avctx, AV_LOG_ERROR,
646 "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n",
647 ctx->twopass_stats.sz);
648 ctx->twopass_stats.sz = 0;
651 decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
652 ctx->twopass_stats.sz);
653 if (decode_size < 0) {
654 av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n");
655 return AVERROR_INVALIDDATA;
658 ctx->twopass_stats.sz = decode_size;
659 enccfg.rc_twopass_stats_in = ctx->twopass_stats;
662 /* 0-3: For non-zero values the encoder increasingly optimizes for reduced
663 * complexity playback on low powered devices at the expense of encode
665 if (avctx->profile != FF_PROFILE_UNKNOWN)
666 enccfg.g_profile = avctx->profile;
668 enccfg.g_error_resilient = ctx->error_resilient;
670 res = choose_tiling(avctx, &enccfg);
674 dump_enc_cfg(avctx, &enccfg);
675 /* Construct Encoder Context */
676 res = aom_codec_enc_init(&ctx->encoder, iface, &enccfg, flags);
677 if (res != AOM_CODEC_OK) {
678 log_encoder_error(avctx, "Failed to initialize encoder");
679 return AVERROR(EINVAL);
682 // codec control failures are currently treated only as warnings
683 av_log(avctx, AV_LOG_DEBUG, "aom_codec_control\n");
684 codecctl_int(avctx, AOME_SET_CPUUSED, ctx->cpu_used);
685 if (ctx->auto_alt_ref >= 0)
686 codecctl_int(avctx, AOME_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
687 if (ctx->arnr_max_frames >= 0)
688 codecctl_int(avctx, AOME_SET_ARNR_MAXFRAMES, ctx->arnr_max_frames);
689 if (ctx->arnr_strength >= 0)
690 codecctl_int(avctx, AOME_SET_ARNR_STRENGTH, ctx->arnr_strength);
691 if (ctx->enable_cdef >= 0)
692 codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef);
693 if (ctx->enable_restoration >= 0)
694 codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration);
696 codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh);
698 codecctl_int(avctx, AOME_SET_CQ_LEVEL, ctx->crf);
700 codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries);
701 codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace);
702 codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc);
703 if (ctx->aq_mode >= 0)
704 codecctl_int(avctx, AV1E_SET_AQ_MODE, ctx->aq_mode);
705 if (ctx->frame_parallel >= 0)
706 codecctl_int(avctx, AV1E_SET_FRAME_PARALLEL_DECODING, ctx->frame_parallel);
707 set_color_range(avctx);
709 codecctl_int(avctx, AV1E_SET_SUPERBLOCK_SIZE, ctx->superblock_size);
710 if (ctx->uniform_tiles) {
711 codecctl_int(avctx, AV1E_SET_TILE_COLUMNS, ctx->tile_cols_log2);
712 codecctl_int(avctx, AV1E_SET_TILE_ROWS, ctx->tile_rows_log2);
715 #ifdef AOM_CTRL_AV1E_SET_DENOISE_NOISE_LEVEL
716 if (ctx->denoise_noise_level >= 0)
717 codecctl_int(avctx, AV1E_SET_DENOISE_NOISE_LEVEL, ctx->denoise_noise_level);
719 #ifdef AOM_CTRL_AV1E_SET_DENOISE_BLOCK_SIZE
720 if (ctx->denoise_block_size >= 0)
721 codecctl_int(avctx, AV1E_SET_DENOISE_BLOCK_SIZE, ctx->denoise_block_size);
723 #ifdef AOM_CTRL_AV1E_SET_ENABLE_GLOBAL_MOTION
724 if (ctx->enable_global_motion >= 0)
725 codecctl_int(avctx, AV1E_SET_ENABLE_GLOBAL_MOTION, ctx->enable_global_motion);
727 #ifdef AOM_CTRL_AV1E_SET_MAX_REFERENCE_FRAMES
728 if (avctx->refs >= 3) {
729 codecctl_int(avctx, AV1E_SET_MAX_REFERENCE_FRAMES, avctx->refs);
732 #ifdef AOM_CTRL_AV1E_SET_ROW_MT
733 if (ctx->row_mt >= 0)
734 codecctl_int(avctx, AV1E_SET_ROW_MT, ctx->row_mt);
736 #ifdef AOM_CTRL_AV1E_SET_ENABLE_INTRABC
737 if (ctx->enable_intrabc >= 0)
738 codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc);
741 // provide dummy value to initialize wrapper, values will be updated each _encode()
742 aom_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1,
745 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
746 ctx->rawimg.bit_depth = enccfg.g_bit_depth;
748 cpb_props = ff_add_cpb_side_data(avctx);
750 return AVERROR(ENOMEM);
752 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
753 const AVBitStreamFilter *filter = av_bsf_get_by_name("extract_extradata");
757 av_log(avctx, AV_LOG_ERROR, "extract_extradata bitstream filter "
758 "not found. This is a bug, please report it.\n");
761 ret = av_bsf_alloc(filter, &ctx->bsf);
765 ret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx);
769 ret = av_bsf_init(ctx->bsf);
774 if (enccfg.rc_end_usage == AOM_CBR ||
775 enccfg.g_pass != AOM_RC_ONE_PASS) {
776 cpb_props->max_bitrate = avctx->rc_max_rate;
777 cpb_props->min_bitrate = avctx->rc_min_rate;
778 cpb_props->avg_bitrate = avctx->bit_rate;
780 cpb_props->buffer_size = avctx->rc_buffer_size;
785 static inline void cx_pktcpy(AOMContext *ctx,
786 struct FrameListData *dst,
787 const struct aom_codec_cx_pkt *src)
789 dst->pts = src->data.frame.pts;
790 dst->duration = src->data.frame.duration;
791 dst->flags = src->data.frame.flags;
792 dst->sz = src->data.frame.sz;
793 dst->buf = src->data.frame.buf;
794 #ifdef AOM_FRAME_IS_INTRAONLY
796 dst->frame_number = ++ctx->frame_number;
797 dst->have_sse = ctx->have_sse;
799 /* associate last-seen SSE to the frame. */
800 /* Transfers ownership from ctx to dst. */
801 memcpy(dst->sse, ctx->sse, sizeof(dst->sse));
808 * Store coded frame information in format suitable for return from encode2().
810 * Write information from @a cx_frame to @a pkt
811 * @return packet data size on success
812 * @return a negative AVERROR on error
814 static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
817 AOMContext *ctx = avctx->priv_data;
818 int av_unused pict_type;
819 int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz, 0);
821 av_log(avctx, AV_LOG_ERROR,
822 "Error getting output packet of size %"SIZE_SPECIFIER".\n", cx_frame->sz);
825 memcpy(pkt->data, cx_frame->buf, pkt->size);
826 pkt->pts = pkt->dts = cx_frame->pts;
828 if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) {
829 pkt->flags |= AV_PKT_FLAG_KEY;
830 #ifdef AOM_FRAME_IS_INTRAONLY
831 pict_type = AV_PICTURE_TYPE_I;
832 } else if (cx_frame->flags & AOM_FRAME_IS_INTRAONLY) {
833 pict_type = AV_PICTURE_TYPE_I;
835 pict_type = AV_PICTURE_TYPE_P;
838 ff_side_data_set_encoder_stats(pkt, 0, cx_frame->sse + 1,
839 cx_frame->have_sse ? 3 : 0, pict_type);
841 if (cx_frame->have_sse) {
843 for (i = 0; i < 3; ++i) {
844 avctx->error[i] += cx_frame->sse[i + 1];
846 cx_frame->have_sse = 0;
850 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
851 ret = av_bsf_send_packet(ctx->bsf, pkt);
853 av_log(avctx, AV_LOG_ERROR, "extract_extradata filter "
854 "failed to send input packet\n");
857 ret = av_bsf_receive_packet(ctx->bsf, pkt);
860 av_log(avctx, AV_LOG_ERROR, "extract_extradata filter "
861 "failed to receive output packet\n");
869 * Queue multiple output frames from the encoder, returning the front-most.
870 * In cases where aom_codec_get_cx_data() returns more than 1 frame append
871 * the frame queue. Return the head frame if available.
872 * @return Stored frame size
873 * @return AVERROR(EINVAL) on output size error
874 * @return AVERROR(ENOMEM) on coded frame queue data allocation error
876 static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out)
878 AOMContext *ctx = avctx->priv_data;
879 const struct aom_codec_cx_pkt *pkt;
880 const void *iter = NULL;
883 if (ctx->coded_frame_list) {
884 struct FrameListData *cx_frame = ctx->coded_frame_list;
885 /* return the leading frame if we've already begun queueing */
886 size = storeframe(avctx, cx_frame, pkt_out);
889 ctx->coded_frame_list = cx_frame->next;
890 free_coded_frame(cx_frame);
893 /* consume all available output from the encoder before returning. buffers
894 * are only good through the next aom_codec call */
895 while ((pkt = aom_codec_get_cx_data(&ctx->encoder, &iter))) {
897 case AOM_CODEC_CX_FRAME_PKT:
899 struct FrameListData cx_frame;
901 /* avoid storing the frame when the list is empty and we haven't yet
902 * provided a frame for output */
903 av_assert0(!ctx->coded_frame_list);
904 cx_pktcpy(ctx, &cx_frame, pkt);
905 size = storeframe(avctx, &cx_frame, pkt_out);
909 struct FrameListData *cx_frame =
910 av_malloc(sizeof(struct FrameListData));
913 av_log(avctx, AV_LOG_ERROR,
914 "Frame queue element alloc failed\n");
915 return AVERROR(ENOMEM);
917 cx_pktcpy(ctx, cx_frame, pkt);
918 cx_frame->buf = av_malloc(cx_frame->sz);
920 if (!cx_frame->buf) {
921 av_log(avctx, AV_LOG_ERROR,
922 "Data buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n",
925 return AVERROR(ENOMEM);
927 memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
928 coded_frame_add(&ctx->coded_frame_list, cx_frame);
931 case AOM_CODEC_STATS_PKT:
933 struct aom_fixed_buf *stats = &ctx->twopass_stats;
935 if ((err = av_reallocp(&stats->buf,
937 pkt->data.twopass_stats.sz)) < 0) {
939 av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
942 memcpy((uint8_t *)stats->buf + stats->sz,
943 pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
944 stats->sz += pkt->data.twopass_stats.sz;
947 #ifdef AOM_FRAME_IS_INTRAONLY
948 case AOM_CODEC_PSNR_PKT:
950 av_assert0(!ctx->have_sse);
951 ctx->sse[0] = pkt->data.psnr.sse[0];
952 ctx->sse[1] = pkt->data.psnr.sse[1];
953 ctx->sse[2] = pkt->data.psnr.sse[2];
954 ctx->sse[3] = pkt->data.psnr.sse[3];
959 case AOM_CODEC_CUSTOM_PKT:
960 // ignore unsupported/unrecognized packet types
968 static int aom_encode(AVCodecContext *avctx, AVPacket *pkt,
969 const AVFrame *frame, int *got_packet)
971 AOMContext *ctx = avctx->priv_data;
972 struct aom_image *rawimg = NULL;
973 int64_t timestamp = 0;
975 aom_enc_frame_flags_t flags = 0;
978 rawimg = &ctx->rawimg;
979 rawimg->planes[AOM_PLANE_Y] = frame->data[0];
980 rawimg->planes[AOM_PLANE_U] = frame->data[1];
981 rawimg->planes[AOM_PLANE_V] = frame->data[2];
982 rawimg->stride[AOM_PLANE_Y] = frame->linesize[0];
983 rawimg->stride[AOM_PLANE_U] = frame->linesize[1];
984 rawimg->stride[AOM_PLANE_V] = frame->linesize[2];
985 timestamp = frame->pts;
986 switch (frame->color_range) {
987 case AVCOL_RANGE_MPEG:
988 rawimg->range = AOM_CR_STUDIO_RANGE;
990 case AVCOL_RANGE_JPEG:
991 rawimg->range = AOM_CR_FULL_RANGE;
995 if (frame->pict_type == AV_PICTURE_TYPE_I)
996 flags |= AOM_EFLAG_FORCE_KF;
999 res = aom_codec_encode(&ctx->encoder, rawimg, timestamp,
1000 avctx->ticks_per_frame, flags);
1001 if (res != AOM_CODEC_OK) {
1002 log_encoder_error(avctx, "Error encoding frame");
1003 return AVERROR_INVALIDDATA;
1005 coded_size = queue_frames(avctx, pkt);
1007 if (!frame && avctx->flags & AV_CODEC_FLAG_PASS1) {
1008 size_t b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz);
1010 avctx->stats_out = av_malloc(b64_size);
1011 if (!avctx->stats_out) {
1012 av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n",
1014 return AVERROR(ENOMEM);
1016 av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf,
1017 ctx->twopass_stats.sz);
1020 *got_packet = !!coded_size;
1024 static const enum AVPixelFormat av1_pix_fmts[] = {
1031 static const enum AVPixelFormat av1_pix_fmts_highbd[] = {
1035 AV_PIX_FMT_YUV420P10,
1036 AV_PIX_FMT_YUV422P10,
1037 AV_PIX_FMT_YUV444P10,
1038 AV_PIX_FMT_YUV420P12,
1039 AV_PIX_FMT_YUV422P12,
1040 AV_PIX_FMT_YUV444P12,
1044 static av_cold void av1_init_static(AVCodec *codec)
1046 aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
1047 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
1048 codec->pix_fmts = av1_pix_fmts_highbd;
1050 codec->pix_fmts = av1_pix_fmts;
1053 static av_cold int av1_init(AVCodecContext *avctx)
1055 return aom_init(avctx, aom_codec_av1_cx());
1058 #define OFFSET(x) offsetof(AOMContext, x)
1059 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1060 static const AVOption options[] = {
1061 { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 8, VE},
1062 { "auto-alt-ref", "Enable use of alternate reference "
1063 "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE},
1064 { "lag-in-frames", "Number of frames to look ahead at for "
1065 "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
1066 { "arnr-max-frames", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
1067 { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
1068 { "aq-mode", "adaptive quantization mode", OFFSET(aq_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 4, VE, "aq_mode"},
1069 { "none", "Aq not used", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, "aq_mode"},
1070 { "variance", "Variance based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, "aq_mode"},
1071 { "complexity", "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, "aq_mode"},
1072 { "cyclic", "Cyclic Refresh Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, "aq_mode"},
1073 { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
1074 { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
1075 { "crf", "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, VE },
1076 { "static-thresh", "A change threshold on blocks below which they will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
1077 { "drop-threshold", "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },
1078 { "denoise-noise-level", "Amount of noise to be removed", OFFSET(denoise_noise_level), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
1079 { "denoise-block-size", "Denoise block size ", OFFSET(denoise_block_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE},
1080 { "undershoot-pct", "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
1081 { "overshoot-pct", "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1000, VE},
1082 { "minsection-pct", "GOP min bitrate (% of target)", OFFSET(minsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE},
1083 { "maxsection-pct", "GOP max bitrate (% of target)", OFFSET(maxsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 5000, VE},
1084 { "frame-parallel", "Enable frame parallel decodability features", OFFSET(frame_parallel), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1085 { "tiles", "Tile columns x rows", OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, VE },
1086 { "tile-columns", "Log2 of number of tile columns to use", OFFSET(tile_cols_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
1087 { "tile-rows", "Log2 of number of tile rows to use", OFFSET(tile_rows_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE},
1088 { "row-mt", "Enable row based multi-threading", OFFSET(row_mt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1089 { "enable-cdef", "Enable CDEF filtering", OFFSET(enable_cdef), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1090 { "enable-global-motion", "Enable global motion", OFFSET(enable_global_motion), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1091 { "enable-intrabc", "Enable intra block copy prediction mode", OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1092 { "enable-restoration", "Enable Loop Restoration filtering", OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
1096 static const AVCodecDefault defaults[] = {
1101 { "keyint_min", "-1" },
1105 static const AVClass class_aom = {
1106 .class_name = "libaom-av1 encoder",
1107 .item_name = av_default_item_name,
1109 .version = LIBAVUTIL_VERSION_INT,
1112 AVCodec ff_libaom_av1_encoder = {
1113 .name = "libaom-av1",
1114 .long_name = NULL_IF_CONFIG_SMALL("libaom AV1"),
1115 .type = AVMEDIA_TYPE_VIDEO,
1116 .id = AV_CODEC_ID_AV1,
1117 .priv_data_size = sizeof(AOMContext),
1119 .encode2 = aom_encode,
1121 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_EXPERIMENTAL,
1122 .profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles),
1123 .priv_class = &class_aom,
1124 .defaults = defaults,
1125 .init_static_data = av1_init_static,
1126 .wrapper_name = "libaom",