]> git.sesse.net Git - nageru/blobdiff - x264_encoder.h
Update the queue length metric after trimming, not before.
[nageru] / x264_encoder.h
index 2e64e66118328cd99e7240d5fcef22a257f7a0fe..2f9c81c4f51e91748680bb8f84234b4f313414e1 100644 (file)
@@ -3,15 +3,11 @@
 // so a little under 100 MB at 720p), then have a separate thread pull out
 // those threads as fast as we can to give it to x264 for encoding.
 //
-// TODO: We use x264's “speedcontrol” patch if available, so that quality is
-// automatically scaled up or down to content and available CPU time.
-//
 // The encoding threads are niced down because mixing is more important than
 // encoding; if we lose frames in mixing, we'll lose frames to disk _and_
 // to the stream, as where if we lose frames in encoding, we'll lose frames
 // to the stream only, so the latter is strictly better. More importantly,
-// this allows speedcontrol (when implemented) to do its thing without
-// disturbing the mixer.
+// this allows speedcontrol to do its thing without disturbing the mixer.
 
 #ifndef _X264ENCODE_H
 #define _X264ENCODE_H 1
@@ -28,6 +24,7 @@
 #include <string>
 #include <thread>
 #include <unordered_map>
+#include <vector>
 
 extern "C" {
 #include <libavformat/avformat.h>
@@ -35,7 +32,10 @@ extern "C" {
 
 #include <movit/image_format.h>
 
+#include "defs.h"
+#include "metrics.h"
 #include "print_latency.h"
+#include "x264_dynamic.h"
 
 class Mux;
 class X264SpeedControl;
@@ -49,7 +49,7 @@ public:
        ~X264Encoder();
 
        // Must be called before first frame. Does not take ownership.
-       void set_mux(Mux *mux) { this->mux = mux; }
+       void add_mux(Mux *mux) { muxes.push_back(mux); }
 
        // <data> is taken to be raw NV12 data of WIDTHxHEIGHT resolution.
        // Does not block.
@@ -82,7 +82,7 @@ private:
        // pool.
        std::unique_ptr<uint8_t[]> frame_pool;
 
-       Mux *mux = nullptr;
+       std::vector<Mux *> muxes;
        bool wants_global_headers;
 
        std::string global_headers;
@@ -91,6 +91,7 @@ private:
        std::thread encoder_thread;
        std::atomic<bool> x264_init_done{false};
        std::atomic<bool> should_quit{false};
+       X264Dynamic dyn;
        x264_t *x264;
        std::unique_ptr<X264SpeedControl> speed_control;
 
@@ -114,6 +115,16 @@ private:
 
        // Key is the pts of the frame.
        std::unordered_map<int64_t, ReceivedTimestamps> frames_being_encoded;
+
+       // Metrics.
+       std::atomic<int64_t> metric_x264_queued_frames{0};
+       std::atomic<int64_t> metric_x264_max_queued_frames{X264_QUEUE_LENGTH};
+       std::atomic<int64_t> metric_x264_dropped_frames{0};
+       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};
+       Histogram metric_x264_crf;
+       LatencyHistogram latency_histogram;
 };
 
 #endif  // !defined(_X264ENCODE_H)