]> git.sesse.net Git - nageru/commitdiff
Add a histogram of output crf values from x264.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 11 Jun 2017 14:35:46 +0000 (16:35 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 11 Jun 2017 14:35:50 +0000 (16:35 +0200)
metrics.cpp
metrics.h
x264_encoder.cpp
x264_encoder.h
x264_speed_control.cpp
x264_speed_control.h

index 2874ad42a8a70260bfb038b7f9320d3aa1880cfb..3b3d1eb2217e6b2aadbdb4e922811de864161d12 100644 (file)
@@ -57,12 +57,13 @@ void Metrics::add(const string &name, const vector<pair<string, string>> &labels
        types[name] = type;
 }
 
-void Metrics::add_histogram(const string &name, const vector<pair<string, string>> &labels, atomic<int64_t> *location, size_t num_elements)
+void Metrics::add_histogram(const string &name, const vector<pair<string, string>> &labels, atomic<int64_t> *first_bucket_location, atomic<double> *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<mutex> 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<pair<string, string>> 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";
        }
 
index 2a19e259cc32bf4df11c1eb779d6339b16382fd9..c1239a6e14fb895494215c77f02b6162d49128dc 100644 (file)
--- a/metrics.h
+++ b/metrics.h
@@ -33,7 +33,7 @@ public:
        void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<double> *location, Type type = TYPE_COUNTER);
 
        // Only integer histogram, ie. keys are 0..(N-1).
-       void add_histogram(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<int64_t> *location, size_t num_elements);
+       void add_histogram(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<int64_t> *first_bucket_location, std::atomic<double> *sum_location, size_t num_elements);
 
        std::string serialize() const;
 
@@ -57,7 +57,8 @@ private:
        struct Histogram {
                std::string name;
                std::vector<std::pair<std::string, std::string>> labels;
-               std::atomic<int64_t> *location_int64;  // First bucket.
+               std::atomic<int64_t> *first_bucket_location;
+               std::atomic<double> *sum_location;
                size_t num_elements;
        };
 
index 3a3151068dfad9333efa46bec795f754f2e15c30..9d108a0604989a87d4898dd970071a3495136bd3 100644 (file)
@@ -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);
index 973b62ce5ba5353d74b82cf2b72f869a24325199..19ce1dfb7ac2e946ad00b921675267fcd1be6cf0 100644 (file)
@@ -122,6 +122,10 @@ private:
        std::atomic<int64_t> metric_x264_output_frames_i{0};
        std::atomic<int64_t> metric_x264_output_frames_p{0};
        std::atomic<int64_t> metric_x264_output_frames_b{0};
+
+       static constexpr size_t crf_buckets = 50;
+       std::atomic<int64_t> metric_x264_crf[crf_buckets]{{0}};
+        std::atomic<double> metric_x264_crf_sum{0.0};
 };
 
 #endif  // !defined(_X264ENCODE_H)
index b6a60e97b877a566331bec7f7c99a578321af1c8..c69d31e2f43f385b5d7af8a455758799a2005ef1 100644 (file)
@@ -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;
 }
index 8a1f344db847cc2d8daaf5747378ede9cbee96d6..2a20414089450d78b9c03ad15f2ed967250010d5 100644 (file)
@@ -133,6 +133,7 @@ private:
 
        // Metrics.
        std::atomic<int64_t> metric_x264_speedcontrol_preset_used_frames[SC_PRESETS]{{0}};
+       std::atomic<double> metric_x264_speedcontrol_preset_used_frames_sum{0.0};
        std::atomic<double> metric_x264_speedcontrol_buffer_available_seconds{0.0};
        std::atomic<double> metric_x264_speedcontrol_buffer_size_seconds{0.0};
        std::atomic<int64_t> metric_x264_speedcontrol_idle_frames{0};