libaomenc.c (71955B)
1 /* 2 * Copyright (c) 2010, Google, Inc. 3 * 4 * This file is part of FFmpeg. 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 /** 22 * @file 23 * AV1 encoder support via libaom 24 */ 25 26 #include <limits.h> 27 28 #define AOM_DISABLE_CTRL_TYPECHECKS 1 29 #include <aom/aom_encoder.h> 30 #include <aom/aomcx.h> 31 32 #include "libavutil/avassert.h" 33 #include "libavutil/avstring.h" 34 #include "libavutil/base64.h" 35 #include "libavutil/common.h" 36 #include "libavutil/cpu.h" 37 #include "libavutil/imgutils.h" 38 #include "libavutil/mathematics.h" 39 #include "libavutil/mem.h" 40 #include "libavutil/opt.h" 41 #include "libavutil/pixdesc.h" 42 43 #include "av1.h" 44 #include "avcodec.h" 45 #include "bsf.h" 46 #include "codec_internal.h" 47 #include "dovi_rpu.h" 48 #include "encode.h" 49 #include "internal.h" 50 #include "libaom.h" 51 #include "packet_internal.h" 52 #include "profiles.h" 53 54 /* 55 * Portion of struct aom_codec_cx_pkt from aom_encoder.h. 56 * One encoded frame returned from the library. 57 */ 58 struct FrameListData { 59 void *buf; /**< compressed data buffer */ 60 size_t sz; /**< length of compressed data */ 61 int64_t pts; /**< time stamp to show frame 62 (in timebase units) */ 63 unsigned long duration; /**< duration to show frame 64 (in timebase units) */ 65 uint32_t flags; /**< flags for this frame */ 66 uint64_t sse[4]; 67 int have_sse; /**< true if we have pending sse[] */ 68 uint64_t frame_number; 69 struct FrameListData *next; 70 }; 71 72 typedef struct AOMEncoderContext { 73 AVClass *class; 74 AVBSFContext *bsf; 75 DOVIContext dovi; 76 struct aom_codec_ctx encoder; 77 struct aom_image rawimg; 78 struct aom_fixed_buf twopass_stats; 79 unsigned twopass_stats_size; 80 struct FrameListData *coded_frame_list; 81 int cpu_used; 82 int auto_alt_ref; 83 int arnr_max_frames; 84 int arnr_strength; 85 int aq_mode; 86 int lag_in_frames; 87 int error_resilient; 88 int crf; 89 int static_thresh; 90 int drop_threshold; 91 int denoise_noise_level; 92 int denoise_block_size; 93 uint64_t sse[4]; 94 int have_sse; /**< true if we have pending sse[] */ 95 uint64_t frame_number; 96 int rc_undershoot_pct; 97 int rc_overshoot_pct; 98 int minsection_pct; 99 int maxsection_pct; 100 int frame_parallel; 101 int tile_cols, tile_rows; 102 int tile_cols_log2, tile_rows_log2; 103 aom_superblock_size_t superblock_size; 104 int uniform_tiles; 105 int row_mt; 106 int enable_cdef; 107 int enable_global_motion; 108 int enable_intrabc; 109 int enable_restoration; 110 int usage; 111 int tune; 112 int still_picture; 113 int enable_rect_partitions; 114 int enable_1to4_partitions; 115 int enable_ab_partitions; 116 int enable_angle_delta; 117 int enable_cfl_intra; 118 int enable_paeth_intra; 119 int enable_smooth_intra; 120 int enable_intra_edge_filter; 121 int enable_palette; 122 int enable_filter_intra; 123 int enable_flip_idtx; 124 int enable_tx64; 125 int reduced_tx_type_set; 126 int use_intra_dct_only; 127 int use_inter_dct_only; 128 int use_intra_default_tx_only; 129 int enable_ref_frame_mvs; 130 int enable_interinter_wedge; 131 int enable_interintra_wedge; 132 int enable_interintra_comp; 133 int enable_masked_comp; 134 int enable_obmc; 135 int enable_onesided_comp; 136 int enable_reduced_reference_set; 137 int enable_smooth_interintra; 138 int enable_diff_wtd_comp; 139 int enable_dist_wtd_comp; 140 int enable_dual_filter; 141 AVDictionary *svc_parameters; 142 AVDictionary *aom_params; 143 } AOMContext; 144 145 static const char *const ctlidstr[] = { 146 [AOME_SET_CPUUSED] = "AOME_SET_CPUUSED", 147 [AOME_SET_CQ_LEVEL] = "AOME_SET_CQ_LEVEL", 148 [AOME_SET_ENABLEAUTOALTREF] = "AOME_SET_ENABLEAUTOALTREF", 149 [AOME_SET_ARNR_MAXFRAMES] = "AOME_SET_ARNR_MAXFRAMES", 150 [AOME_SET_ARNR_STRENGTH] = "AOME_SET_ARNR_STRENGTH", 151 [AOME_SET_STATIC_THRESHOLD] = "AOME_SET_STATIC_THRESHOLD", 152 [AV1E_SET_COLOR_RANGE] = "AV1E_SET_COLOR_RANGE", 153 [AV1E_SET_COLOR_PRIMARIES] = "AV1E_SET_COLOR_PRIMARIES", 154 [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS", 155 [AV1E_SET_TRANSFER_CHARACTERISTICS] = "AV1E_SET_TRANSFER_CHARACTERISTICS", 156 [AV1E_SET_AQ_MODE] = "AV1E_SET_AQ_MODE", 157 [AV1E_SET_FRAME_PARALLEL_DECODING] = "AV1E_SET_FRAME_PARALLEL_DECODING", 158 [AV1E_SET_SUPERBLOCK_SIZE] = "AV1E_SET_SUPERBLOCK_SIZE", 159 [AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS", 160 [AV1E_SET_TILE_ROWS] = "AV1E_SET_TILE_ROWS", 161 [AV1E_SET_ENABLE_RESTORATION] = "AV1E_SET_ENABLE_RESTORATION", 162 [AV1E_SET_ROW_MT] = "AV1E_SET_ROW_MT", 163 [AV1E_SET_DENOISE_NOISE_LEVEL] = "AV1E_SET_DENOISE_NOISE_LEVEL", 164 [AV1E_SET_DENOISE_BLOCK_SIZE] = "AV1E_SET_DENOISE_BLOCK_SIZE", 165 [AV1E_SET_MAX_REFERENCE_FRAMES] = "AV1E_SET_MAX_REFERENCE_FRAMES", 166 [AV1E_SET_ENABLE_GLOBAL_MOTION] = "AV1E_SET_ENABLE_GLOBAL_MOTION", 167 [AV1E_SET_ENABLE_INTRABC] = "AV1E_SET_ENABLE_INTRABC", 168 [AV1E_SET_ENABLE_CDEF] = "AV1E_SET_ENABLE_CDEF", 169 [AOME_SET_TUNING] = "AOME_SET_TUNING", 170 [AV1E_SET_ENABLE_1TO4_PARTITIONS] = "AV1E_SET_ENABLE_1TO4_PARTITIONS", 171 [AV1E_SET_ENABLE_AB_PARTITIONS] = "AV1E_SET_ENABLE_AB_PARTITIONS", 172 [AV1E_SET_ENABLE_RECT_PARTITIONS] = "AV1E_SET_ENABLE_RECT_PARTITIONS", 173 [AV1E_SET_ENABLE_ANGLE_DELTA] = "AV1E_SET_ENABLE_ANGLE_DELTA", 174 [AV1E_SET_ENABLE_CFL_INTRA] = "AV1E_SET_ENABLE_CFL_INTRA", 175 [AV1E_SET_ENABLE_FILTER_INTRA] = "AV1E_SET_ENABLE_FILTER_INTRA", 176 [AV1E_SET_ENABLE_INTRA_EDGE_FILTER] = "AV1E_SET_ENABLE_INTRA_EDGE_FILTER", 177 [AV1E_SET_ENABLE_PAETH_INTRA] = "AV1E_SET_ENABLE_PAETH_INTRA", 178 [AV1E_SET_ENABLE_SMOOTH_INTRA] = "AV1E_SET_ENABLE_SMOOTH_INTRA", 179 [AV1E_SET_ENABLE_PALETTE] = "AV1E_SET_ENABLE_PALETTE", 180 [AV1E_SET_ENABLE_FLIP_IDTX] = "AV1E_SET_ENABLE_FLIP_IDTX", 181 [AV1E_SET_ENABLE_TX64] = "AV1E_SET_ENABLE_TX64", 182 [AV1E_SET_INTRA_DCT_ONLY] = "AV1E_SET_INTRA_DCT_ONLY", 183 [AV1E_SET_INTER_DCT_ONLY] = "AV1E_SET_INTER_DCT_ONLY", 184 [AV1E_SET_INTRA_DEFAULT_TX_ONLY] = "AV1E_SET_INTRA_DEFAULT_TX_ONLY", 185 [AV1E_SET_REDUCED_TX_TYPE_SET] = "AV1E_SET_REDUCED_TX_TYPE_SET", 186 [AV1E_SET_ENABLE_DIFF_WTD_COMP] = "AV1E_SET_ENABLE_DIFF_WTD_COMP", 187 [AV1E_SET_ENABLE_DIST_WTD_COMP] = "AV1E_SET_ENABLE_DIST_WTD_COMP", 188 [AV1E_SET_ENABLE_DUAL_FILTER] = "AV1E_SET_ENABLE_DUAL_FILTER", 189 [AV1E_SET_ENABLE_INTERINTER_WEDGE] = "AV1E_SET_ENABLE_INTERINTER_WEDGE", 190 [AV1E_SET_ENABLE_INTERINTRA_WEDGE] = "AV1E_SET_ENABLE_INTERINTRA_WEDGE", 191 [AV1E_SET_ENABLE_MASKED_COMP] = "AV1E_SET_ENABLE_MASKED_COMP", 192 [AV1E_SET_ENABLE_INTERINTRA_COMP] = "AV1E_SET_ENABLE_INTERINTRA_COMP", 193 [AV1E_SET_ENABLE_OBMC] = "AV1E_SET_ENABLE_OBMC", 194 [AV1E_SET_ENABLE_ONESIDED_COMP] = "AV1E_SET_ENABLE_ONESIDED_COMP", 195 [AV1E_SET_REDUCED_REFERENCE_SET] = "AV1E_SET_REDUCED_REFERENCE_SET", 196 [AV1E_SET_ENABLE_SMOOTH_INTERINTRA] = "AV1E_SET_ENABLE_SMOOTH_INTERINTRA", 197 [AV1E_SET_ENABLE_REF_FRAME_MVS] = "AV1E_SET_ENABLE_REF_FRAME_MVS", 198 #ifdef AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS 199 [AV1E_GET_NUM_OPERATING_POINTS] = "AV1E_GET_NUM_OPERATING_POINTS", 200 #endif 201 [AV1E_GET_SEQ_LEVEL_IDX] = "AV1E_GET_SEQ_LEVEL_IDX", 202 #ifdef AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX 203 [AV1E_GET_TARGET_SEQ_LEVEL_IDX] = "AV1E_GET_TARGET_SEQ_LEVEL_IDX", 204 #endif 205 [AV1_GET_NEW_FRAME_IMAGE] = "AV1_GET_NEW_FRAME_IMAGE", 206 [AV1E_SET_SVC_PARAMS] = "AV1E_SET_SVC_PARAMS", 207 }; 208 209 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) 210 { 211 AOMContext *ctx = avctx->priv_data; 212 const char *error = aom_codec_error(&ctx->encoder); 213 const char *detail = aom_codec_error_detail(&ctx->encoder); 214 215 av_log(avctx, AV_LOG_ERROR, "%s: %s\n", desc, error); 216 if (detail) 217 av_log(avctx, AV_LOG_ERROR, " Additional information: %s\n", detail); 218 } 219 220 static av_cold void dump_enc_cfg(AVCodecContext *avctx, 221 const struct aom_codec_enc_cfg *cfg, 222 int level) 223 { 224 int width = -30; 225 226 av_log(avctx, level, "aom_codec_enc_cfg\n"); 227 av_log(avctx, level, "generic settings\n" 228 " %*s%u\n %*s%u\n %*s%u\n %*s%u\n %*s%u\n" 229 " %*s%u\n %*s%u\n" 230 " %*s{%u/%u}\n %*s%u\n %*s%d\n %*s%u\n", 231 width, "g_usage:", cfg->g_usage, 232 width, "g_threads:", cfg->g_threads, 233 width, "g_profile:", cfg->g_profile, 234 width, "g_w:", cfg->g_w, 235 width, "g_h:", cfg->g_h, 236 width, "g_bit_depth:", cfg->g_bit_depth, 237 width, "g_input_bit_depth:", cfg->g_input_bit_depth, 238 width, "g_timebase:", cfg->g_timebase.num, cfg->g_timebase.den, 239 width, "g_error_resilient:", cfg->g_error_resilient, 240 width, "g_pass:", cfg->g_pass, 241 width, "g_lag_in_frames:", cfg->g_lag_in_frames); 242 av_log(avctx, level, "rate control settings\n" 243 " %*s%u\n %*s%d\n %*s%p(%"SIZE_SPECIFIER")\n %*s%u\n", 244 width, "rc_dropframe_thresh:", cfg->rc_dropframe_thresh, 245 width, "rc_end_usage:", cfg->rc_end_usage, 246 width, "rc_twopass_stats_in:", cfg->rc_twopass_stats_in.buf, cfg->rc_twopass_stats_in.sz, 247 width, "rc_target_bitrate:", cfg->rc_target_bitrate); 248 av_log(avctx, level, "quantizer settings\n" 249 " %*s%u\n %*s%u\n", 250 width, "rc_min_quantizer:", cfg->rc_min_quantizer, 251 width, "rc_max_quantizer:", cfg->rc_max_quantizer); 252 av_log(avctx, level, "bitrate tolerance\n" 253 " %*s%u\n %*s%u\n", 254 width, "rc_undershoot_pct:", cfg->rc_undershoot_pct, 255 width, "rc_overshoot_pct:", cfg->rc_overshoot_pct); 256 av_log(avctx, level, "decoder buffer model\n" 257 " %*s%u\n %*s%u\n %*s%u\n", 258 width, "rc_buf_sz:", cfg->rc_buf_sz, 259 width, "rc_buf_initial_sz:", cfg->rc_buf_initial_sz, 260 width, "rc_buf_optimal_sz:", cfg->rc_buf_optimal_sz); 261 av_log(avctx, level, "2 pass rate control settings\n" 262 " %*s%u\n %*s%u\n %*s%u\n", 263 width, "rc_2pass_vbr_bias_pct:", cfg->rc_2pass_vbr_bias_pct, 264 width, "rc_2pass_vbr_minsection_pct:", cfg->rc_2pass_vbr_minsection_pct, 265 width, "rc_2pass_vbr_maxsection_pct:", cfg->rc_2pass_vbr_maxsection_pct); 266 av_log(avctx, level, "keyframing settings\n" 267 " %*s%d\n %*s%u\n %*s%u\n", 268 width, "kf_mode:", cfg->kf_mode, 269 width, "kf_min_dist:", cfg->kf_min_dist, 270 width, "kf_max_dist:", cfg->kf_max_dist); 271 av_log(avctx, level, "tile settings\n" 272 " %*s%d\n %*s%d\n", 273 width, "tile_width_count:", cfg->tile_width_count, 274 width, "tile_height_count:", cfg->tile_height_count); 275 av_log(avctx, level, "\n"); 276 } 277 278 static void coded_frame_add(void *list, struct FrameListData *cx_frame) 279 { 280 struct FrameListData **p = list; 281 282 while (*p) 283 p = &(*p)->next; 284 *p = cx_frame; 285 cx_frame->next = NULL; 286 } 287 288 static av_cold void free_coded_frame(struct FrameListData *cx_frame) 289 { 290 av_freep(&cx_frame->buf); 291 av_freep(&cx_frame); 292 } 293 294 static av_cold void free_frame_list(struct FrameListData *list) 295 { 296 struct FrameListData *p = list; 297 298 while (p) { 299 list = list->next; 300 free_coded_frame(p); 301 p = list; 302 } 303 } 304 305 static av_cold int codecctl_int(AVCodecContext *avctx, 306 #ifdef UENUM1BYTE 307 aome_enc_control_id id, 308 #else 309 enum aome_enc_control_id id, 310 #endif 311 int val) 312 { 313 AOMContext *ctx = avctx->priv_data; 314 char buf[80]; 315 int width = -30; 316 int res; 317 318 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); 319 av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, val); 320 321 res = aom_codec_control(&ctx->encoder, id, val); 322 if (res != AOM_CODEC_OK) { 323 snprintf(buf, sizeof(buf), "Failed to set %s codec control", 324 ctlidstr[id]); 325 log_encoder_error(avctx, buf); 326 return AVERROR(EINVAL); 327 } 328 329 return 0; 330 } 331 332 #if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \ 333 defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \ 334 defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX) 335 static av_cold int codecctl_intp(AVCodecContext *avctx, 336 #ifdef UENUM1BYTE 337 aome_enc_control_id id, 338 #else 339 enum aome_enc_control_id id, 340 #endif 341 int* ptr) 342 { 343 AOMContext *ctx = avctx->priv_data; 344 char buf[80]; 345 int width = -30; 346 int res; 347 348 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); 349 av_log(avctx, AV_LOG_DEBUG, " %*s%d\n", width, buf, *ptr); 350 351 res = aom_codec_control(&ctx->encoder, id, ptr); 352 if (res != AOM_CODEC_OK) { 353 snprintf(buf, sizeof(buf), "Failed to set %s codec control", 354 ctlidstr[id]); 355 log_encoder_error(avctx, buf); 356 return AVERROR(EINVAL); 357 } 358 359 return 0; 360 } 361 #endif 362 363 static av_cold int codecctl_imgp(AVCodecContext *avctx, 364 #ifdef UENUM1BYTE 365 aome_enc_control_id id, 366 #else 367 enum aome_enc_control_id id, 368 #endif 369 struct aom_image *img) 370 { 371 AOMContext *ctx = avctx->priv_data; 372 char buf[80]; 373 int res; 374 375 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); 376 377 res = aom_codec_control(&ctx->encoder, id, img); 378 if (res != AOM_CODEC_OK) { 379 snprintf(buf, sizeof(buf), "Failed to get %s codec control", 380 ctlidstr[id]); 381 log_encoder_error(avctx, buf); 382 return AVERROR(EINVAL); 383 } 384 385 return 0; 386 } 387 388 static av_cold int codecctl_svcp(AVCodecContext *avctx, 389 #ifdef UENUM1BYTE 390 aome_enc_control_id id, 391 #else 392 enum aome_enc_control_id id, 393 #endif 394 aom_svc_params_t *svc_params) 395 { 396 AOMContext *ctx = avctx->priv_data; 397 char buf[80]; 398 int res; 399 400 snprintf(buf, sizeof(buf), "%s:", ctlidstr[id]); 401 402 res = aom_codec_control(&ctx->encoder, id, svc_params); 403 if (res != AOM_CODEC_OK) { 404 snprintf(buf, sizeof(buf), "Failed to get %s codec control", 405 ctlidstr[id]); 406 log_encoder_error(avctx, buf); 407 return AVERROR(EINVAL); 408 } 409 410 return 0; 411 } 412 413 static av_cold int aom_free(AVCodecContext *avctx) 414 { 415 AOMContext *ctx = avctx->priv_data; 416 417 #if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \ 418 defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \ 419 defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX) 420 if (ctx->encoder.iface && !(avctx->flags & AV_CODEC_FLAG_PASS1)) { 421 int num_operating_points; 422 int levels[32]; 423 int target_levels[32]; 424 425 if (!codecctl_intp(avctx, AV1E_GET_NUM_OPERATING_POINTS, 426 &num_operating_points) && 427 !codecctl_intp(avctx, AV1E_GET_SEQ_LEVEL_IDX, levels) && 428 !codecctl_intp(avctx, AV1E_GET_TARGET_SEQ_LEVEL_IDX, 429 target_levels)) { 430 for (int i = 0; i < num_operating_points; i++) { 431 if (levels[i] > target_levels[i]) { 432 // Warn when the target level was not met 433 av_log(avctx, AV_LOG_WARNING, 434 "Could not encode to target level %d.%d for " 435 "operating point %d. The output level is %d.%d.\n", 436 2 + (target_levels[i] >> 2), target_levels[i] & 3, 437 i, 2 + (levels[i] >> 2), levels[i] & 3); 438 } else if (target_levels[i] < 31) { 439 // Log the encoded level if a target level was given 440 av_log(avctx, AV_LOG_INFO, 441 "Output level for operating point %d is %d.%d.\n", 442 i, 2 + (levels[i] >> 2), levels[i] & 3); 443 } 444 } 445 } 446 } 447 #endif 448 449 aom_codec_destroy(&ctx->encoder); 450 aom_img_remove_metadata(&ctx->rawimg); 451 av_freep(&ctx->twopass_stats.buf); 452 av_freep(&avctx->stats_out); 453 free_frame_list(ctx->coded_frame_list); 454 av_bsf_free(&ctx->bsf); 455 ff_dovi_ctx_unref(&ctx->dovi); 456 return 0; 457 } 458 459 static void aom_svc_parse_int_array(int *dest, char *value, int max_entries) 460 { 461 int dest_idx = 0; 462 char *saveptr = NULL; 463 char *token = av_strtok(value, ",", &saveptr); 464 465 while (token && dest_idx < max_entries) { 466 dest[dest_idx++] = strtoul(token, NULL, 10); 467 token = av_strtok(NULL, ",", &saveptr); 468 } 469 } 470 471 static int set_pix_fmt(AVCodecContext *avctx, aom_codec_caps_t codec_caps, 472 struct aom_codec_enc_cfg *enccfg, aom_codec_flags_t *flags, 473 aom_img_fmt_t *img_fmt) 474 { 475 AOMContext av_unused *ctx = avctx->priv_data; 476 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 477 enccfg->g_bit_depth = enccfg->g_input_bit_depth = desc->comp[0].depth; 478 switch (avctx->pix_fmt) { 479 case AV_PIX_FMT_GRAY8: 480 enccfg->monochrome = 1; 481 /* Fall-through */ 482 case AV_PIX_FMT_YUV420P: 483 enccfg->g_profile = AV_PROFILE_AV1_MAIN; 484 *img_fmt = AOM_IMG_FMT_I420; 485 return 0; 486 case AV_PIX_FMT_YUV422P: 487 enccfg->g_profile = AV_PROFILE_AV1_PROFESSIONAL; 488 *img_fmt = AOM_IMG_FMT_I422; 489 return 0; 490 case AV_PIX_FMT_YUV444P: 491 case AV_PIX_FMT_GBRP: 492 enccfg->g_profile = AV_PROFILE_AV1_HIGH; 493 *img_fmt = AOM_IMG_FMT_I444; 494 return 0; 495 case AV_PIX_FMT_GRAY10: 496 case AV_PIX_FMT_GRAY12: 497 enccfg->monochrome = 1; 498 /* Fall-through */ 499 case AV_PIX_FMT_YUV420P10: 500 case AV_PIX_FMT_YUV420P12: 501 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { 502 enccfg->g_profile = 503 enccfg->g_bit_depth == 10 ? AV_PROFILE_AV1_MAIN : AV_PROFILE_AV1_PROFESSIONAL; 504 *img_fmt = AOM_IMG_FMT_I42016; 505 *flags |= AOM_CODEC_USE_HIGHBITDEPTH; 506 return 0; 507 } 508 break; 509 case AV_PIX_FMT_YUV422P10: 510 case AV_PIX_FMT_YUV422P12: 511 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { 512 enccfg->g_profile = AV_PROFILE_AV1_PROFESSIONAL; 513 *img_fmt = AOM_IMG_FMT_I42216; 514 *flags |= AOM_CODEC_USE_HIGHBITDEPTH; 515 return 0; 516 } 517 break; 518 case AV_PIX_FMT_YUV444P10: 519 case AV_PIX_FMT_YUV444P12: 520 case AV_PIX_FMT_GBRP10: 521 case AV_PIX_FMT_GBRP12: 522 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { 523 enccfg->g_profile = 524 enccfg->g_bit_depth == 10 ? AV_PROFILE_AV1_HIGH : AV_PROFILE_AV1_PROFESSIONAL; 525 *img_fmt = AOM_IMG_FMT_I44416; 526 *flags |= AOM_CODEC_USE_HIGHBITDEPTH; 527 return 0; 528 } 529 break; 530 default: 531 break; 532 } 533 av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n"); 534 return AVERROR_INVALIDDATA; 535 } 536 537 static void set_color_range(AVCodecContext *avctx) 538 { 539 aom_color_range_t aom_cr; 540 switch (avctx->color_range) { 541 case AVCOL_RANGE_UNSPECIFIED: 542 case AVCOL_RANGE_MPEG: aom_cr = AOM_CR_STUDIO_RANGE; break; 543 case AVCOL_RANGE_JPEG: aom_cr = AOM_CR_FULL_RANGE; break; 544 default: 545 av_log(avctx, AV_LOG_WARNING, "Unsupported color range (%d)\n", 546 avctx->color_range); 547 return; 548 } 549 550 codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr); 551 } 552 553 static int count_uniform_tiling(int dim, int sb_size, int tiles_log2) 554 { 555 int sb_dim = (dim + sb_size - 1) / sb_size; 556 int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2; 557 av_assert0(tile_dim > 0); 558 return (sb_dim + tile_dim - 1) / tile_dim; 559 } 560 561 static int choose_tiling(AVCodecContext *avctx, 562 struct aom_codec_enc_cfg *enccfg) 563 { 564 AOMContext *ctx = avctx->priv_data; 565 int sb_128x128_possible, sb_size, sb_width, sb_height; 566 int uniform_rows, uniform_cols; 567 int uniform_64x64_possible, uniform_128x128_possible; 568 int tile_size, rounding, i; 569 570 if (ctx->tile_cols_log2 >= 0) 571 ctx->tile_cols = 1 << ctx->tile_cols_log2; 572 if (ctx->tile_rows_log2 >= 0) 573 ctx->tile_rows = 1 << ctx->tile_rows_log2; 574 575 if (ctx->tile_cols == 0) { 576 ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) / 577 AV1_MAX_TILE_WIDTH; 578 if (ctx->tile_cols > 1) { 579 av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile " 580 "columns to fill width.\n", ctx->tile_cols); 581 } 582 } 583 av_assert0(ctx->tile_cols > 0); 584 if (ctx->tile_rows == 0) { 585 int max_tile_width = 586 FFALIGN((FFALIGN(avctx->width, 128) + 587 ctx->tile_cols - 1) / ctx->tile_cols, 128); 588 ctx->tile_rows = 589 (max_tile_width * FFALIGN(avctx->height, 128) + 590 AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA; 591 if (ctx->tile_rows > 1) { 592 av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile " 593 "rows to fill area.\n", ctx->tile_rows); 594 } 595 } 596 av_assert0(ctx->tile_rows > 0); 597 598 if ((avctx->width + 63) / 64 < ctx->tile_cols || 599 (avctx->height + 63) / 64 < ctx->tile_rows) { 600 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not " 601 "large enough to fit specified tile arrangement.\n"); 602 return AVERROR(EINVAL); 603 } 604 if (ctx->tile_cols > AV1_MAX_TILE_COLS || 605 ctx->tile_rows > AV1_MAX_TILE_ROWS) { 606 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does " 607 "not allow more than %dx%d tiles.\n", 608 AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS); 609 return AVERROR(EINVAL); 610 } 611 if (avctx->width / ctx->tile_cols > AV1_MAX_TILE_WIDTH) { 612 av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does " 613 "not allow tiles of width greater than %d.\n", 614 AV1_MAX_TILE_WIDTH); 615 return AVERROR(EINVAL); 616 } 617 618 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC; 619 620 if (ctx->tile_cols == 1 && ctx->tile_rows == 1) { 621 av_log(avctx, AV_LOG_DEBUG, "Using a single tile.\n"); 622 return 0; 623 } 624 625 sb_128x128_possible = 626 (avctx->width + 127) / 128 >= ctx->tile_cols && 627 (avctx->height + 127) / 128 >= ctx->tile_rows; 628 629 ctx->tile_cols_log2 = ctx->tile_cols == 1 ? 0 : 630 av_log2(ctx->tile_cols - 1) + 1; 631 ctx->tile_rows_log2 = ctx->tile_rows == 1 ? 0 : 632 av_log2(ctx->tile_rows - 1) + 1; 633 634 uniform_cols = count_uniform_tiling(avctx->width, 635 64, ctx->tile_cols_log2); 636 uniform_rows = count_uniform_tiling(avctx->height, 637 64, ctx->tile_rows_log2); 638 av_log(avctx, AV_LOG_DEBUG, "Uniform with 64x64 superblocks " 639 "-> %dx%d tiles.\n", uniform_cols, uniform_rows); 640 uniform_64x64_possible = uniform_cols == ctx->tile_cols && 641 uniform_rows == ctx->tile_rows; 642 643 if (sb_128x128_possible) { 644 uniform_cols = count_uniform_tiling(avctx->width, 645 128, ctx->tile_cols_log2); 646 uniform_rows = count_uniform_tiling(avctx->height, 647 128, ctx->tile_rows_log2); 648 av_log(avctx, AV_LOG_DEBUG, "Uniform with 128x128 superblocks " 649 "-> %dx%d tiles.\n", uniform_cols, uniform_rows); 650 uniform_128x128_possible = uniform_cols == ctx->tile_cols && 651 uniform_rows == ctx->tile_rows; 652 } else { 653 av_log(avctx, AV_LOG_DEBUG, "128x128 superblocks not possible.\n"); 654 uniform_128x128_possible = 0; 655 } 656 657 ctx->uniform_tiles = 1; 658 if (uniform_64x64_possible && uniform_128x128_possible) { 659 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with dynamic " 660 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n", 661 ctx->tile_cols_log2, ctx->tile_rows_log2); 662 return 0; 663 } 664 if (uniform_64x64_possible && !sb_128x128_possible) { 665 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with 64x64 " 666 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n", 667 ctx->tile_cols_log2, ctx->tile_rows_log2); 668 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64; 669 return 0; 670 } 671 if (uniform_128x128_possible) { 672 av_log(avctx, AV_LOG_DEBUG, "Using uniform tiling with 128x128 " 673 "superblocks (tile_cols_log2 = %d, tile_rows_log2 = %d).\n", 674 ctx->tile_cols_log2, ctx->tile_rows_log2); 675 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128; 676 return 0; 677 } 678 ctx->uniform_tiles = 0; 679 680 if (sb_128x128_possible) { 681 sb_size = 128; 682 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_128X128; 683 } else { 684 sb_size = 64; 685 ctx->superblock_size = AOM_SUPERBLOCK_SIZE_64X64; 686 } 687 av_log(avctx, AV_LOG_DEBUG, "Using fixed tiling with %dx%d " 688 "superblocks (tile_cols = %d, tile_rows = %d).\n", 689 sb_size, sb_size, ctx->tile_cols, ctx->tile_rows); 690 691 enccfg->tile_width_count = ctx->tile_cols; 692 enccfg->tile_height_count = ctx->tile_rows; 693 694 sb_width = (avctx->width + sb_size - 1) / sb_size; 695 sb_height = (avctx->height + sb_size - 1) / sb_size; 696 697 tile_size = sb_width / ctx->tile_cols; 698 rounding = sb_width % ctx->tile_cols; 699 for (i = 0; i < ctx->tile_cols; i++) { 700 enccfg->tile_widths[i] = tile_size + 701 (i < rounding / 2 || 702 i > ctx->tile_cols - 1 - (rounding + 1) / 2); 703 } 704 705 tile_size = sb_height / ctx->tile_rows; 706 rounding = sb_height % ctx->tile_rows; 707 for (i = 0; i < ctx->tile_rows; i++) { 708 enccfg->tile_heights[i] = tile_size + 709 (i < rounding / 2 || 710 i > ctx->tile_rows - 1 - (rounding + 1) / 2); 711 } 712 713 return 0; 714 } 715 716 static av_cold int aom_init(AVCodecContext *avctx, 717 const struct aom_codec_iface *iface) 718 { 719 AOMContext *ctx = avctx->priv_data; 720 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 721 struct aom_codec_enc_cfg enccfg = { 0 }; 722 aom_codec_flags_t flags = 723 (avctx->flags & AV_CODEC_FLAG_PSNR) ? AOM_CODEC_USE_PSNR : 0; 724 AVCPBProperties *cpb_props; 725 int res; 726 aom_img_fmt_t img_fmt; 727 aom_codec_caps_t codec_caps = aom_codec_get_caps(iface); 728 729 av_log(avctx, AV_LOG_INFO, "%s\n", aom_codec_version_str()); 730 av_log(avctx, AV_LOG_VERBOSE, "%s\n", aom_codec_build_config()); 731 732 if ((res = aom_codec_enc_config_default(iface, &enccfg, ctx->usage)) != AOM_CODEC_OK) { 733 av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n", 734 aom_codec_err_to_string(res)); 735 return AVERROR(EINVAL); 736 } 737 738 if (set_pix_fmt(avctx, codec_caps, &enccfg, &flags, &img_fmt)) 739 return AVERROR(EINVAL); 740 741 if(!avctx->bit_rate) 742 if(avctx->rc_max_rate || avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) { 743 av_log( avctx, AV_LOG_ERROR, "Rate control parameters set without a bitrate\n"); 744 return AVERROR(EINVAL); 745 } 746 747 dump_enc_cfg(avctx, &enccfg, AV_LOG_DEBUG); 748 749 enccfg.g_w = avctx->width; 750 enccfg.g_h = avctx->height; 751 enccfg.g_timebase.num = avctx->time_base.num; 752 enccfg.g_timebase.den = avctx->time_base.den; 753 enccfg.g_threads = 754 FFMIN(avctx->thread_count ? avctx->thread_count : av_cpu_count(), 64); 755 756 if (ctx->lag_in_frames >= 0) 757 enccfg.g_lag_in_frames = ctx->lag_in_frames; 758 759 if (avctx->flags & AV_CODEC_FLAG_PASS1) 760 enccfg.g_pass = AOM_RC_FIRST_PASS; 761 else if (avctx->flags & AV_CODEC_FLAG_PASS2) 762 enccfg.g_pass = AOM_RC_LAST_PASS; 763 else 764 enccfg.g_pass = AOM_RC_ONE_PASS; 765 766 if (avctx->rc_min_rate == avctx->rc_max_rate && 767 avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate) { 768 enccfg.rc_end_usage = AOM_CBR; 769 } else if (ctx->crf >= 0) { 770 enccfg.rc_end_usage = AOM_CQ; 771 if (!avctx->bit_rate) 772 enccfg.rc_end_usage = AOM_Q; 773 } 774 775 if (avctx->bit_rate) { 776 enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000, 777 AV_ROUND_NEAR_INF); 778 } else if (enccfg.rc_end_usage != AOM_Q) { 779 enccfg.rc_end_usage = AOM_Q; 780 ctx->crf = 32; 781 av_log(avctx, AV_LOG_WARNING, 782 "Neither bitrate nor constrained quality specified, using default CRF of %d\n", 783 ctx->crf); 784 } 785 786 if (avctx->qmin >= 0) 787 enccfg.rc_min_quantizer = avctx->qmin; 788 if (avctx->qmax >= 0) { 789 enccfg.rc_max_quantizer = avctx->qmax; 790 } else if (!ctx->crf) { 791 enccfg.rc_max_quantizer = 0; 792 } 793 794 if (enccfg.rc_end_usage == AOM_CQ || enccfg.rc_end_usage == AOM_Q) { 795 if (ctx->crf < enccfg.rc_min_quantizer || ctx->crf > enccfg.rc_max_quantizer) { 796 av_log(avctx, AV_LOG_ERROR, 797 "CQ level %d must be between minimum and maximum quantizer value (%d-%d)\n", 798 ctx->crf, enccfg.rc_min_quantizer, enccfg.rc_max_quantizer); 799 return AVERROR(EINVAL); 800 } 801 } 802 803 enccfg.rc_dropframe_thresh = ctx->drop_threshold; 804 805 // 0-100 (0 => CBR, 100 => VBR) 806 enccfg.rc_2pass_vbr_bias_pct = round(avctx->qcompress * 100); 807 if (ctx->minsection_pct >= 0) 808 enccfg.rc_2pass_vbr_minsection_pct = ctx->minsection_pct; 809 else if (avctx->bit_rate) 810 enccfg.rc_2pass_vbr_minsection_pct = 811 avctx->rc_min_rate * 100LL / avctx->bit_rate; 812 if (ctx->maxsection_pct >= 0) 813 enccfg.rc_2pass_vbr_maxsection_pct = ctx->maxsection_pct; 814 else if (avctx->rc_max_rate) 815 enccfg.rc_2pass_vbr_maxsection_pct = 816 avctx->rc_max_rate * 100LL / avctx->bit_rate; 817 818 if (avctx->rc_buffer_size) 819 enccfg.rc_buf_sz = 820 avctx->rc_buffer_size * 1000LL / avctx->bit_rate; 821 if (avctx->rc_initial_buffer_occupancy) 822 enccfg.rc_buf_initial_sz = 823 avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate; 824 enccfg.rc_buf_optimal_sz = enccfg.rc_buf_sz * 5 / 6; 825 826 if (ctx->rc_undershoot_pct >= 0) 827 enccfg.rc_undershoot_pct = ctx->rc_undershoot_pct; 828 if (ctx->rc_overshoot_pct >= 0) 829 enccfg.rc_overshoot_pct = ctx->rc_overshoot_pct; 830 831 // _enc_init() will balk if kf_min_dist differs from max w/AOM_KF_AUTO 832 if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size) 833 enccfg.kf_min_dist = avctx->keyint_min; 834 if (avctx->gop_size >= 0) 835 enccfg.kf_max_dist = avctx->gop_size; 836 837 if (enccfg.g_pass == AOM_RC_FIRST_PASS) 838 enccfg.g_lag_in_frames = 0; 839 else if (enccfg.g_pass == AOM_RC_LAST_PASS) { 840 int decode_size, ret; 841 842 if (!avctx->stats_in) { 843 av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n"); 844 return AVERROR_INVALIDDATA; 845 } 846 847 ctx->twopass_stats.sz = strlen(avctx->stats_in) * 3 / 4; 848 ret = av_reallocp(&ctx->twopass_stats.buf, ctx->twopass_stats.sz); 849 if (ret < 0) { 850 av_log(avctx, AV_LOG_ERROR, 851 "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n", 852 ctx->twopass_stats.sz); 853 ctx->twopass_stats.sz = 0; 854 return ret; 855 } 856 decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in, 857 ctx->twopass_stats.sz); 858 if (decode_size < 0) { 859 av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n"); 860 return AVERROR_INVALIDDATA; 861 } 862 863 ctx->twopass_stats.sz = decode_size; 864 enccfg.rc_twopass_stats_in = ctx->twopass_stats; 865 } 866 867 /* 0-3: For non-zero values the encoder increasingly optimizes for reduced 868 * complexity playback on low powered devices at the expense of encode 869 * quality. */ 870 if (avctx->profile != AV_PROFILE_UNKNOWN) 871 enccfg.g_profile = avctx->profile; 872 873 enccfg.g_error_resilient = ctx->error_resilient; 874 875 res = choose_tiling(avctx, &enccfg); 876 if (res < 0) 877 return res; 878 879 if (ctx->still_picture) { 880 // Set the maximum number of frames to 1. This will let libaom set 881 // still_picture and reduced_still_picture_header to 1 in the Sequence 882 // Header as required by AVIF still images. 883 enccfg.g_limit = 1; 884 // Reduce memory usage for still images. 885 enccfg.g_lag_in_frames = 0; 886 // All frames will be key frames. 887 enccfg.kf_max_dist = 0; 888 enccfg.kf_mode = AOM_KF_DISABLED; 889 } 890 891 /* Construct Encoder Context */ 892 res = aom_codec_enc_init(&ctx->encoder, iface, &enccfg, flags); 893 if (res != AOM_CODEC_OK) { 894 dump_enc_cfg(avctx, &enccfg, AV_LOG_WARNING); 895 log_encoder_error(avctx, "Failed to initialize encoder"); 896 return AVERROR(EINVAL); 897 } 898 dump_enc_cfg(avctx, &enccfg, AV_LOG_DEBUG); 899 900 // codec control failures are currently treated only as warnings 901 av_log(avctx, AV_LOG_DEBUG, "aom_codec_control\n"); 902 codecctl_int(avctx, AOME_SET_CPUUSED, ctx->cpu_used); 903 if (ctx->auto_alt_ref >= 0) 904 codecctl_int(avctx, AOME_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref); 905 if (ctx->arnr_max_frames >= 0) 906 codecctl_int(avctx, AOME_SET_ARNR_MAXFRAMES, ctx->arnr_max_frames); 907 if (ctx->arnr_strength >= 0) 908 codecctl_int(avctx, AOME_SET_ARNR_STRENGTH, ctx->arnr_strength); 909 if (ctx->enable_cdef >= 0) 910 codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef); 911 if (ctx->enable_restoration >= 0) 912 codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration); 913 if (ctx->enable_rect_partitions >= 0) 914 codecctl_int(avctx, AV1E_SET_ENABLE_RECT_PARTITIONS, ctx->enable_rect_partitions); 915 if (ctx->enable_1to4_partitions >= 0) 916 codecctl_int(avctx, AV1E_SET_ENABLE_1TO4_PARTITIONS, ctx->enable_1to4_partitions); 917 if (ctx->enable_ab_partitions >= 0) 918 codecctl_int(avctx, AV1E_SET_ENABLE_AB_PARTITIONS, ctx->enable_ab_partitions); 919 if (ctx->enable_angle_delta >= 0) 920 codecctl_int(avctx, AV1E_SET_ENABLE_ANGLE_DELTA, ctx->enable_angle_delta); 921 if (ctx->enable_cfl_intra >= 0) 922 codecctl_int(avctx, AV1E_SET_ENABLE_CFL_INTRA, ctx->enable_cfl_intra); 923 if (ctx->enable_filter_intra >= 0) 924 codecctl_int(avctx, AV1E_SET_ENABLE_FILTER_INTRA, ctx->enable_filter_intra); 925 if (ctx->enable_intra_edge_filter >= 0) 926 codecctl_int(avctx, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctx->enable_intra_edge_filter); 927 if (ctx->enable_paeth_intra >= 0) 928 codecctl_int(avctx, AV1E_SET_ENABLE_PAETH_INTRA, ctx->enable_paeth_intra); 929 if (ctx->enable_smooth_intra >= 0) 930 codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTRA, ctx->enable_smooth_intra); 931 if (ctx->enable_palette >= 0) 932 codecctl_int(avctx, AV1E_SET_ENABLE_PALETTE, ctx->enable_palette); 933 if (ctx->enable_tx64 >= 0) 934 codecctl_int(avctx, AV1E_SET_ENABLE_TX64, ctx->enable_tx64); 935 if (ctx->enable_flip_idtx >= 0) 936 codecctl_int(avctx, AV1E_SET_ENABLE_FLIP_IDTX, ctx->enable_flip_idtx); 937 if (ctx->use_intra_dct_only >= 0) 938 codecctl_int(avctx, AV1E_SET_INTRA_DCT_ONLY, ctx->use_intra_dct_only); 939 if (ctx->use_inter_dct_only >= 0) 940 codecctl_int(avctx, AV1E_SET_INTER_DCT_ONLY, ctx->use_inter_dct_only); 941 if (ctx->use_intra_default_tx_only >= 0) 942 codecctl_int(avctx, AV1E_SET_INTRA_DEFAULT_TX_ONLY, ctx->use_intra_default_tx_only); 943 if (ctx->reduced_tx_type_set >= 0) 944 codecctl_int(avctx, AV1E_SET_REDUCED_TX_TYPE_SET, ctx->reduced_tx_type_set); 945 if (ctx->enable_ref_frame_mvs >= 0) 946 codecctl_int(avctx, AV1E_SET_ENABLE_REF_FRAME_MVS, ctx->enable_ref_frame_mvs); 947 if (ctx->enable_reduced_reference_set >= 0) 948 codecctl_int(avctx, AV1E_SET_REDUCED_REFERENCE_SET, ctx->enable_reduced_reference_set); 949 if (ctx->enable_diff_wtd_comp >= 0) 950 codecctl_int(avctx, AV1E_SET_ENABLE_DIFF_WTD_COMP, ctx->enable_diff_wtd_comp); 951 if (ctx->enable_dist_wtd_comp >= 0) 952 codecctl_int(avctx, AV1E_SET_ENABLE_DIST_WTD_COMP, ctx->enable_dist_wtd_comp); 953 if (ctx->enable_dual_filter >= 0) 954 codecctl_int(avctx, AV1E_SET_ENABLE_DUAL_FILTER, ctx->enable_dual_filter); 955 if (ctx->enable_interinter_wedge >= 0) 956 codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTER_WEDGE, ctx->enable_interinter_wedge); 957 if (ctx->enable_masked_comp >= 0) 958 codecctl_int(avctx, AV1E_SET_ENABLE_MASKED_COMP, ctx->enable_masked_comp); 959 if (ctx->enable_interintra_comp >= 0) 960 codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_COMP, ctx->enable_interintra_comp); 961 if (ctx->enable_interintra_wedge >= 0) 962 codecctl_int(avctx, AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctx->enable_interintra_wedge); 963 if (ctx->enable_obmc >= 0) 964 codecctl_int(avctx, AV1E_SET_ENABLE_OBMC, ctx->enable_obmc); 965 if (ctx->enable_onesided_comp >= 0) 966 codecctl_int(avctx, AV1E_SET_ENABLE_ONESIDED_COMP, ctx->enable_onesided_comp); 967 if (ctx->enable_smooth_interintra >= 0) 968 codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctx->enable_smooth_interintra); 969 970 codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh); 971 if (ctx->crf >= 0) 972 codecctl_int(avctx, AOME_SET_CQ_LEVEL, ctx->crf); 973 if (ctx->tune >= 0) 974 codecctl_int(avctx, AOME_SET_TUNING, ctx->tune); 975 976 if (desc->flags & AV_PIX_FMT_FLAG_RGB) { 977 codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, AVCOL_PRI_BT709); 978 codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, AVCOL_SPC_RGB); 979 codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, AVCOL_TRC_IEC61966_2_1); 980 } else { 981 codecctl_int(avctx, AV1E_SET_COLOR_PRIMARIES, avctx->color_primaries); 982 codecctl_int(avctx, AV1E_SET_MATRIX_COEFFICIENTS, avctx->colorspace); 983 codecctl_int(avctx, AV1E_SET_TRANSFER_CHARACTERISTICS, avctx->color_trc); 984 } 985 if (ctx->aq_mode >= 0) 986 codecctl_int(avctx, AV1E_SET_AQ_MODE, ctx->aq_mode); 987 if (ctx->frame_parallel >= 0) 988 codecctl_int(avctx, AV1E_SET_FRAME_PARALLEL_DECODING, ctx->frame_parallel); 989 set_color_range(avctx); 990 991 codecctl_int(avctx, AV1E_SET_SUPERBLOCK_SIZE, ctx->superblock_size); 992 if (ctx->uniform_tiles) { 993 codecctl_int(avctx, AV1E_SET_TILE_COLUMNS, ctx->tile_cols_log2); 994 codecctl_int(avctx, AV1E_SET_TILE_ROWS, ctx->tile_rows_log2); 995 } 996 997 if (ctx->denoise_noise_level >= 0) 998 codecctl_int(avctx, AV1E_SET_DENOISE_NOISE_LEVEL, ctx->denoise_noise_level); 999 if (ctx->denoise_block_size >= 0) 1000 codecctl_int(avctx, AV1E_SET_DENOISE_BLOCK_SIZE, ctx->denoise_block_size); 1001 if (ctx->enable_global_motion >= 0) 1002 codecctl_int(avctx, AV1E_SET_ENABLE_GLOBAL_MOTION, ctx->enable_global_motion); 1003 if (avctx->refs >= 3) { 1004 codecctl_int(avctx, AV1E_SET_MAX_REFERENCE_FRAMES, avctx->refs); 1005 } 1006 if (ctx->row_mt >= 0) 1007 codecctl_int(avctx, AV1E_SET_ROW_MT, ctx->row_mt); 1008 if (ctx->enable_intrabc >= 0) 1009 codecctl_int(avctx, AV1E_SET_ENABLE_INTRABC, ctx->enable_intrabc); 1010 1011 if (enccfg.rc_end_usage == AOM_CBR) { 1012 aom_svc_params_t svc_params = {}; 1013 svc_params.framerate_factor[0] = 1; 1014 svc_params.number_spatial_layers = 1; 1015 svc_params.number_temporal_layers = 1; 1016 1017 AVDictionaryEntry *en = NULL; 1018 while ((en = av_dict_get(ctx->svc_parameters, "", en, AV_DICT_IGNORE_SUFFIX))) { 1019 if (!strlen(en->value)) 1020 return AVERROR(EINVAL); 1021 1022 if (!strcmp(en->key, "number_spatial_layers")) 1023 svc_params.number_spatial_layers = strtoul(en->value, NULL, 10); 1024 else if (!strcmp(en->key, "number_temporal_layers")) 1025 svc_params.number_temporal_layers = strtoul(en->value, NULL, 10); 1026 else if (!strcmp(en->key, "max_quantizers")) 1027 aom_svc_parse_int_array(svc_params.max_quantizers, en->value, AOM_MAX_LAYERS); 1028 else if (!strcmp(en->key, "min_quantizers")) 1029 aom_svc_parse_int_array(svc_params.min_quantizers, en->value, AOM_MAX_LAYERS); 1030 else if (!strcmp(en->key, "scaling_factor_num")) 1031 aom_svc_parse_int_array(svc_params.scaling_factor_num, en->value, AOM_MAX_SS_LAYERS); 1032 else if (!strcmp(en->key, "scaling_factor_den")) 1033 aom_svc_parse_int_array(svc_params.scaling_factor_den, en->value, AOM_MAX_SS_LAYERS); 1034 else if (!strcmp(en->key, "layer_target_bitrate")) 1035 aom_svc_parse_int_array(svc_params.layer_target_bitrate, en->value, AOM_MAX_LAYERS); 1036 else if (!strcmp(en->key, "framerate_factor")) 1037 aom_svc_parse_int_array(svc_params.framerate_factor, en->value, AOM_MAX_TS_LAYERS); 1038 } 1039 1040 res = codecctl_svcp(avctx, AV1E_SET_SVC_PARAMS, &svc_params); 1041 if (res < 0) 1042 return res; 1043 } 1044 1045 1046 #if AOM_ENCODER_ABI_VERSION >= 23 1047 { 1048 const AVDictionaryEntry *en = NULL; 1049 1050 while ((en = av_dict_iterate(ctx->aom_params, en))) { 1051 int ret = aom_codec_set_option(&ctx->encoder, en->key, en->value); 1052 if (ret != AOM_CODEC_OK) { 1053 log_encoder_error(avctx, en->key); 1054 return AVERROR_EXTERNAL; 1055 } 1056 } 1057 } 1058 #endif 1059 1060 // provide dummy value to initialize wrapper, values will be updated each _encode() 1061 aom_img_wrap(&ctx->rawimg, img_fmt, avctx->width, avctx->height, 1, 1062 (unsigned char*)1); 1063 1064 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) 1065 ctx->rawimg.bit_depth = enccfg.g_bit_depth; 1066 1067 cpb_props = ff_encode_add_cpb_side_data(avctx); 1068 if (!cpb_props) 1069 return AVERROR(ENOMEM); 1070 1071 ctx->dovi.logctx = avctx; 1072 if ((res = ff_dovi_configure(&ctx->dovi, avctx)) < 0) 1073 return res; 1074 1075 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { 1076 const AVBitStreamFilter *filter = av_bsf_get_by_name("extract_extradata"); 1077 int ret; 1078 1079 if (!filter) { 1080 av_log(avctx, AV_LOG_ERROR, "extract_extradata bitstream filter " 1081 "not found. This is a bug, please report it.\n"); 1082 return AVERROR_BUG; 1083 } 1084 ret = av_bsf_alloc(filter, &ctx->bsf); 1085 if (ret < 0) 1086 return ret; 1087 1088 ret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx); 1089 if (ret < 0) 1090 return ret; 1091 1092 ret = av_bsf_init(ctx->bsf); 1093 if (ret < 0) 1094 return ret; 1095 } 1096 1097 if (enccfg.rc_end_usage == AOM_CBR || 1098 enccfg.g_pass != AOM_RC_ONE_PASS) { 1099 cpb_props->max_bitrate = avctx->rc_max_rate; 1100 cpb_props->min_bitrate = avctx->rc_min_rate; 1101 cpb_props->avg_bitrate = avctx->bit_rate; 1102 } 1103 cpb_props->buffer_size = avctx->rc_buffer_size; 1104 1105 return 0; 1106 } 1107 1108 static inline void cx_pktcpy(AOMContext *ctx, 1109 struct FrameListData *dst, 1110 const struct aom_codec_cx_pkt *src) 1111 { 1112 dst->pts = src->data.frame.pts; 1113 dst->duration = src->data.frame.duration; 1114 dst->flags = src->data.frame.flags; 1115 dst->sz = src->data.frame.sz; 1116 dst->buf = src->data.frame.buf; 1117 dst->frame_number = ++ctx->frame_number; 1118 dst->have_sse = ctx->have_sse; 1119 if (ctx->have_sse) { 1120 /* associate last-seen SSE to the frame. */ 1121 /* Transfers ownership from ctx to dst. */ 1122 memcpy(dst->sse, ctx->sse, sizeof(dst->sse)); 1123 ctx->have_sse = 0; 1124 } 1125 } 1126 1127 /** 1128 * Store coded frame information in format suitable for return from encode2(). 1129 * 1130 * Write information from @a cx_frame to @a pkt 1131 * @return packet data size on success 1132 * @return a negative AVERROR on error 1133 */ 1134 static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame, 1135 AVPacket *pkt) 1136 { 1137 AOMContext *ctx = avctx->priv_data; 1138 int av_unused pict_type; 1139 int ret = ff_get_encode_buffer(avctx, pkt, cx_frame->sz, 0); 1140 if (ret < 0) { 1141 av_log(avctx, AV_LOG_ERROR, 1142 "Error getting output packet of size %"SIZE_SPECIFIER".\n", cx_frame->sz); 1143 return ret; 1144 } 1145 memcpy(pkt->data, cx_frame->buf, pkt->size); 1146 pkt->pts = pkt->dts = cx_frame->pts; 1147 pkt->duration = cx_frame->duration; 1148 1149 if (!!(cx_frame->flags & AOM_FRAME_IS_KEY)) { 1150 pkt->flags |= AV_PKT_FLAG_KEY; 1151 pict_type = AV_PICTURE_TYPE_I; 1152 } else if (cx_frame->flags & AOM_FRAME_IS_INTRAONLY) { 1153 pict_type = AV_PICTURE_TYPE_I; 1154 } else { 1155 pict_type = AV_PICTURE_TYPE_P; 1156 } 1157 1158 ff_side_data_set_encoder_stats(pkt, 0, cx_frame->sse + 1, 1159 cx_frame->have_sse ? 3 : 0, pict_type); 1160 1161 if (cx_frame->have_sse) { 1162 int i; 1163 for (i = 0; i < 3; ++i) { 1164 avctx->error[i] += cx_frame->sse[i + 1]; 1165 } 1166 cx_frame->have_sse = 0; 1167 } 1168 1169 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { 1170 ret = av_bsf_send_packet(ctx->bsf, pkt); 1171 if (ret < 0) { 1172 av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " 1173 "failed to send input packet\n"); 1174 return ret; 1175 } 1176 ret = av_bsf_receive_packet(ctx->bsf, pkt); 1177 1178 if (ret < 0) { 1179 av_log(avctx, AV_LOG_ERROR, "extract_extradata filter " 1180 "failed to receive output packet\n"); 1181 return ret; 1182 } 1183 } 1184 return pkt->size; 1185 } 1186 1187 /** 1188 * Queue multiple output frames from the encoder, returning the front-most. 1189 * In cases where aom_codec_get_cx_data() returns more than 1 frame append 1190 * the frame queue. Return the head frame if available. 1191 * @return Stored frame size 1192 * @return AVERROR(EINVAL) on output size error 1193 * @return AVERROR(ENOMEM) on coded frame queue data allocation error 1194 */ 1195 static int queue_frames(AVCodecContext *avctx, AVPacket *pkt_out) 1196 { 1197 AOMContext *ctx = avctx->priv_data; 1198 const struct aom_codec_cx_pkt *pkt; 1199 const void *iter = NULL; 1200 int size = 0; 1201 1202 if (ctx->coded_frame_list) { 1203 struct FrameListData *cx_frame = ctx->coded_frame_list; 1204 /* return the leading frame if we've already begun queueing */ 1205 size = storeframe(avctx, cx_frame, pkt_out); 1206 if (size < 0) 1207 return size; 1208 ctx->coded_frame_list = cx_frame->next; 1209 free_coded_frame(cx_frame); 1210 } 1211 1212 /* consume all available output from the encoder before returning. buffers 1213 * are only good through the next aom_codec call */ 1214 while ((pkt = aom_codec_get_cx_data(&ctx->encoder, &iter))) { 1215 switch (pkt->kind) { 1216 case AOM_CODEC_CX_FRAME_PKT: 1217 if (!size) { 1218 struct FrameListData cx_frame; 1219 1220 /* avoid storing the frame when the list is empty and we haven't yet 1221 * provided a frame for output */ 1222 av_assert0(!ctx->coded_frame_list); 1223 cx_pktcpy(ctx, &cx_frame, pkt); 1224 size = storeframe(avctx, &cx_frame, pkt_out); 1225 if (size < 0) 1226 return size; 1227 } else { 1228 struct FrameListData *cx_frame = 1229 av_malloc(sizeof(struct FrameListData)); 1230 1231 if (!cx_frame) { 1232 av_log(avctx, AV_LOG_ERROR, 1233 "Frame queue element alloc failed\n"); 1234 return AVERROR(ENOMEM); 1235 } 1236 cx_pktcpy(ctx, cx_frame, pkt); 1237 cx_frame->buf = av_malloc(cx_frame->sz); 1238 1239 if (!cx_frame->buf) { 1240 av_log(avctx, AV_LOG_ERROR, 1241 "Data buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n", 1242 cx_frame->sz); 1243 av_freep(&cx_frame); 1244 return AVERROR(ENOMEM); 1245 } 1246 memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); 1247 coded_frame_add(&ctx->coded_frame_list, cx_frame); 1248 } 1249 break; 1250 case AOM_CODEC_STATS_PKT: 1251 { 1252 struct aom_fixed_buf *stats = &ctx->twopass_stats; 1253 uint8_t *tmp = av_fast_realloc(stats->buf, 1254 &ctx->twopass_stats_size, 1255 stats->sz + 1256 pkt->data.twopass_stats.sz); 1257 if (!tmp) { 1258 av_freep(&stats->buf); 1259 stats->sz = 0; 1260 av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); 1261 return AVERROR(ENOMEM); 1262 } 1263 stats->buf = tmp; 1264 memcpy((uint8_t *)stats->buf + stats->sz, 1265 pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz); 1266 stats->sz += pkt->data.twopass_stats.sz; 1267 break; 1268 } 1269 case AOM_CODEC_PSNR_PKT: 1270 { 1271 av_assert0(!ctx->have_sse); 1272 ctx->sse[0] = pkt->data.psnr.sse[0]; 1273 ctx->sse[1] = pkt->data.psnr.sse[1]; 1274 ctx->sse[2] = pkt->data.psnr.sse[2]; 1275 ctx->sse[3] = pkt->data.psnr.sse[3]; 1276 ctx->have_sse = 1; 1277 break; 1278 } 1279 case AOM_CODEC_CUSTOM_PKT: 1280 // ignore unsupported/unrecognized packet types 1281 break; 1282 } 1283 } 1284 1285 return size; 1286 } 1287 1288 static enum AVPixelFormat aomfmt_to_pixfmt(struct aom_image *img) 1289 { 1290 switch (img->fmt) { 1291 case AOM_IMG_FMT_I420: 1292 case AOM_IMG_FMT_I42016: 1293 if (img->bit_depth == 8) 1294 return img->monochrome ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_YUV420P; 1295 else if (img->bit_depth == 10) 1296 return img->monochrome ? AV_PIX_FMT_GRAY10 : AV_PIX_FMT_YUV420P10; 1297 else 1298 return img->monochrome ? AV_PIX_FMT_GRAY12 : AV_PIX_FMT_YUV420P12; 1299 case AOM_IMG_FMT_I422: 1300 case AOM_IMG_FMT_I42216: 1301 if (img->bit_depth == 8) 1302 return AV_PIX_FMT_YUV422P; 1303 else if (img->bit_depth == 10) 1304 return AV_PIX_FMT_YUV422P10; 1305 else 1306 return AV_PIX_FMT_YUV422P12; 1307 case AOM_IMG_FMT_I444: 1308 case AOM_IMG_FMT_I44416: 1309 if (img->bit_depth == 8) 1310 return AV_PIX_FMT_YUV444P; 1311 else if (img->bit_depth == 10) 1312 return AV_PIX_FMT_YUV444P10; 1313 else 1314 return AV_PIX_FMT_YUV444P12; 1315 }; 1316 return AV_PIX_FMT_NONE; 1317 } 1318 1319 static int aom_encode(AVCodecContext *avctx, AVPacket *pkt, 1320 const AVFrame *frame, int *got_packet) 1321 { 1322 AOMContext *ctx = avctx->priv_data; 1323 struct aom_image *rawimg = NULL; 1324 int64_t timestamp = 0; 1325 unsigned long duration = 0; 1326 int res, coded_size; 1327 aom_enc_frame_flags_t flags = 0; 1328 AVFrameSideData *sd; 1329 1330 if (frame) { 1331 rawimg = &ctx->rawimg; 1332 rawimg->planes[AOM_PLANE_Y] = frame->data[0]; 1333 rawimg->planes[AOM_PLANE_U] = frame->data[1]; 1334 rawimg->planes[AOM_PLANE_V] = frame->data[2]; 1335 rawimg->stride[AOM_PLANE_Y] = frame->linesize[0]; 1336 rawimg->stride[AOM_PLANE_U] = frame->linesize[1]; 1337 rawimg->stride[AOM_PLANE_V] = frame->linesize[2]; 1338 timestamp = frame->pts; 1339 1340 if (frame->duration > ULONG_MAX) { 1341 av_log(avctx, AV_LOG_WARNING, 1342 "Frame duration too large: %"PRId64"\n", frame->duration); 1343 } else if (frame->duration) 1344 duration = frame->duration; 1345 else if (avctx->framerate.num > 0 && avctx->framerate.den > 0) 1346 duration = av_rescale_q(1, av_inv_q(avctx->framerate), avctx->time_base); 1347 else { 1348 FF_DISABLE_DEPRECATION_WARNINGS 1349 duration = 1350 #if FF_API_TICKS_PER_FRAME 1351 avctx->ticks_per_frame ? avctx->ticks_per_frame : 1352 #endif 1353 1; 1354 FF_ENABLE_DEPRECATION_WARNINGS 1355 } 1356 1357 switch (frame->color_range) { 1358 case AVCOL_RANGE_MPEG: 1359 rawimg->range = AOM_CR_STUDIO_RANGE; 1360 break; 1361 case AVCOL_RANGE_JPEG: 1362 rawimg->range = AOM_CR_FULL_RANGE; 1363 break; 1364 } 1365 1366 aom_img_remove_metadata(rawimg); 1367 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOVI_METADATA); 1368 if (ctx->dovi.cfg.dv_profile && sd) { 1369 const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data; 1370 uint8_t *t35; 1371 int size; 1372 if ((res = ff_dovi_rpu_generate(&ctx->dovi, metadata, FF_DOVI_WRAP_T35, 1373 &t35, &size)) < 0) 1374 return res; 1375 res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35, 1376 t35, size, AOM_MIF_ANY_FRAME); 1377 av_free(t35); 1378 if (res != AOM_CODEC_OK) 1379 return AVERROR(ENOMEM); 1380 } else if (ctx->dovi.cfg.dv_profile) { 1381 av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received frame " 1382 "without AV_FRAME_DATA_DOVI_METADATA\n"); 1383 return AVERROR_INVALIDDATA; 1384 } 1385 1386 if (frame->pict_type == AV_PICTURE_TYPE_I) 1387 flags |= AOM_EFLAG_FORCE_KF; 1388 1389 AVDictionaryEntry* en = av_dict_get(frame->metadata, "temporal_id", NULL, 0); 1390 if (en) { 1391 aom_svc_layer_id_t layer_id = {}; 1392 layer_id.temporal_layer_id = strtoul(en->value, NULL, 10); 1393 av_log(avctx, AV_LOG_DEBUG, "Frame pts % " PRId64 " temporal layer id %d", 1394 frame->pts, layer_id.temporal_layer_id); 1395 if (!ctx->svc_parameters) { 1396 av_log(avctx, AV_LOG_WARNING, 1397 "Temporal SVC not enabled, but temporal layer id received."); 1398 } 1399 res = aom_codec_control(&ctx->encoder, AV1E_SET_SVC_LAYER_ID, &layer_id); 1400 if (res != AOM_CODEC_OK) { 1401 av_log(avctx, AV_LOG_ERROR, 1402 "Error setting temporal layer id %d on frame pts % " PRId64 "\n", 1403 layer_id.temporal_layer_id, frame->pts); 1404 return res; 1405 } 1406 } 1407 } 1408 1409 res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, flags); 1410 if (res != AOM_CODEC_OK) { 1411 log_encoder_error(avctx, "Error encoding frame"); 1412 return AVERROR_INVALIDDATA; 1413 } 1414 coded_size = queue_frames(avctx, pkt); 1415 if (coded_size < 0) 1416 return coded_size; 1417 1418 if (!frame && avctx->flags & AV_CODEC_FLAG_PASS1) { 1419 size_t b64_size = AV_BASE64_SIZE(ctx->twopass_stats.sz); 1420 1421 avctx->stats_out = av_malloc(b64_size); 1422 if (!avctx->stats_out) { 1423 av_log(avctx, AV_LOG_ERROR, "Stat buffer alloc (%"SIZE_SPECIFIER" bytes) failed\n", 1424 b64_size); 1425 return AVERROR(ENOMEM); 1426 } 1427 av_base64_encode(avctx->stats_out, b64_size, ctx->twopass_stats.buf, 1428 ctx->twopass_stats.sz); 1429 } 1430 1431 *got_packet = !!coded_size; 1432 1433 if (*got_packet && avctx->flags & AV_CODEC_FLAG_RECON_FRAME) { 1434 AVCodecInternal *avci = avctx->internal; 1435 struct aom_image img; 1436 1437 av_frame_unref(avci->recon_frame); 1438 1439 res = codecctl_imgp(avctx, AV1_GET_NEW_FRAME_IMAGE, &img); 1440 if (res < 0) 1441 return res; 1442 1443 avci->recon_frame->format = aomfmt_to_pixfmt(&img); 1444 if (avci->recon_frame->format == AV_PIX_FMT_NONE) { 1445 av_log(ctx, AV_LOG_ERROR, 1446 "Unhandled reconstructed frame colorspace: %d\n", 1447 img.fmt); 1448 return AVERROR(ENOSYS); 1449 } 1450 1451 avci->recon_frame->width = img.d_w; 1452 avci->recon_frame->height = img.d_h; 1453 1454 res = av_frame_get_buffer(avci->recon_frame, 0); 1455 if (res < 0) 1456 return res; 1457 1458 if ((img.fmt & AOM_IMG_FMT_HIGHBITDEPTH) && img.bit_depth == 8) 1459 ff_aom_image_copy_16_to_8(avci->recon_frame, &img); 1460 else { 1461 const uint8_t *planes[4] = { img.planes[0], img.planes[1], img.planes[2] }; 1462 const int stride[4] = { img.stride[0], img.stride[1], img.stride[2] }; 1463 1464 av_image_copy(avci->recon_frame->data, avci->recon_frame->linesize, planes, 1465 stride, avci->recon_frame->format, img.d_w, img.d_h); 1466 } 1467 } 1468 1469 return 0; 1470 } 1471 1472 static const enum AVPixelFormat av1_pix_fmts[] = { 1473 AV_PIX_FMT_YUV420P, 1474 AV_PIX_FMT_YUV422P, 1475 AV_PIX_FMT_YUV444P, 1476 AV_PIX_FMT_GBRP, 1477 AV_PIX_FMT_NONE 1478 }; 1479 1480 static const enum AVPixelFormat av1_pix_fmts_with_gray[] = { 1481 AV_PIX_FMT_YUV420P, 1482 AV_PIX_FMT_YUV422P, 1483 AV_PIX_FMT_YUV444P, 1484 AV_PIX_FMT_GBRP, 1485 AV_PIX_FMT_GRAY8, 1486 AV_PIX_FMT_NONE 1487 }; 1488 1489 static const enum AVPixelFormat av1_pix_fmts_highbd[] = { 1490 AV_PIX_FMT_YUV420P, 1491 AV_PIX_FMT_YUV422P, 1492 AV_PIX_FMT_YUV444P, 1493 AV_PIX_FMT_GBRP, 1494 AV_PIX_FMT_YUV420P10, 1495 AV_PIX_FMT_YUV422P10, 1496 AV_PIX_FMT_YUV444P10, 1497 AV_PIX_FMT_YUV420P12, 1498 AV_PIX_FMT_YUV422P12, 1499 AV_PIX_FMT_YUV444P12, 1500 AV_PIX_FMT_GBRP10, 1501 AV_PIX_FMT_GBRP12, 1502 AV_PIX_FMT_NONE 1503 }; 1504 1505 static const enum AVPixelFormat av1_pix_fmts_highbd_with_gray[] = { 1506 AV_PIX_FMT_YUV420P, 1507 AV_PIX_FMT_YUV422P, 1508 AV_PIX_FMT_YUV444P, 1509 AV_PIX_FMT_GBRP, 1510 AV_PIX_FMT_YUV420P10, 1511 AV_PIX_FMT_YUV422P10, 1512 AV_PIX_FMT_YUV444P10, 1513 AV_PIX_FMT_YUV420P12, 1514 AV_PIX_FMT_YUV422P12, 1515 AV_PIX_FMT_YUV444P12, 1516 AV_PIX_FMT_GBRP10, 1517 AV_PIX_FMT_GBRP12, 1518 AV_PIX_FMT_GRAY8, 1519 AV_PIX_FMT_GRAY10, 1520 AV_PIX_FMT_GRAY12, 1521 AV_PIX_FMT_NONE 1522 }; 1523 1524 static int av1_get_supported_config(const AVCodecContext *avctx, 1525 const AVCodec *codec, 1526 enum AVCodecConfig config, 1527 unsigned flags, const void **out, 1528 int *out_num) 1529 { 1530 if (config == AV_CODEC_CONFIG_PIX_FORMAT) { 1531 int supports_monochrome = aom_codec_version() >= 20001; 1532 aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx()); 1533 if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH) { 1534 if (supports_monochrome) { 1535 *out = av1_pix_fmts_highbd_with_gray; 1536 *out_num = FF_ARRAY_ELEMS(av1_pix_fmts_highbd_with_gray) - 1; 1537 } else { 1538 *out = av1_pix_fmts_highbd; 1539 *out_num = FF_ARRAY_ELEMS(av1_pix_fmts_highbd) - 1; 1540 } 1541 } else { 1542 if (supports_monochrome) { 1543 *out = av1_pix_fmts_with_gray; 1544 *out_num = FF_ARRAY_ELEMS(av1_pix_fmts_with_gray) - 1; 1545 } else { 1546 *out = av1_pix_fmts; 1547 *out_num = FF_ARRAY_ELEMS(av1_pix_fmts) - 1; 1548 } 1549 } 1550 return 0; 1551 } 1552 1553 return ff_default_get_supported_config(avctx, codec, config, flags, out, out_num); 1554 } 1555 1556 static av_cold int av1_init(AVCodecContext *avctx) 1557 { 1558 return aom_init(avctx, aom_codec_av1_cx()); 1559 } 1560 1561 #define OFFSET(x) offsetof(AOMContext, x) 1562 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1563 static const AVOption options[] = { 1564 { "cpu-used", "Quality/Speed ratio modifier", OFFSET(cpu_used), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 8, VE}, 1565 { "auto-alt-ref", "Enable use of alternate reference " 1566 "frames (2-pass only)", OFFSET(auto_alt_ref), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, VE}, 1567 { "lag-in-frames", "Number of frames to look ahead at for " 1568 "alternate reference frame selection", OFFSET(lag_in_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, 1569 { "arnr-max-frames", "altref noise reduction max frame count", OFFSET(arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, 1570 { "arnr-strength", "altref noise reduction filter strength", OFFSET(arnr_strength), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE}, 1571 { "aq-mode", "adaptive quantization mode", OFFSET(aq_mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 4, VE, .unit = "aq_mode"}, 1572 { "none", "Aq not used", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, VE, .unit = "aq_mode"}, 1573 { "variance", "Variance based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, VE, .unit = "aq_mode"}, 1574 { "complexity", "Complexity based Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, VE, .unit = "aq_mode"}, 1575 { "cyclic", "Cyclic Refresh Aq", 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 0, VE, .unit = "aq_mode"}, 1576 { "error-resilience", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, .unit = "er"}, 1577 { "default", "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = AOM_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, .unit = "er"}, 1578 { "crf", "Select the quality for constant quality mode", offsetof(AOMContext, crf), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, VE }, 1579 { "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 }, 1580 { "drop-threshold", "Frame drop threshold", offsetof(AOMContext, drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE }, 1581 { "denoise-noise-level", "Amount of noise to be removed", OFFSET(denoise_noise_level), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, 1582 { "denoise-block-size", "Denoise block size ", OFFSET(denoise_block_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, VE}, 1583 { "undershoot-pct", "Datarate undershoot (min) target (%)", OFFSET(rc_undershoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE}, 1584 { "overshoot-pct", "Datarate overshoot (max) target (%)", OFFSET(rc_overshoot_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1000, VE}, 1585 { "minsection-pct", "GOP min bitrate (% of target)", OFFSET(minsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 100, VE}, 1586 { "maxsection-pct", "GOP max bitrate (% of target)", OFFSET(maxsection_pct), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 5000, VE}, 1587 { "frame-parallel", "Enable frame parallel decodability features", OFFSET(frame_parallel), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1588 { "tiles", "Tile columns x rows", OFFSET(tile_cols), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, VE }, 1589 { "tile-columns", "Log2 of number of tile columns to use", OFFSET(tile_cols_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE}, 1590 { "tile-rows", "Log2 of number of tile rows to use", OFFSET(tile_rows_log2), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 6, VE}, 1591 { "row-mt", "Enable row based multi-threading", OFFSET(row_mt), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1592 { "enable-cdef", "Enable CDEF filtering", OFFSET(enable_cdef), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1593 { "enable-global-motion", "Enable global motion", OFFSET(enable_global_motion), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1594 { "enable-intrabc", "Enable intra block copy prediction mode", OFFSET(enable_intrabc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1595 { "enable-restoration", "Enable Loop Restoration filtering", OFFSET(enable_restoration), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1596 { "usage", "Quality and compression efficiency vs speed trade-off", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, VE, .unit = "usage"}, 1597 { "good", "Good quality", 0, AV_OPT_TYPE_CONST, {.i64 = 0 /* AOM_USAGE_GOOD_QUALITY */}, 0, 0, VE, .unit = "usage"}, 1598 { "realtime", "Realtime encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 1 /* AOM_USAGE_REALTIME */}, 0, 0, VE, .unit = "usage"}, 1599 { "allintra", "All Intra encoding", 0, AV_OPT_TYPE_CONST, {.i64 = 2 /* AOM_USAGE_ALL_INTRA */}, 0, 0, VE, .unit = "usage"}, 1600 { "tune", "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, .unit = "tune"}, 1601 { "psnr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, .unit = "tune"}, 1602 { "ssim", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, .unit = "tune"}, 1603 FF_AV1_PROFILE_OPTS 1604 { "still-picture", "Encode in single frame mode (typically used for still AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, VE }, 1605 { "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" }, 1606 { "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags = VE, .unit = "dovi" }, 1607 { "enable-rect-partitions", "Enable rectangular partitions", OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1608 { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1609 { "enable-ab-partitions", "Enable ab shape partitions", OFFSET(enable_ab_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1610 { "enable-angle-delta", "Enable angle delta intra prediction", OFFSET(enable_angle_delta), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1611 { "enable-cfl-intra", "Enable chroma predicted from luma intra prediction", OFFSET(enable_cfl_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1612 { "enable-filter-intra", "Enable filter intra predictor", OFFSET(enable_filter_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1613 { "enable-intra-edge-filter", "Enable intra edge filter", OFFSET(enable_intra_edge_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1614 { "enable-smooth-intra", "Enable smooth intra prediction mode", OFFSET(enable_smooth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1615 { "enable-paeth-intra", "Enable paeth predictor in intra prediction", OFFSET(enable_paeth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1616 { "enable-palette", "Enable palette prediction mode", OFFSET(enable_palette), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1617 { "enable-flip-idtx", "Enable extended transform type", OFFSET(enable_flip_idtx), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1618 { "enable-tx64", "Enable 64-pt transform", OFFSET(enable_tx64), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1619 { "reduced-tx-type-set", "Use reduced set of transform types", OFFSET(reduced_tx_type_set), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1620 { "use-intra-dct-only", "Use DCT only for INTRA modes", OFFSET(use_intra_dct_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1621 { "use-inter-dct-only", "Use DCT only for INTER modes", OFFSET(use_inter_dct_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1622 { "use-intra-default-tx-only", "Use default-transform only for INTRA modes", OFFSET(use_intra_default_tx_only), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1623 { "enable-ref-frame-mvs", "Enable temporal mv prediction", OFFSET(enable_ref_frame_mvs), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1624 { "enable-reduced-reference-set", "Use reduced set of single and compound references", OFFSET(enable_reduced_reference_set), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1625 { "enable-obmc", "Enable obmc", OFFSET(enable_obmc), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1626 { "enable-dual-filter", "Enable dual filter", OFFSET(enable_dual_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1627 { "enable-diff-wtd-comp", "Enable difference-weighted compound", OFFSET(enable_diff_wtd_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1628 { "enable-dist-wtd-comp", "Enable distance-weighted compound", OFFSET(enable_dist_wtd_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1629 { "enable-onesided-comp", "Enable one sided compound", OFFSET(enable_onesided_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1630 { "enable-interinter-wedge", "Enable interinter wedge compound", OFFSET(enable_interinter_wedge), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1631 { "enable-interintra-wedge", "Enable interintra wedge compound", OFFSET(enable_interintra_wedge), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1632 { "enable-masked-comp", "Enable masked compound", OFFSET(enable_masked_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1633 { "enable-interintra-comp", "Enable interintra compound", OFFSET(enable_interintra_comp), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1634 { "enable-smooth-interintra", "Enable smooth interintra mode", OFFSET(enable_smooth_interintra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, 1635 { "svc-parameters", "SVC configuration using a :-separated list of key=value parameters (only applied in CBR mode)", OFFSET(svc_parameters), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE}, 1636 #if AOM_ENCODER_ABI_VERSION >= 23 1637 { "aom-params", "Set libaom options using a :-separated list of key=value pairs", OFFSET(aom_params), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, 1638 #endif 1639 { NULL }, 1640 }; 1641 1642 static const FFCodecDefault defaults[] = { 1643 { "b", "0" }, 1644 { "qmin", "-1" }, 1645 { "qmax", "-1" }, 1646 { "g", "-1" }, 1647 { "keyint_min", "-1" }, 1648 { NULL }, 1649 }; 1650 1651 static const AVClass class_aom = { 1652 .class_name = "libaom-av1 encoder", 1653 .item_name = av_default_item_name, 1654 .option = options, 1655 .version = LIBAVUTIL_VERSION_INT, 1656 }; 1657 1658 FFCodec ff_libaom_av1_encoder = { 1659 .p.name = "libaom-av1", 1660 CODEC_LONG_NAME("libaom AV1"), 1661 .p.type = AVMEDIA_TYPE_VIDEO, 1662 .p.id = AV_CODEC_ID_AV1, 1663 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | 1664 AV_CODEC_CAP_ENCODER_RECON_FRAME | 1665 AV_CODEC_CAP_OTHER_THREADS, 1666 .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, 1667 .p.profiles = NULL_IF_CONFIG_SMALL(ff_av1_profiles), 1668 .p.priv_class = &class_aom, 1669 .p.wrapper_name = "libaom", 1670 .priv_data_size = sizeof(AOMContext), 1671 .init = av1_init, 1672 FF_CODEC_ENCODE_CB(aom_encode), 1673 .close = aom_free, 1674 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | 1675 FF_CODEC_CAP_INIT_CLEANUP | 1676 FF_CODEC_CAP_AUTO_THREADS, 1677 .defaults = defaults, 1678 .get_supported_config = av1_get_supported_config, 1679 };