1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Scalable Video Technology for AV1 encoder library plugin 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (c) 2018 Intel Corporation 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with this program; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include <stdint.h> 24cabdff1aSopenharmony_ci#include <EbSvtAv1ErrorCodes.h> 25cabdff1aSopenharmony_ci#include <EbSvtAv1Enc.h> 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "libavutil/common.h" 28cabdff1aSopenharmony_ci#include "libavutil/frame.h" 29cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 30cabdff1aSopenharmony_ci#include "libavutil/opt.h" 31cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 32cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci#include "codec_internal.h" 35cabdff1aSopenharmony_ci#include "internal.h" 36cabdff1aSopenharmony_ci#include "encode.h" 37cabdff1aSopenharmony_ci#include "packet_internal.h" 38cabdff1aSopenharmony_ci#include "avcodec.h" 39cabdff1aSopenharmony_ci#include "profiles.h" 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_citypedef enum eos_status { 42cabdff1aSopenharmony_ci EOS_NOT_REACHED = 0, 43cabdff1aSopenharmony_ci EOS_SENT, 44cabdff1aSopenharmony_ci EOS_RECEIVED 45cabdff1aSopenharmony_ci}EOS_STATUS; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_citypedef struct SvtContext { 48cabdff1aSopenharmony_ci const AVClass *class; 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_ci EbSvtAv1EncConfiguration enc_params; 51cabdff1aSopenharmony_ci EbComponentType *svt_handle; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci EbBufferHeaderType *in_buf; 54cabdff1aSopenharmony_ci int raw_size; 55cabdff1aSopenharmony_ci int max_tu_size; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci AVFrame *frame; 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci AVBufferPool *pool; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci EOS_STATUS eos_flag; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci // User options. 64cabdff1aSopenharmony_ci AVDictionary *svtav1_opts; 65cabdff1aSopenharmony_ci#if FF_API_SVTAV1_OPTS 66cabdff1aSopenharmony_ci int hierarchical_level; 67cabdff1aSopenharmony_ci int la_depth; 68cabdff1aSopenharmony_ci int scd; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci int tier; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci int tile_columns; 73cabdff1aSopenharmony_ci int tile_rows; 74cabdff1aSopenharmony_ci#endif 75cabdff1aSopenharmony_ci int enc_mode; 76cabdff1aSopenharmony_ci int crf; 77cabdff1aSopenharmony_ci int qp; 78cabdff1aSopenharmony_ci} SvtContext; 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_cistatic const struct { 81cabdff1aSopenharmony_ci EbErrorType eb_err; 82cabdff1aSopenharmony_ci int av_err; 83cabdff1aSopenharmony_ci const char *desc; 84cabdff1aSopenharmony_ci} svt_errors[] = { 85cabdff1aSopenharmony_ci { EB_ErrorNone, 0, "success" }, 86cabdff1aSopenharmony_ci { EB_ErrorInsufficientResources, AVERROR(ENOMEM), "insufficient resources" }, 87cabdff1aSopenharmony_ci { EB_ErrorUndefined, AVERROR(EINVAL), "undefined error" }, 88cabdff1aSopenharmony_ci { EB_ErrorInvalidComponent, AVERROR(EINVAL), "invalid component" }, 89cabdff1aSopenharmony_ci { EB_ErrorBadParameter, AVERROR(EINVAL), "bad parameter" }, 90cabdff1aSopenharmony_ci { EB_ErrorDestroyThreadFailed, AVERROR_EXTERNAL, "failed to destroy thread" }, 91cabdff1aSopenharmony_ci { EB_ErrorSemaphoreUnresponsive, AVERROR_EXTERNAL, "semaphore unresponsive" }, 92cabdff1aSopenharmony_ci { EB_ErrorDestroySemaphoreFailed, AVERROR_EXTERNAL, "failed to destroy semaphore"}, 93cabdff1aSopenharmony_ci { EB_ErrorCreateMutexFailed, AVERROR_EXTERNAL, "failed to create mutex" }, 94cabdff1aSopenharmony_ci { EB_ErrorMutexUnresponsive, AVERROR_EXTERNAL, "mutex unresponsive" }, 95cabdff1aSopenharmony_ci { EB_ErrorDestroyMutexFailed, AVERROR_EXTERNAL, "failed to destroy mutex" }, 96cabdff1aSopenharmony_ci { EB_NoErrorEmptyQueue, AVERROR(EAGAIN), "empty queue" }, 97cabdff1aSopenharmony_ci}; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_cistatic int svt_map_error(EbErrorType eb_err, const char **desc) 100cabdff1aSopenharmony_ci{ 101cabdff1aSopenharmony_ci int i; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci av_assert0(desc); 104cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(svt_errors); i++) { 105cabdff1aSopenharmony_ci if (svt_errors[i].eb_err == eb_err) { 106cabdff1aSopenharmony_ci *desc = svt_errors[i].desc; 107cabdff1aSopenharmony_ci return svt_errors[i].av_err; 108cabdff1aSopenharmony_ci } 109cabdff1aSopenharmony_ci } 110cabdff1aSopenharmony_ci *desc = "unknown error"; 111cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 112cabdff1aSopenharmony_ci} 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_cistatic int svt_print_error(void *log_ctx, EbErrorType err, 115cabdff1aSopenharmony_ci const char *error_string) 116cabdff1aSopenharmony_ci{ 117cabdff1aSopenharmony_ci const char *desc; 118cabdff1aSopenharmony_ci int ret = svt_map_error(err, &desc); 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci av_log(log_ctx, AV_LOG_ERROR, "%s: %s (0x%x)\n", error_string, desc, err); 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci return ret; 123cabdff1aSopenharmony_ci} 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_cistatic int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc) 126cabdff1aSopenharmony_ci{ 127cabdff1aSopenharmony_ci const size_t luma_size = config->source_width * config->source_height * 128cabdff1aSopenharmony_ci (config->encoder_bit_depth > 8 ? 2 : 1); 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci EbSvtIOFormat *in_data; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci svt_enc->raw_size = luma_size * 3 / 2; 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci // allocate buffer for in and out 135cabdff1aSopenharmony_ci svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); 136cabdff1aSopenharmony_ci if (!svt_enc->in_buf) 137cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci svt_enc->in_buf->p_buffer = av_mallocz(sizeof(*in_data)); 140cabdff1aSopenharmony_ci if (!svt_enc->in_buf->p_buffer) 141cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci svt_enc->in_buf->size = sizeof(*svt_enc->in_buf); 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci return 0; 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci} 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_cistatic int config_enc_params(EbSvtAv1EncConfiguration *param, 150cabdff1aSopenharmony_ci AVCodecContext *avctx) 151cabdff1aSopenharmony_ci{ 152cabdff1aSopenharmony_ci SvtContext *svt_enc = avctx->priv_data; 153cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc; 154cabdff1aSopenharmony_ci AVDictionaryEntry *en = NULL; 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_ci // Update param from options 157cabdff1aSopenharmony_ci#if FF_API_SVTAV1_OPTS 158cabdff1aSopenharmony_ci param->hierarchical_levels = svt_enc->hierarchical_level; 159cabdff1aSopenharmony_ci param->tier = svt_enc->tier; 160cabdff1aSopenharmony_ci param->scene_change_detection = svt_enc->scd; 161cabdff1aSopenharmony_ci param->tile_columns = svt_enc->tile_columns; 162cabdff1aSopenharmony_ci param->tile_rows = svt_enc->tile_rows; 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci if (svt_enc->la_depth >= 0) 165cabdff1aSopenharmony_ci param->look_ahead_distance = svt_enc->la_depth; 166cabdff1aSopenharmony_ci#endif 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci if (svt_enc->enc_mode >= 0) 169cabdff1aSopenharmony_ci param->enc_mode = svt_enc->enc_mode; 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci if (avctx->bit_rate) { 172cabdff1aSopenharmony_ci param->target_bit_rate = avctx->bit_rate; 173cabdff1aSopenharmony_ci if (avctx->rc_max_rate != avctx->bit_rate) 174cabdff1aSopenharmony_ci param->rate_control_mode = 1; 175cabdff1aSopenharmony_ci else 176cabdff1aSopenharmony_ci param->rate_control_mode = 2; 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci param->max_qp_allowed = avctx->qmax; 179cabdff1aSopenharmony_ci param->min_qp_allowed = avctx->qmin; 180cabdff1aSopenharmony_ci } 181cabdff1aSopenharmony_ci param->max_bit_rate = avctx->rc_max_rate; 182cabdff1aSopenharmony_ci if ((avctx->bit_rate > 0 || avctx->rc_max_rate > 0) && avctx->rc_buffer_size) 183cabdff1aSopenharmony_ci param->maximum_buffer_size_ms = 184cabdff1aSopenharmony_ci avctx->rc_buffer_size * 1000LL / 185cabdff1aSopenharmony_ci FFMAX(avctx->bit_rate, avctx->rc_max_rate); 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci if (svt_enc->crf > 0) { 188cabdff1aSopenharmony_ci param->qp = svt_enc->crf; 189cabdff1aSopenharmony_ci param->rate_control_mode = 0; 190cabdff1aSopenharmony_ci } else if (svt_enc->qp > 0) { 191cabdff1aSopenharmony_ci param->qp = svt_enc->qp; 192cabdff1aSopenharmony_ci param->rate_control_mode = 0; 193cabdff1aSopenharmony_ci param->enable_adaptive_quantization = 0; 194cabdff1aSopenharmony_ci } 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_ci desc = av_pix_fmt_desc_get(avctx->pix_fmt); 197cabdff1aSopenharmony_ci param->color_primaries = avctx->color_primaries; 198cabdff1aSopenharmony_ci param->matrix_coefficients = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? 199cabdff1aSopenharmony_ci AVCOL_SPC_RGB : avctx->colorspace; 200cabdff1aSopenharmony_ci param->transfer_characteristics = avctx->color_trc; 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED) 203cabdff1aSopenharmony_ci param->color_range = avctx->color_range == AVCOL_RANGE_JPEG; 204cabdff1aSopenharmony_ci else 205cabdff1aSopenharmony_ci param->color_range = !!(desc->flags & AV_PIX_FMT_FLAG_RGB); 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci#if SVT_AV1_CHECK_VERSION(1, 0, 0) 208cabdff1aSopenharmony_ci if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { 209cabdff1aSopenharmony_ci const char *name = 210cabdff1aSopenharmony_ci av_chroma_location_name(avctx->chroma_sample_location); 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci switch (avctx->chroma_sample_location) { 213cabdff1aSopenharmony_ci case AVCHROMA_LOC_LEFT: 214cabdff1aSopenharmony_ci param->chroma_sample_position = EB_CSP_VERTICAL; 215cabdff1aSopenharmony_ci break; 216cabdff1aSopenharmony_ci case AVCHROMA_LOC_TOPLEFT: 217cabdff1aSopenharmony_ci param->chroma_sample_position = EB_CSP_COLOCATED; 218cabdff1aSopenharmony_ci break; 219cabdff1aSopenharmony_ci default: 220cabdff1aSopenharmony_ci if (!name) 221cabdff1aSopenharmony_ci break; 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, 224cabdff1aSopenharmony_ci "Specified chroma sample location %s is unsupported " 225cabdff1aSopenharmony_ci "on the AV1 bit stream level. Usage of a container that " 226cabdff1aSopenharmony_ci "allows passing this information - such as Matroska - " 227cabdff1aSopenharmony_ci "is recommended.\n", 228cabdff1aSopenharmony_ci name); 229cabdff1aSopenharmony_ci break; 230cabdff1aSopenharmony_ci } 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci#endif 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci if (avctx->profile != FF_PROFILE_UNKNOWN) 235cabdff1aSopenharmony_ci param->profile = avctx->profile; 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci if (avctx->level != FF_LEVEL_UNKNOWN) 238cabdff1aSopenharmony_ci param->level = avctx->level; 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_ci if (avctx->gop_size > 0) 241cabdff1aSopenharmony_ci param->intra_period_length = avctx->gop_size - 1; 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { 244cabdff1aSopenharmony_ci param->frame_rate_numerator = avctx->framerate.num; 245cabdff1aSopenharmony_ci param->frame_rate_denominator = avctx->framerate.den; 246cabdff1aSopenharmony_ci } else { 247cabdff1aSopenharmony_ci param->frame_rate_numerator = avctx->time_base.den; 248cabdff1aSopenharmony_ci param->frame_rate_denominator = avctx->time_base.num * avctx->ticks_per_frame; 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci /* 2 = IDR, closed GOP, 1 = CRA, open GOP */ 252cabdff1aSopenharmony_ci param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1; 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci#if SVT_AV1_CHECK_VERSION(0, 9, 1) 255cabdff1aSopenharmony_ci while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) { 256cabdff1aSopenharmony_ci EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value); 257cabdff1aSopenharmony_ci if (ret != EB_ErrorNone) { 258cabdff1aSopenharmony_ci int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING; 259cabdff1aSopenharmony_ci av_log(avctx, level, "Error parsing option %s: %s.\n", en->key, en->value); 260cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 261cabdff1aSopenharmony_ci return AVERROR(EINVAL); 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci#else 265cabdff1aSopenharmony_ci if ((en = av_dict_get(svt_enc->svtav1_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { 266cabdff1aSopenharmony_ci int level = (avctx->err_recognition & AV_EF_EXPLODE) ? AV_LOG_ERROR : AV_LOG_WARNING; 267cabdff1aSopenharmony_ci av_log(avctx, level, "svt-params needs libavcodec to be compiled with SVT-AV1 " 268cabdff1aSopenharmony_ci "headers >= 0.9.1.\n"); 269cabdff1aSopenharmony_ci if (avctx->err_recognition & AV_EF_EXPLODE) 270cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci#endif 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci param->source_width = avctx->width; 275cabdff1aSopenharmony_ci param->source_height = avctx->height; 276cabdff1aSopenharmony_ci 277cabdff1aSopenharmony_ci param->encoder_bit_depth = desc->comp[0].depth; 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 1) 280cabdff1aSopenharmony_ci param->encoder_color_format = EB_YUV420; 281cabdff1aSopenharmony_ci else if (desc->log2_chroma_w == 1 && desc->log2_chroma_h == 0) 282cabdff1aSopenharmony_ci param->encoder_color_format = EB_YUV422; 283cabdff1aSopenharmony_ci else if (!desc->log2_chroma_w && !desc->log2_chroma_h) 284cabdff1aSopenharmony_ci param->encoder_color_format = EB_YUV444; 285cabdff1aSopenharmony_ci else { 286cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR , "Unsupported pixel format\n"); 287cabdff1aSopenharmony_ci return AVERROR(EINVAL); 288cabdff1aSopenharmony_ci } 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci if ((param->encoder_color_format == EB_YUV422 || param->encoder_bit_depth > 10) 291cabdff1aSopenharmony_ci && param->profile != FF_PROFILE_AV1_PROFESSIONAL ) { 292cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Forcing Professional profile\n"); 293cabdff1aSopenharmony_ci param->profile = FF_PROFILE_AV1_PROFESSIONAL; 294cabdff1aSopenharmony_ci } else if (param->encoder_color_format == EB_YUV444 && param->profile != FF_PROFILE_AV1_HIGH) { 295cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Forcing High profile\n"); 296cabdff1aSopenharmony_ci param->profile = FF_PROFILE_AV1_HIGH; 297cabdff1aSopenharmony_ci } 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci avctx->bit_rate = param->rate_control_mode > 0 ? 300cabdff1aSopenharmony_ci param->target_bit_rate : 0; 301cabdff1aSopenharmony_ci avctx->rc_max_rate = param->max_bit_rate; 302cabdff1aSopenharmony_ci avctx->rc_buffer_size = param->maximum_buffer_size_ms * 303cabdff1aSopenharmony_ci FFMAX(avctx->bit_rate, avctx->rc_max_rate) / 1000LL; 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci if (avctx->bit_rate || avctx->rc_max_rate || avctx->rc_buffer_size) { 306cabdff1aSopenharmony_ci AVCPBProperties *cpb_props = ff_add_cpb_side_data(avctx); 307cabdff1aSopenharmony_ci if (!cpb_props) 308cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci cpb_props->buffer_size = avctx->rc_buffer_size; 311cabdff1aSopenharmony_ci cpb_props->max_bitrate = avctx->rc_max_rate; 312cabdff1aSopenharmony_ci cpb_props->avg_bitrate = avctx->bit_rate; 313cabdff1aSopenharmony_ci } 314cabdff1aSopenharmony_ci 315cabdff1aSopenharmony_ci return 0; 316cabdff1aSopenharmony_ci} 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_cistatic int read_in_data(EbSvtAv1EncConfiguration *param, const AVFrame *frame, 319cabdff1aSopenharmony_ci EbBufferHeaderType *header_ptr) 320cabdff1aSopenharmony_ci{ 321cabdff1aSopenharmony_ci EbSvtIOFormat *in_data = (EbSvtIOFormat *)header_ptr->p_buffer; 322cabdff1aSopenharmony_ci ptrdiff_t linesizes[4]; 323cabdff1aSopenharmony_ci size_t sizes[4]; 324cabdff1aSopenharmony_ci int bytes_shift = param->encoder_bit_depth > 8 ? 1 : 0; 325cabdff1aSopenharmony_ci int ret, frame_size; 326cabdff1aSopenharmony_ci 327cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) 328cabdff1aSopenharmony_ci linesizes[i] = frame->linesize[i]; 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci ret = av_image_fill_plane_sizes(sizes, frame->format, frame->height, 331cabdff1aSopenharmony_ci linesizes); 332cabdff1aSopenharmony_ci if (ret < 0) 333cabdff1aSopenharmony_ci return ret; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci frame_size = 0; 336cabdff1aSopenharmony_ci for (int i = 0; i < 4; i++) { 337cabdff1aSopenharmony_ci if (sizes[i] > INT_MAX - frame_size) 338cabdff1aSopenharmony_ci return AVERROR(EINVAL); 339cabdff1aSopenharmony_ci frame_size += sizes[i]; 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci in_data->luma = frame->data[0]; 343cabdff1aSopenharmony_ci in_data->cb = frame->data[1]; 344cabdff1aSopenharmony_ci in_data->cr = frame->data[2]; 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci in_data->y_stride = AV_CEIL_RSHIFT(frame->linesize[0], bytes_shift); 347cabdff1aSopenharmony_ci in_data->cb_stride = AV_CEIL_RSHIFT(frame->linesize[1], bytes_shift); 348cabdff1aSopenharmony_ci in_data->cr_stride = AV_CEIL_RSHIFT(frame->linesize[2], bytes_shift); 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci header_ptr->n_filled_len = frame_size; 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci return 0; 353cabdff1aSopenharmony_ci} 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_cistatic av_cold int eb_enc_init(AVCodecContext *avctx) 356cabdff1aSopenharmony_ci{ 357cabdff1aSopenharmony_ci SvtContext *svt_enc = avctx->priv_data; 358cabdff1aSopenharmony_ci EbErrorType svt_ret; 359cabdff1aSopenharmony_ci int ret; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci svt_enc->eos_flag = EOS_NOT_REACHED; 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params); 364cabdff1aSopenharmony_ci if (svt_ret != EB_ErrorNone) { 365cabdff1aSopenharmony_ci return svt_print_error(avctx, svt_ret, "Error initializing encoder handle"); 366cabdff1aSopenharmony_ci } 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci ret = config_enc_params(&svt_enc->enc_params, avctx); 369cabdff1aSopenharmony_ci if (ret < 0) { 370cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Error configuring encoder parameters\n"); 371cabdff1aSopenharmony_ci return ret; 372cabdff1aSopenharmony_ci } 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_set_parameter(svt_enc->svt_handle, &svt_enc->enc_params); 375cabdff1aSopenharmony_ci if (svt_ret != EB_ErrorNone) { 376cabdff1aSopenharmony_ci return svt_print_error(avctx, svt_ret, "Error setting encoder parameters"); 377cabdff1aSopenharmony_ci } 378cabdff1aSopenharmony_ci 379cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_init(svt_enc->svt_handle); 380cabdff1aSopenharmony_ci if (svt_ret != EB_ErrorNone) { 381cabdff1aSopenharmony_ci return svt_print_error(avctx, svt_ret, "Error initializing encoder"); 382cabdff1aSopenharmony_ci } 383cabdff1aSopenharmony_ci 384cabdff1aSopenharmony_ci if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { 385cabdff1aSopenharmony_ci EbBufferHeaderType *headerPtr = NULL; 386cabdff1aSopenharmony_ci 387cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_stream_header(svt_enc->svt_handle, &headerPtr); 388cabdff1aSopenharmony_ci if (svt_ret != EB_ErrorNone) { 389cabdff1aSopenharmony_ci return svt_print_error(avctx, svt_ret, "Error building stream header"); 390cabdff1aSopenharmony_ci } 391cabdff1aSopenharmony_ci 392cabdff1aSopenharmony_ci avctx->extradata_size = headerPtr->n_filled_len; 393cabdff1aSopenharmony_ci avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 394cabdff1aSopenharmony_ci if (!avctx->extradata) { 395cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 396cabdff1aSopenharmony_ci "Cannot allocate AV1 header of size %d.\n", avctx->extradata_size); 397cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 398cabdff1aSopenharmony_ci } 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci memcpy(avctx->extradata, headerPtr->p_buffer, avctx->extradata_size); 401cabdff1aSopenharmony_ci 402cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_stream_header_release(headerPtr); 403cabdff1aSopenharmony_ci if (svt_ret != EB_ErrorNone) { 404cabdff1aSopenharmony_ci return svt_print_error(avctx, svt_ret, "Error freeing stream header"); 405cabdff1aSopenharmony_ci } 406cabdff1aSopenharmony_ci } 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci svt_enc->frame = av_frame_alloc(); 409cabdff1aSopenharmony_ci if (!svt_enc->frame) 410cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 411cabdff1aSopenharmony_ci 412cabdff1aSopenharmony_ci return alloc_buffer(&svt_enc->enc_params, svt_enc); 413cabdff1aSopenharmony_ci} 414cabdff1aSopenharmony_ci 415cabdff1aSopenharmony_cistatic int eb_send_frame(AVCodecContext *avctx, const AVFrame *frame) 416cabdff1aSopenharmony_ci{ 417cabdff1aSopenharmony_ci SvtContext *svt_enc = avctx->priv_data; 418cabdff1aSopenharmony_ci EbBufferHeaderType *headerPtr = svt_enc->in_buf; 419cabdff1aSopenharmony_ci int ret; 420cabdff1aSopenharmony_ci 421cabdff1aSopenharmony_ci if (!frame) { 422cabdff1aSopenharmony_ci EbBufferHeaderType headerPtrLast; 423cabdff1aSopenharmony_ci 424cabdff1aSopenharmony_ci if (svt_enc->eos_flag == EOS_SENT) 425cabdff1aSopenharmony_ci return 0; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci memset(&headerPtrLast, 0, sizeof(headerPtrLast)); 428cabdff1aSopenharmony_ci headerPtrLast.pic_type = EB_AV1_INVALID_PICTURE; 429cabdff1aSopenharmony_ci headerPtrLast.flags = EB_BUFFERFLAG_EOS; 430cabdff1aSopenharmony_ci 431cabdff1aSopenharmony_ci svt_av1_enc_send_picture(svt_enc->svt_handle, &headerPtrLast); 432cabdff1aSopenharmony_ci svt_enc->eos_flag = EOS_SENT; 433cabdff1aSopenharmony_ci return 0; 434cabdff1aSopenharmony_ci } 435cabdff1aSopenharmony_ci 436cabdff1aSopenharmony_ci ret = read_in_data(&svt_enc->enc_params, frame, headerPtr); 437cabdff1aSopenharmony_ci if (ret < 0) 438cabdff1aSopenharmony_ci return ret; 439cabdff1aSopenharmony_ci 440cabdff1aSopenharmony_ci headerPtr->flags = 0; 441cabdff1aSopenharmony_ci headerPtr->p_app_private = NULL; 442cabdff1aSopenharmony_ci headerPtr->pts = frame->pts; 443cabdff1aSopenharmony_ci 444cabdff1aSopenharmony_ci switch (frame->pict_type) { 445cabdff1aSopenharmony_ci case AV_PICTURE_TYPE_I: 446cabdff1aSopenharmony_ci headerPtr->pic_type = EB_AV1_KEY_PICTURE; 447cabdff1aSopenharmony_ci break; 448cabdff1aSopenharmony_ci default: 449cabdff1aSopenharmony_ci // Actually means auto, or default. 450cabdff1aSopenharmony_ci headerPtr->pic_type = EB_AV1_INVALID_PICTURE; 451cabdff1aSopenharmony_ci break; 452cabdff1aSopenharmony_ci } 453cabdff1aSopenharmony_ci 454cabdff1aSopenharmony_ci svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr); 455cabdff1aSopenharmony_ci 456cabdff1aSopenharmony_ci return 0; 457cabdff1aSopenharmony_ci} 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_cistatic AVBufferRef *get_output_ref(AVCodecContext *avctx, SvtContext *svt_enc, int filled_len) 460cabdff1aSopenharmony_ci{ 461cabdff1aSopenharmony_ci if (filled_len > svt_enc->max_tu_size) { 462cabdff1aSopenharmony_ci const int max_frames = 8; 463cabdff1aSopenharmony_ci int max_tu_size; 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci if (filled_len > svt_enc->raw_size * max_frames) { 466cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "TU size > %d raw frame size.\n", max_frames); 467cabdff1aSopenharmony_ci return NULL; 468cabdff1aSopenharmony_ci } 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci max_tu_size = 1 << av_ceil_log2(filled_len); 471cabdff1aSopenharmony_ci av_buffer_pool_uninit(&svt_enc->pool); 472cabdff1aSopenharmony_ci svt_enc->pool = av_buffer_pool_init(max_tu_size + AV_INPUT_BUFFER_PADDING_SIZE, NULL); 473cabdff1aSopenharmony_ci if (!svt_enc->pool) 474cabdff1aSopenharmony_ci return NULL; 475cabdff1aSopenharmony_ci 476cabdff1aSopenharmony_ci svt_enc->max_tu_size = max_tu_size; 477cabdff1aSopenharmony_ci } 478cabdff1aSopenharmony_ci av_assert0(svt_enc->pool); 479cabdff1aSopenharmony_ci 480cabdff1aSopenharmony_ci return av_buffer_pool_get(svt_enc->pool); 481cabdff1aSopenharmony_ci} 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_cistatic int eb_receive_packet(AVCodecContext *avctx, AVPacket *pkt) 484cabdff1aSopenharmony_ci{ 485cabdff1aSopenharmony_ci SvtContext *svt_enc = avctx->priv_data; 486cabdff1aSopenharmony_ci EbBufferHeaderType *headerPtr; 487cabdff1aSopenharmony_ci AVFrame *frame = svt_enc->frame; 488cabdff1aSopenharmony_ci EbErrorType svt_ret; 489cabdff1aSopenharmony_ci AVBufferRef *ref; 490cabdff1aSopenharmony_ci int ret = 0, pict_type; 491cabdff1aSopenharmony_ci 492cabdff1aSopenharmony_ci if (svt_enc->eos_flag == EOS_RECEIVED) 493cabdff1aSopenharmony_ci return AVERROR_EOF; 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci ret = ff_encode_get_frame(avctx, frame); 496cabdff1aSopenharmony_ci if (ret < 0 && ret != AVERROR_EOF) 497cabdff1aSopenharmony_ci return ret; 498cabdff1aSopenharmony_ci if (ret == AVERROR_EOF) 499cabdff1aSopenharmony_ci frame = NULL; 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_ci ret = eb_send_frame(avctx, frame); 502cabdff1aSopenharmony_ci if (ret < 0) 503cabdff1aSopenharmony_ci return ret; 504cabdff1aSopenharmony_ci av_frame_unref(svt_enc->frame); 505cabdff1aSopenharmony_ci 506cabdff1aSopenharmony_ci svt_ret = svt_av1_enc_get_packet(svt_enc->svt_handle, &headerPtr, svt_enc->eos_flag); 507cabdff1aSopenharmony_ci if (svt_ret == EB_NoErrorEmptyQueue) 508cabdff1aSopenharmony_ci return AVERROR(EAGAIN); 509cabdff1aSopenharmony_ci 510cabdff1aSopenharmony_ci ref = get_output_ref(avctx, svt_enc, headerPtr->n_filled_len); 511cabdff1aSopenharmony_ci if (!ref) { 512cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Failed to allocate output packet.\n"); 513cabdff1aSopenharmony_ci svt_av1_enc_release_out_buffer(&headerPtr); 514cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 515cabdff1aSopenharmony_ci } 516cabdff1aSopenharmony_ci pkt->buf = ref; 517cabdff1aSopenharmony_ci pkt->data = ref->data; 518cabdff1aSopenharmony_ci 519cabdff1aSopenharmony_ci memcpy(pkt->data, headerPtr->p_buffer, headerPtr->n_filled_len); 520cabdff1aSopenharmony_ci memset(pkt->data + headerPtr->n_filled_len, 0, AV_INPUT_BUFFER_PADDING_SIZE); 521cabdff1aSopenharmony_ci 522cabdff1aSopenharmony_ci pkt->size = headerPtr->n_filled_len; 523cabdff1aSopenharmony_ci pkt->pts = headerPtr->pts; 524cabdff1aSopenharmony_ci pkt->dts = headerPtr->dts; 525cabdff1aSopenharmony_ci 526cabdff1aSopenharmony_ci switch (headerPtr->pic_type) { 527cabdff1aSopenharmony_ci case EB_AV1_KEY_PICTURE: 528cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 529cabdff1aSopenharmony_ci // fall-through 530cabdff1aSopenharmony_ci case EB_AV1_INTRA_ONLY_PICTURE: 531cabdff1aSopenharmony_ci pict_type = AV_PICTURE_TYPE_I; 532cabdff1aSopenharmony_ci break; 533cabdff1aSopenharmony_ci case EB_AV1_INVALID_PICTURE: 534cabdff1aSopenharmony_ci pict_type = AV_PICTURE_TYPE_NONE; 535cabdff1aSopenharmony_ci break; 536cabdff1aSopenharmony_ci default: 537cabdff1aSopenharmony_ci pict_type = AV_PICTURE_TYPE_P; 538cabdff1aSopenharmony_ci break; 539cabdff1aSopenharmony_ci } 540cabdff1aSopenharmony_ci 541cabdff1aSopenharmony_ci if (headerPtr->pic_type == EB_AV1_NON_REF_PICTURE) 542cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_DISPOSABLE; 543cabdff1aSopenharmony_ci 544cabdff1aSopenharmony_ci if (headerPtr->flags & EB_BUFFERFLAG_EOS) 545cabdff1aSopenharmony_ci svt_enc->eos_flag = EOS_RECEIVED; 546cabdff1aSopenharmony_ci 547cabdff1aSopenharmony_ci ff_side_data_set_encoder_stats(pkt, headerPtr->qp * FF_QP2LAMBDA, NULL, 0, pict_type); 548cabdff1aSopenharmony_ci 549cabdff1aSopenharmony_ci svt_av1_enc_release_out_buffer(&headerPtr); 550cabdff1aSopenharmony_ci 551cabdff1aSopenharmony_ci return 0; 552cabdff1aSopenharmony_ci} 553cabdff1aSopenharmony_ci 554cabdff1aSopenharmony_cistatic av_cold int eb_enc_close(AVCodecContext *avctx) 555cabdff1aSopenharmony_ci{ 556cabdff1aSopenharmony_ci SvtContext *svt_enc = avctx->priv_data; 557cabdff1aSopenharmony_ci 558cabdff1aSopenharmony_ci if (svt_enc->svt_handle) { 559cabdff1aSopenharmony_ci svt_av1_enc_deinit(svt_enc->svt_handle); 560cabdff1aSopenharmony_ci svt_av1_enc_deinit_handle(svt_enc->svt_handle); 561cabdff1aSopenharmony_ci } 562cabdff1aSopenharmony_ci if (svt_enc->in_buf) { 563cabdff1aSopenharmony_ci av_free(svt_enc->in_buf->p_buffer); 564cabdff1aSopenharmony_ci av_freep(&svt_enc->in_buf); 565cabdff1aSopenharmony_ci } 566cabdff1aSopenharmony_ci 567cabdff1aSopenharmony_ci av_buffer_pool_uninit(&svt_enc->pool); 568cabdff1aSopenharmony_ci av_frame_free(&svt_enc->frame); 569cabdff1aSopenharmony_ci 570cabdff1aSopenharmony_ci return 0; 571cabdff1aSopenharmony_ci} 572cabdff1aSopenharmony_ci 573cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(SvtContext, x) 574cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 575cabdff1aSopenharmony_cistatic const AVOption options[] = { 576cabdff1aSopenharmony_ci#if FF_API_SVTAV1_OPTS 577cabdff1aSopenharmony_ci { "hielevel", "Hierarchical prediction levels setting (Deprecated, use svtav1-params)", OFFSET(hierarchical_level), 578cabdff1aSopenharmony_ci AV_OPT_TYPE_INT, { .i64 = 4 }, 3, 4, VE | AV_OPT_FLAG_DEPRECATED , "hielevel"}, 579cabdff1aSopenharmony_ci { "3level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "hielevel" }, 580cabdff1aSopenharmony_ci { "4level", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4 }, INT_MIN, INT_MAX, VE, "hielevel" }, 581cabdff1aSopenharmony_ci 582cabdff1aSopenharmony_ci { "la_depth", "Look ahead distance [0, 120] (Deprecated, use svtav1-params)", OFFSET(la_depth), 583cabdff1aSopenharmony_ci AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 120, VE | AV_OPT_FLAG_DEPRECATED }, 584cabdff1aSopenharmony_ci 585cabdff1aSopenharmony_ci { "tier", "Set operating point tier (Deprecated, use svtav1-params)", OFFSET(tier), 586cabdff1aSopenharmony_ci AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED, "tier" }, 587cabdff1aSopenharmony_ci { "main", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, VE, "tier" }, 588cabdff1aSopenharmony_ci { "high", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "tier" }, 589cabdff1aSopenharmony_ci#endif 590cabdff1aSopenharmony_ci { "preset", "Encoding preset", 591cabdff1aSopenharmony_ci OFFSET(enc_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_ENC_PRESET, VE }, 592cabdff1aSopenharmony_ci 593cabdff1aSopenharmony_ci FF_AV1_PROFILE_OPTS 594cabdff1aSopenharmony_ci 595cabdff1aSopenharmony_ci#define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \ 596cabdff1aSopenharmony_ci { .i64 = value }, 0, 0, VE, "avctx.level" 597cabdff1aSopenharmony_ci { LEVEL("2.0", 20) }, 598cabdff1aSopenharmony_ci { LEVEL("2.1", 21) }, 599cabdff1aSopenharmony_ci { LEVEL("2.2", 22) }, 600cabdff1aSopenharmony_ci { LEVEL("2.3", 23) }, 601cabdff1aSopenharmony_ci { LEVEL("3.0", 30) }, 602cabdff1aSopenharmony_ci { LEVEL("3.1", 31) }, 603cabdff1aSopenharmony_ci { LEVEL("3.2", 32) }, 604cabdff1aSopenharmony_ci { LEVEL("3.3", 33) }, 605cabdff1aSopenharmony_ci { LEVEL("4.0", 40) }, 606cabdff1aSopenharmony_ci { LEVEL("4.1", 41) }, 607cabdff1aSopenharmony_ci { LEVEL("4.2", 42) }, 608cabdff1aSopenharmony_ci { LEVEL("4.3", 43) }, 609cabdff1aSopenharmony_ci { LEVEL("5.0", 50) }, 610cabdff1aSopenharmony_ci { LEVEL("5.1", 51) }, 611cabdff1aSopenharmony_ci { LEVEL("5.2", 52) }, 612cabdff1aSopenharmony_ci { LEVEL("5.3", 53) }, 613cabdff1aSopenharmony_ci { LEVEL("6.0", 60) }, 614cabdff1aSopenharmony_ci { LEVEL("6.1", 61) }, 615cabdff1aSopenharmony_ci { LEVEL("6.2", 62) }, 616cabdff1aSopenharmony_ci { LEVEL("6.3", 63) }, 617cabdff1aSopenharmony_ci { LEVEL("7.0", 70) }, 618cabdff1aSopenharmony_ci { LEVEL("7.1", 71) }, 619cabdff1aSopenharmony_ci { LEVEL("7.2", 72) }, 620cabdff1aSopenharmony_ci { LEVEL("7.3", 73) }, 621cabdff1aSopenharmony_ci#undef LEVEL 622cabdff1aSopenharmony_ci 623cabdff1aSopenharmony_ci { "crf", "Constant Rate Factor value", OFFSET(crf), 624cabdff1aSopenharmony_ci AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE }, 625cabdff1aSopenharmony_ci { "qp", "Initial Quantizer level value", OFFSET(qp), 626cabdff1aSopenharmony_ci AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE }, 627cabdff1aSopenharmony_ci#if FF_API_SVTAV1_OPTS 628cabdff1aSopenharmony_ci { "sc_detection", "Scene change detection (Deprecated, use svtav1-params)", OFFSET(scd), 629cabdff1aSopenharmony_ci AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE | AV_OPT_FLAG_DEPRECATED }, 630cabdff1aSopenharmony_ci 631cabdff1aSopenharmony_ci { "tile_columns", "Log2 of number of tile columns to use (Deprecated, use svtav1-params)", OFFSET(tile_columns), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 4, VE | AV_OPT_FLAG_DEPRECATED }, 632cabdff1aSopenharmony_ci { "tile_rows", "Log2 of number of tile rows to use (Deprecated, use svtav1-params)", OFFSET(tile_rows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 6, VE | AV_OPT_FLAG_DEPRECATED }, 633cabdff1aSopenharmony_ci#endif 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, VE }, 636cabdff1aSopenharmony_ci 637cabdff1aSopenharmony_ci {NULL}, 638cabdff1aSopenharmony_ci}; 639cabdff1aSopenharmony_ci 640cabdff1aSopenharmony_cistatic const AVClass class = { 641cabdff1aSopenharmony_ci .class_name = "libsvtav1", 642cabdff1aSopenharmony_ci .item_name = av_default_item_name, 643cabdff1aSopenharmony_ci .option = options, 644cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 645cabdff1aSopenharmony_ci}; 646cabdff1aSopenharmony_ci 647cabdff1aSopenharmony_cistatic const FFCodecDefault eb_enc_defaults[] = { 648cabdff1aSopenharmony_ci { "b", "0" }, 649cabdff1aSopenharmony_ci { "flags", "+cgop" }, 650cabdff1aSopenharmony_ci { "g", "-1" }, 651cabdff1aSopenharmony_ci { "qmin", "1" }, 652cabdff1aSopenharmony_ci { "qmax", "63" }, 653cabdff1aSopenharmony_ci { NULL }, 654cabdff1aSopenharmony_ci}; 655cabdff1aSopenharmony_ci 656cabdff1aSopenharmony_ciconst FFCodec ff_libsvtav1_encoder = { 657cabdff1aSopenharmony_ci .p.name = "libsvtav1", 658cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("SVT-AV1(Scalable Video Technology for AV1) encoder"), 659cabdff1aSopenharmony_ci .priv_data_size = sizeof(SvtContext), 660cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 661cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_AV1, 662cabdff1aSopenharmony_ci .init = eb_enc_init, 663cabdff1aSopenharmony_ci FF_CODEC_RECEIVE_PACKET_CB(eb_receive_packet), 664cabdff1aSopenharmony_ci .close = eb_enc_close, 665cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS, 666cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP, 667cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, 668cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P10, 669cabdff1aSopenharmony_ci AV_PIX_FMT_NONE }, 670cabdff1aSopenharmony_ci .p.priv_class = &class, 671cabdff1aSopenharmony_ci .defaults = eb_enc_defaults, 672cabdff1aSopenharmony_ci .p.wrapper_name = "libsvtav1", 673cabdff1aSopenharmony_ci}; 674