From: Steinar H. Gunderson Date: Sun, 11 Jun 2017 14:35:46 +0000 (+0200) Subject: Add a histogram of output crf values from x264. X-Git-Tag: 1.6.1~61 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=0ec13fe273ceb4f0db4d1b431a8adec9f1f03b7e Add a histogram of output crf values from x264. --- diff --git a/metrics.cpp b/metrics.cpp index 2874ad4..3b3d1eb 100644 --- a/metrics.cpp +++ b/metrics.cpp @@ -57,12 +57,13 @@ void Metrics::add(const string &name, const vector> &labels types[name] = type; } -void Metrics::add_histogram(const string &name, const vector> &labels, atomic *location, size_t num_elements) +void Metrics::add_histogram(const string &name, const vector> &labels, atomic *first_bucket_location, atomic *sum_location, size_t num_elements) { Histogram histogram; histogram.name = name; histogram.labels = labels; - histogram.location_int64 = location; + histogram.first_bucket_location = first_bucket_location; + histogram.sum_location = sum_location; histogram.num_elements = num_elements; lock_guard lock(mu); @@ -93,20 +94,19 @@ string Metrics::serialize() const for (const Histogram &histogram : histograms) { ss << "# TYPE nageru_" << histogram.name << " histogram\n"; - int64_t sum = 0, count = 0; + int64_t count = 0; for (size_t i = 0; i < histogram.num_elements; ++i) { char buf[16]; snprintf(buf, sizeof(buf), "%lu", i); vector> labels = histogram.labels; labels.emplace_back("le", buf); - int64_t val = histogram.location_int64[i].load(); - sum += i * val; + int64_t val = histogram.first_bucket_location[i].load(); count += val; ss << serialize_name(histogram.name + "_bucket", labels) << " " << count << "\n"; } - ss << serialize_name(histogram.name + "_sum", histogram.labels) << " " << sum << "\n"; + ss << serialize_name(histogram.name + "_sum", histogram.labels) << " " << histogram.sum_location->load() << "\n"; ss << serialize_name(histogram.name + "_count", histogram.labels) << " " << count << "\n"; } diff --git a/metrics.h b/metrics.h index 2a19e25..c1239a6 100644 --- a/metrics.h +++ b/metrics.h @@ -33,7 +33,7 @@ public: void add(const std::string &name, const std::vector> &labels, std::atomic *location, Type type = TYPE_COUNTER); // Only integer histogram, ie. keys are 0..(N-1). - void add_histogram(const std::string &name, const std::vector> &labels, std::atomic *location, size_t num_elements); + void add_histogram(const std::string &name, const std::vector> &labels, std::atomic *first_bucket_location, std::atomic *sum_location, size_t num_elements); std::string serialize() const; @@ -57,7 +57,8 @@ private: struct Histogram { std::string name; std::vector> labels; - std::atomic *location_int64; // First bucket. + std::atomic *first_bucket_location; + std::atomic *sum_location; size_t num_elements; }; diff --git a/x264_encoder.cpp b/x264_encoder.cpp index 3a31510..9d108a0 100644 --- a/x264_encoder.cpp +++ b/x264_encoder.cpp @@ -65,6 +65,7 @@ X264Encoder::X264Encoder(AVOutputFormat *oformat) global_metrics.add("x264_output_frames", {{ "type", "i" }}, &metric_x264_output_frames_i); global_metrics.add("x264_output_frames", {{ "type", "p" }}, &metric_x264_output_frames_p); global_metrics.add("x264_output_frames", {{ "type", "b" }}, &metric_x264_output_frames_b); + global_metrics.add_histogram("x264_crf", {}, metric_x264_crf, &metric_x264_crf_sum, crf_buckets); } X264Encoder::~X264Encoder() @@ -363,6 +364,16 @@ void X264Encoder::encode_frame(X264Encoder::QueuedFrame qf) ++metric_x264_output_frames_p; } + if (pic.prop.f_crf_avg <= 0.0) { + ++metric_x264_crf[0]; + } else if (pic.prop.f_crf_avg <= crf_buckets - 1) { + ++metric_x264_crf[int(floor(pic.prop.f_crf_avg))]; + } else { + // Just clamp; this isn't ideal, but at least the total count will be right. + ++metric_x264_crf[crf_buckets - 1]; + } + metric_x264_crf_sum = metric_x264_crf_sum + pic.prop.f_crf_avg; + if (frames_being_encoded.count(pic.i_pts)) { ReceivedTimestamps received_ts = frames_being_encoded[pic.i_pts]; frames_being_encoded.erase(pic.i_pts); diff --git a/x264_encoder.h b/x264_encoder.h index 973b62c..19ce1df 100644 --- a/x264_encoder.h +++ b/x264_encoder.h @@ -122,6 +122,10 @@ private: std::atomic metric_x264_output_frames_i{0}; std::atomic metric_x264_output_frames_p{0}; std::atomic metric_x264_output_frames_b{0}; + + static constexpr size_t crf_buckets = 50; + std::atomic metric_x264_crf[crf_buckets]{{0}}; + std::atomic metric_x264_crf_sum{0.0}; }; #endif // !defined(_X264ENCODE_H) diff --git a/x264_speed_control.cpp b/x264_speed_control.cpp index b6a60e9..c69d31e 100644 --- a/x264_speed_control.cpp +++ b/x264_speed_control.cpp @@ -40,7 +40,7 @@ X264SpeedControl::X264SpeedControl(x264_t *x264, float f_speed, int i_buffer_siz metric_x264_speedcontrol_buffer_available_seconds = buffer_fill * 1e-6; metric_x264_speedcontrol_buffer_size_seconds = buffer_size * 1e-6; - global_metrics.add_histogram("x264_speedcontrol_preset_used_frames", {}, metric_x264_speedcontrol_preset_used_frames, SC_PRESETS); + global_metrics.add_histogram("x264_speedcontrol_preset_used_frames", {}, metric_x264_speedcontrol_preset_used_frames, &metric_x264_speedcontrol_preset_used_frames_sum, SC_PRESETS); 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); @@ -338,4 +338,6 @@ void X264SpeedControl::apply_preset(int new_preset) preset = new_preset; ++metric_x264_speedcontrol_preset_used_frames[new_preset]; + // Non-atomic add, but that's fine, since there are no concurrent writers. + metric_x264_speedcontrol_preset_used_frames_sum = metric_x264_speedcontrol_preset_used_frames_sum + new_preset; } diff --git a/x264_speed_control.h b/x264_speed_control.h index 8a1f344..2a20414 100644 --- a/x264_speed_control.h +++ b/x264_speed_control.h @@ -133,6 +133,7 @@ private: // Metrics. std::atomic metric_x264_speedcontrol_preset_used_frames[SC_PRESETS]{{0}}; + std::atomic metric_x264_speedcontrol_preset_used_frames_sum{0.0}; std::atomic metric_x264_speedcontrol_buffer_available_seconds{0.0}; std::atomic metric_x264_speedcontrol_buffer_size_seconds{0.0}; std::atomic metric_x264_speedcontrol_idle_frames{0};