From a89f0c565d3410cfd9b266dd661a934408a01028 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 1 Aug 2016 19:53:23 +0200 Subject: [PATCH] Fix an issue with changing video bitrate when x264 speed control was in effect. --- x264_encoder.cpp | 18 ++++++++++++------ x264_speed_control.cpp | 3 +++ x264_speed_control.h | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/x264_encoder.cpp b/x264_encoder.cpp index f77549d..9874519 100644 --- a/x264_encoder.cpp +++ b/x264_encoder.cpp @@ -249,12 +249,18 @@ void X264Encoder::encode_frame(X264Encoder::QueuedFrame qf) // See if we have a new bitrate to change to. unsigned new_rate = new_bitrate_kbit.exchange(0); // Read and clear. if (new_rate != 0) { - x264_param_t param; - x264_encoder_parameters(x264, ¶m); - param.rc.i_bitrate = new_rate; - update_vbv_settings(¶m); - x264_encoder_reconfig(x264, ¶m); - printf("changing rate to %u\n", new_rate); + if (speed_control) { + speed_control->set_config_override_function([new_rate](x264_param_t *param) { + param->rc.i_bitrate = new_rate; + update_vbv_settings(param); + }); + } else { + x264_param_t param; + x264_encoder_parameters(x264, ¶m); + param.rc.i_bitrate = new_rate; + update_vbv_settings(¶m); + x264_encoder_reconfig(x264, ¶m); + } } if (speed_control) { diff --git a/x264_speed_control.cpp b/x264_speed_control.cpp index c6add3e..7eca74d 100644 --- a/x264_speed_control.cpp +++ b/x264_speed_control.cpp @@ -305,6 +305,9 @@ void X264SpeedControl::apply_preset(int new_preset) p.analyse.b_mixed_references = s->mix; p.analyse.i_direct_mv_pred = s->direct; p.analyse.i_me_range = s->merange; + if (override_func) { + override_func(&p); + } x264_encoder_reconfig(x264, &p); preset = new_preset; } diff --git a/x264_speed_control.h b/x264_speed_control.h index 84eb090..7add8fd 100644 --- a/x264_speed_control.h +++ b/x264_speed_control.h @@ -47,6 +47,7 @@ #include #include #include +#include extern "C" { #include "x264.h" @@ -80,6 +81,17 @@ public: void before_frame(float new_buffer_fill, int new_buffer_size, float f_uspf); void after_frame(); + // x264 seemingly has an issue where x264_encoder_reconfig() is not reflected + // immediately in x264_encoder_parameters(). Since speed control keeps calling + // those two all the time, any changes you make outside X264SpeedControl + // could be overridden. Thus, to make changes to encoder parameters, you should + // instead set a function here, which will be called every time parameters + // are modified. + void set_config_override_function(std::function override_func) + { + this->override_func = override_func; + } + private: void set_buffer_size(int new_buffer_size); int dither_preset(float f); @@ -112,4 +124,6 @@ private: double avg_preset; int den; } stat; + + std::function override_func = nullptr; }; -- 2.39.2