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