PR #21232 opened by Werner Robitza (slhck)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21232
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21232.patch

Add support for standard -pass and -passlogfile options, matching the behavior
of libx264.
Add the -x265-stats option to specify the stats filename.
Update documentation.



>From 4a40be44b9b252211684b8f2e3ee0b52ed8e5c45 Mon Sep 17 00:00:00 2001
From: Werner Robitza <[email protected]>
Date: Thu, 18 Dec 2025 12:47:17 +0100
Subject: [PATCH] avcodec/libx265: add pass and x265-stats option

Add support for standard -pass and -passlogfile options, matching the behavior
of libx264.
Add the -x265-stats option to specify the stats filename.
Update documentation.

Signed-off-by: Werner Robitza <[email protected]>
---
 doc/encoders.texi         |  4 ++++
 fftools/ffmpeg_mux_init.c |  5 +++++
 libavcodec/libx265.c      | 20 ++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index e93a3cc275..610ec9a04c 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3083,6 +3083,10 @@ Quantizer curve compression factor
 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.
 
+@item x265-stats
+Specify the file name for 2-pass stats. This is set automatically when using
+the @option{-passlogfile} option.
+
 @item udu_sei @var{boolean}
 Import user data unregistered SEI if available into output. Default is 0 (off).
 
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 194a87875d..0569f62836 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -730,6 +730,11 @@ static int new_stream_video(Muxer *mux, const 
OptionsContext *o,
                                                      AV_OPT_SEARCH_CHILDREN) > 
0)
                     av_opt_set(video_enc, "stats", logfilename,
                                AV_OPT_SEARCH_CHILDREN);
+            } else if (!strcmp(video_enc->codec->name, "libx265")) {
+                if (av_opt_is_set_to_default_by_name(video_enc, "x265-stats",
+                                                     AV_OPT_SEARCH_CHILDREN) > 
0)
+                    av_opt_set(video_enc, "x265-stats", logfilename,
+                               AV_OPT_SEARCH_CHILDREN);
             } else {
                 if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
                     char  *logbuffer = read_file_to_string(logfilename);
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 341868e7cd..89cd7d5dbe 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -71,6 +71,7 @@ typedef struct libx265Context {
     char *preset;
     char *tune;
     char *profile;
+    char *stats;
     AVDictionary *x265_opts;
 
     void *sei_data;
@@ -529,6 +530,24 @@ static av_cold int libx265_encode_init(AVCodecContext 
*avctx)
         }
     }
 
+    if (avctx->flags & AV_CODEC_FLAG_PASS1) {
+        if (ctx->api->param_parse(ctx->params, "pass", "1") == 
X265_PARAM_BAD_VALUE) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid value for param \"pass\".\n");
+            return AVERROR(EINVAL);
+        }
+    } else if (avctx->flags & AV_CODEC_FLAG_PASS2) {
+        if (ctx->api->param_parse(ctx->params, "pass", "2") == 
X265_PARAM_BAD_VALUE) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid value for param \"pass\".\n");
+            return AVERROR(EINVAL);
+        }
+    }
+    if (ctx->stats) {
+        if (ctx->api->param_parse(ctx->params, "stats", ctx->stats) == 
X265_PARAM_BAD_VALUE) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid value \"%s\" for param 
\"stats\".\n", ctx->stats);
+            return AVERROR(EINVAL);
+        }
+    }
+
     if (ctx->params->rc.vbvBufferSize && avctx->rc_initial_buffer_occupancy > 
1000 &&
         ctx->params->rc.vbvBufferInit == 0.9) {
         ctx->params->rc.vbvBufferInit = 
(float)avctx->rc_initial_buffer_occupancy / 1000;
@@ -1009,6 +1028,7 @@ static const AVOption options[] = {
     { "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 },
     { "profile",     "set the x265 profile",                                   
                     OFFSET(profile),   AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
+    { "x265-stats",  "Filename for 2 pass stats",                              
                     OFFSET(stats),     AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
     { "udu_sei",     "Use user data unregistered SEI if available",            
                     OFFSET(udu_sei),   AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, 
VE },
     { "a53cc",       "Use A53 Closed Captions (if available)",                 
                     OFFSET(a53_cc),    AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, 
VE },
     { "x265-params", "set the x265 configuration using a :-separated list of 
key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT,   { 0 }, 0, 0, VE },
-- 
2.49.1

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to