From patchwork Mon Dec 30 19:20:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 17073 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 4FEFC448545 for ; Mon, 30 Dec 2019 21:21:09 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3F8B968ACBF; Mon, 30 Dec 2019 21:21:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 852F368AA15 for ; Mon, 30 Dec 2019 21:21:00 +0200 (EET) Received: by mail-pf1-f194.google.com with SMTP id x184so18688952pfb.3 for ; Mon, 30 Dec 2019 11:21:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=t5WnuCsVATP3HeKSbnSeivb+GCDfkcH+RmwZOhJqtK4=; b=DidXvECF9Xoxc2pe3JqufLAUMW7I7TCRNg2xXa3hnVmqaOfUU/Ue/ZX916dJ+SxnKH l6PLWlFK1cLxOOiff7akj/6e/aUS+QKUgEKq76Hr15Gyw/+HgyaujRiygCyxzbFWzS3D R6xz61a3Lwxlb2OIfW8n341AMT8SrkDMarSRxnx+qR/KJtw4loYM08XpHSzhGNn0m+sZ 4tRclH4pWr2Gq2POARnjuU9zh2qGP0JsoMRYJixbjknRQTbzmAowt1Fyv56oNpALTXef LNRprn9mmFjppfpF8HSwPdvVWjSuQ406ooUzZGjsvPDQT03nlxJBvm1UcnVQ4YvQVFpy Lh5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=t5WnuCsVATP3HeKSbnSeivb+GCDfkcH+RmwZOhJqtK4=; b=NOSLeaEAD3QIIhN/vAtPTmeDNBY0Jj3qGI8n6TO7xwiRjsBcJWueFgbxSFU2n7H4hC 9r6gVgi1huEKYwUGRrC8/FNv15HmTfIvH0a5HQ/jvlq/OVZ2Jss8VoTXtQeP1l/uBqGG 46wB5h9Q41+jQ4X9tbd1lTA/Gks0ezsRTcoJ4OnvFlR0s2azT/izsmJOEWddEg3cUjC+ ojDlyMXDJMU2IOUli+Ydddpke9J6ob5DnAgVlK2mr0nxsaZ2K0F3SYGxm0o5JD2bxGl6 jekL/3cCuuqyLcyiN/2PQClhx4JG+R8jUYnZoaCKYblB+JBynEx+YTcYLwR5uT3AZICB 9kSg== X-Gm-Message-State: APjAAAXOo669SeEi/QdsQ4FqehenqfL0ArS0HL8FhJa/+WgHFd3xOcQS 7NhUpBUi1FFI6bl1HTzQdyqCNmyW X-Google-Smtp-Source: APXvYqzj6q9jqpT/zjUbXvegFFua3hSNfhdKyEO6BIbbCNPizo/O74QJr0/rKblv+W6s67LYkJSqjQ== X-Received: by 2002:aa7:971d:: with SMTP id a29mr72129955pfg.29.1577733658461; Mon, 30 Dec 2019 11:20:58 -0800 (PST) Received: from localhost.localdomain ([181.23.77.192]) by smtp.gmail.com with ESMTPSA id p17sm51275102pfn.31.2019.12.30.11.20.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Dec 2019 11:20:58 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 30 Dec 2019 16:20:07 -0300 Message-Id: <20191230192009.2462-2-jamrial@gmail.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191230192009.2462-1-jamrial@gmail.com> References: <20191230192009.2462-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/4 v2] avcodec/libx265: add a qp option and apply the relevant global AVCodecContext settings to the encoder context X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: James Almer --- doc/encoders.texi | 22 ++++++++++++++ libavcodec/libx265.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 673eaf6496..61e674cf96 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2441,6 +2441,28 @@ Set profile restrictions. @item crf Set the quality for constant quality mode. +@item qp +Set constant quantization rate control method parameter. + +@item qmin +Minimum quantizer scale. + +@item qmax +Maximum quantizer scale. + +@item qdiff +Maximum difference between quantizer scales. + +@item qblur +Quantizer curve blur + +@item qcomp +Quantizer curve compression factor + +@item i_qfactor + +@item b_qfactor + @item forced-idr Normally, when forcing a I-frame type, the encoder can select any type of I-frame. This option forces it to choose an IDR-frame. diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index 798ba12efa..9646e208f4 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -42,6 +42,7 @@ typedef struct libx265Context { const x265_api *api; float crf; + int cqp; int forced_idr; char *preset; char *tune; @@ -82,6 +83,21 @@ static av_cold int libx265_encode_close(AVCodecContext *avctx) return 0; } +static av_cold int libx265_param_parse_float(AVCodecContext *avctx, + const char *key, float value) +{ + libx265Context *ctx = avctx->priv_data; + char buf[256]; + + snprintf(buf, sizeof(buf), "%2.2f", value); + if (ctx->api->param_parse(ctx->params, key, buf) == X265_PARAM_BAD_VALUE) { + av_log(avctx, AV_LOG_ERROR, "Invalid value %2.2f for param \"%s\".\n", value, key); + return AVERROR(EINVAL); + } + + return 0; +} + static av_cold int libx265_param_parse_int(AVCodecContext *avctx, const char *key, int value) { @@ -242,6 +258,50 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) } else if (avctx->bit_rate > 0) { ctx->params->rc.bitrate = avctx->bit_rate / 1000; ctx->params->rc.rateControlMode = X265_RC_ABR; + } else if (ctx->cqp >= 0) { + char cqp[6]; + + snprintf(cqp, sizeof(cqp), "%d", ctx->cqp); + if (ctx->api->param_parse(ctx->params, "qp", cqp) == X265_PARAM_BAD_VALUE) { + av_log(avctx, AV_LOG_ERROR, "Invalid cqp: %d.\n", ctx->cqp); + return AVERROR(EINVAL); + } + } + + if (avctx->qmin >= 0) { + ret = libx265_param_parse_int(avctx, "qpmin", avctx->qmin); + if (ret < 0) + return ret; + } + if (avctx->qmax >= 0) { + ret = libx265_param_parse_int(avctx, "qpmax", avctx->qmax); + if (ret < 0) + return ret; + } + if (avctx->max_qdiff >= 0) { + ret = libx265_param_parse_int(avctx, "qpstep", avctx->max_qdiff); + if (ret < 0) + return ret; + } + if (avctx->qblur >= 0) { + ret = libx265_param_parse_float(avctx, "qblur", avctx->qblur); + if (ret < 0) + return ret; + } + if (avctx->qcompress >= 0) { + ret = libx265_param_parse_float(avctx, "qcomp", avctx->qcompress); + if (ret < 0) + return ret; + } + if (avctx->i_quant_factor > 0) { + ret = libx265_param_parse_float(avctx, "ipratio", avctx->i_quant_factor); + if (ret < 0) + return ret; + } + if (avctx->b_quant_factor > 0) { + ret = libx265_param_parse_float(avctx, "pbratio", avctx->b_quant_factor); + if (ret < 0) + return ret; } ctx->params->rc.vbvBufferSize = avctx->rc_buffer_size / 1000; @@ -576,6 +636,7 @@ static av_cold void libx265_encode_init_csp(AVCodec *codec) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "crf", "set the x265 crf", OFFSET(crf), AV_OPT_TYPE_FLOAT, { .dbl = -1 }, -1, FLT_MAX, VE }, + { "qp", "set the x265 qp", OFFSET(cqp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE }, { "forced-idr", "if forcing keyframes, force them as IDR frames", OFFSET(forced_idr),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "preset", "set the x265 preset", OFFSET(preset), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "tune", "set the x265 tune parameter", OFFSET(tune), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, @@ -597,6 +658,13 @@ static const AVCodecDefault x265_defaults[] = { { "g", "-1" }, { "keyint_min", "-1" }, { "refs", "-1" }, + { "qmin", "-1" }, + { "qmax", "-1" }, + { "qdiff", "-1" }, + { "qblur", "-1" }, + { "qcomp", "-1" }, + { "i_qfactor", "-1" }, + { "b_qfactor", "-1" }, { NULL }, };