using namespace std;
+namespace {
+
+void update_vbv_settings(x264_param_t *param)
+{
+ if (global_flags.x264_vbv_buffer_size < 0) {
+ param->rc.i_vbv_buffer_size = param->rc.i_bitrate; // One-second VBV.
+ } else {
+ param->rc.i_vbv_buffer_size = global_flags.x264_vbv_buffer_size;
+ }
+ if (global_flags.x264_vbv_max_bitrate < 0) {
+ param->rc.i_vbv_max_bitrate = param->rc.i_bitrate; // CBR.
+ } else {
+ param->rc.i_vbv_max_bitrate = global_flags.x264_vbv_max_bitrate;
+ }
+}
+
+} // namespace
+
X264Encoder::X264Encoder(AVOutputFormat *oformat)
: wants_global_headers(oformat->flags & AVFMT_GLOBALHEADER)
{
param.rc.i_rc_method = X264_RC_ABR;
param.rc.i_bitrate = global_flags.x264_bitrate;
- if (global_flags.x264_vbv_buffer_size < 0) {
- param.rc.i_vbv_buffer_size = param.rc.i_bitrate; // One-second VBV.
- } else {
- param.rc.i_vbv_buffer_size = global_flags.x264_vbv_buffer_size;
- }
- if (global_flags.x264_vbv_max_bitrate < 0) {
- param.rc.i_vbv_max_bitrate = param.rc.i_bitrate; // CBR.
- } else {
- param.rc.i_vbv_max_bitrate = global_flags.x264_vbv_max_bitrate;
- }
+ update_vbv_settings(¶m);
if (param.rc.i_vbv_max_bitrate > 0) {
// If the user wants VBV control to cap the max rate, it is
// also reasonable to assume that they are fine with the stream
void X264Encoder::encoder_thread_func()
{
- nice(5); // Note that x264 further nices some of its threads.
+ if (nice(5) == -1) { // Note that x264 further nices some of its threads.
+ perror("nice()");
+ // No exit; it's not fatal.
+ }
init_x264();
bool frames_left;
input_pic = &pic;
}
+ // 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) {
+ 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) {
speed_control->before_frame(float(free_frames.size()) / X264_QUEUE_LENGTH, X264_QUEUE_LENGTH, 1e6 * qf.duration / TIMEBASE);
}