]> git.sesse.net Git - nageru/blobdiff - nageru/cef_encoder_adapter.h
Add CEF support to Kaeru.
[nageru] / nageru / cef_encoder_adapter.h
diff --git a/nageru/cef_encoder_adapter.h b/nageru/cef_encoder_adapter.h
new file mode 100644 (file)
index 0000000..989520c
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _CEF_ENCODER_ADAPTER
+#define _CEF_ENCODER_ADAPTER 1
+
+#include <stddef.h>
+#include <stdint.h>
+#include <bmusb/bmusb.h>
+#include <chrono>
+#include <optional>
+#include <mutex>
+#include <memory>
+
+#include "nageru/quittable_sleeper.h"
+#include "shared/ffmpeg_raii.h"
+
+extern "C" {
+#include <libavutil/rational.h>
+#include <libswscale/swscale.h>
+#include <libavutil/pixfmt.h>
+}
+
+class X264Encoder;
+class AudioEncoder;
+
+// For use in Kaeru, where we don't have a full mixer; converts the video data
+// from BGRA to NV12 (as CEF cannot produce NV12), and also deals with the fact
+// that CEF doesn't produce a steady stream of frames (see comments
+// on duplicate_frame_if_needed()).
+class CEFEncoderAdapter {
+public:
+       // Does not take ownership of the encoders.
+       CEFEncoderAdapter(unsigned width, unsigned height, X264Encoder *x264_encoder, AudioEncoder *audio_encoder)
+               : nv12_data(new uint8_t[width * height * 2]),
+                 sws_ctx(sws_getContext(width, height, AV_PIX_FMT_BGRA,
+                       width, height, AV_PIX_FMT_NV12,
+                       SWS_BICUBIC, nullptr, nullptr, nullptr)),
+                 x264_encoder(x264_encoder),
+                 audio_encoder(audio_encoder) {}
+
+       void video_frame_callback(uint16_t timecode,
+                                 bmusb::FrameAllocator::Frame video_frame, size_t video_offset, bmusb::VideoFormat video_format,
+                                 bmusb::FrameAllocator::Frame audio_frame, size_t audio_offset, bmusb::AudioFormat audio_format);
+       void duplicate_frame_if_needed(QuittableSleeper *should_quit);
+
+private:
+       std::optional<std::chrono::steady_clock::time_point> get_last_frame() const;
+
+       mutable std::mutex mu;  // Protects all data members.
+       std::unique_ptr<uint8_t[]> nv12_data;
+       SwsContextWithDeleter sws_ctx;
+       std::chrono::steady_clock::time_point start;
+       std::chrono::steady_clock::time_point last_frame;
+       bmusb::VideoFormat last_video_format;
+       bmusb::AudioFormat last_audio_format;
+       bool first_frame = true;
+       X264Encoder *x264_encoder;
+       AudioEncoder *audio_encoder;
+       static constexpr AVRational video_timebase{ 1, 1000000 };
+};
+
+#endif