#include "x264_speed_control.h"
+#include <dlfcn.h>
#include <math.h>
#include <stdio.h>
#include <x264.h>
#include <type_traits>
#include "flags.h"
+#include "metrics.h"
using namespace std;
using namespace std::chrono;
+#define SC_PRESETS 26
+
X264SpeedControl::X264SpeedControl(x264_t *x264, float f_speed, int i_buffer_size, float f_buffer_init)
- : x264(x264), f_speed(f_speed)
+ : dyn(load_x264_for_bit_depth(global_flags.x264_bit_depth)),
+ x264(x264), f_speed(f_speed)
{
x264_param_t param;
- x264_encoder_parameters(x264, ¶m);
+ dyn.x264_encoder_parameters(x264, ¶m);
float fps = (float)param.i_fps_num / param.i_fps_den;
uspf = 1e6 / fps;
stat.max_buffer = 0;
stat.avg_preset = 0.0;
stat.den = 0;
+
+ metric_x264_speedcontrol_buffer_available_seconds = buffer_fill * 1e-6;
+ metric_x264_speedcontrol_buffer_size_seconds = buffer_size * 1e-6;
+ metric_x264_speedcontrol_preset_used_frames.init_uniform(SC_PRESETS);
+ global_metrics.add("x264_speedcontrol_preset_used_frames", &metric_x264_speedcontrol_preset_used_frames);
+ global_metrics.add("x264_speedcontrol_buffer_available_seconds", &metric_x264_speedcontrol_buffer_available_seconds, Metrics::TYPE_GAUGE);
+ global_metrics.add("x264_speedcontrol_buffer_size_seconds", &metric_x264_speedcontrol_buffer_size_seconds, Metrics::TYPE_GAUGE);
+ global_metrics.add("x264_speedcontrol_idle_frames", &metric_x264_speedcontrol_idle_frames);
+ global_metrics.add("x264_speedcontrol_late_frames", &metric_x264_speedcontrol_late_frames);
}
X264SpeedControl::~X264SpeedControl()
(float)stat.min_buffer / buffer_size,
(float)stat.max_buffer / buffer_size );
// x264_log( x264, X264_LOG_INFO, "speedcontrol: avg cplx=%.5f\n", cplx_num / cplx_den );
+ if (dyn.handle) {
+ dlclose(dyn.handle);
+ }
}
typedef struct
// Note that the two first and the two last are also used for extrapolation
// should the desired time be outside the range. Thus, it is disadvantageous if
// they are chosen so that the timings are too close to each other.
-#define SC_PRESETS 26
static const sc_preset_t presets[SC_PRESETS] = {
#define I4 X264_ANALYSE_I4x4
#define I8 X264_ANALYSE_I8x8
set_buffer_size(new_buffer_size);
}
buffer_fill = buffer_size * new_buffer_fill;
+ metric_x264_speedcontrol_buffer_available_seconds = buffer_fill * 1e-6;
steady_clock::time_point t;
first = false;
}
buffer_fill = buffer_size;
+ metric_x264_speedcontrol_buffer_available_seconds = buffer_fill * 1e-6;
+ ++metric_x264_speedcontrol_idle_frames;
} else if (buffer_fill <= 0) { // oops, we're late
// fprintf(stderr, "speedcontrol underflow (%.6f sec)\n", buffer_fill/1e6);
+ ++metric_x264_speedcontrol_late_frames;
}
{
const sc_preset_t *s = &presets[new_preset];
x264_param_t p;
- x264_encoder_parameters(x264, &p);
+ dyn.x264_encoder_parameters(x264, &p);
p.i_frame_reference = s->refs;
p.i_bframe_adaptive = s->badapt;
if (override_func) {
override_func(&p);
}
- x264_encoder_reconfig(x264, &p);
+ dyn.x264_encoder_reconfig(x264, &p);
preset = new_preset;
+
+ metric_x264_speedcontrol_preset_used_frames.count_event(new_preset);
}