]> git.sesse.net Git - nageru/blob - nageru/cef_encoder_adapter.h
Add CEF support to Kaeru.
[nageru] / nageru / cef_encoder_adapter.h
1 #ifndef _CEF_ENCODER_ADAPTER
2 #define _CEF_ENCODER_ADAPTER 1
3
4 #include <stddef.h>
5 #include <stdint.h>
6 #include <bmusb/bmusb.h>
7 #include <chrono>
8 #include <optional>
9 #include <mutex>
10 #include <memory>
11
12 #include "nageru/quittable_sleeper.h"
13 #include "shared/ffmpeg_raii.h"
14
15 extern "C" {
16 #include <libavutil/rational.h>
17 #include <libswscale/swscale.h>
18 #include <libavutil/pixfmt.h>
19 }
20
21 class X264Encoder;
22 class AudioEncoder;
23
24 // For use in Kaeru, where we don't have a full mixer; converts the video data
25 // from BGRA to NV12 (as CEF cannot produce NV12), and also deals with the fact
26 // that CEF doesn't produce a steady stream of frames (see comments
27 // on duplicate_frame_if_needed()).
28 class CEFEncoderAdapter {
29 public:
30         // Does not take ownership of the encoders.
31         CEFEncoderAdapter(unsigned width, unsigned height, X264Encoder *x264_encoder, AudioEncoder *audio_encoder)
32                 : nv12_data(new uint8_t[width * height * 2]),
33                   sws_ctx(sws_getContext(width, height, AV_PIX_FMT_BGRA,
34                         width, height, AV_PIX_FMT_NV12,
35                         SWS_BICUBIC, nullptr, nullptr, nullptr)),
36                   x264_encoder(x264_encoder),
37                   audio_encoder(audio_encoder) {}
38
39         void video_frame_callback(uint16_t timecode,
40                                   bmusb::FrameAllocator::Frame video_frame, size_t video_offset, bmusb::VideoFormat video_format,
41                                   bmusb::FrameAllocator::Frame audio_frame, size_t audio_offset, bmusb::AudioFormat audio_format);
42         void duplicate_frame_if_needed(QuittableSleeper *should_quit);
43
44 private:
45         std::optional<std::chrono::steady_clock::time_point> get_last_frame() const;
46
47         mutable std::mutex mu;  // Protects all data members.
48         std::unique_ptr<uint8_t[]> nv12_data;
49         SwsContextWithDeleter sws_ctx;
50         std::chrono::steady_clock::time_point start;
51         std::chrono::steady_clock::time_point last_frame;
52         bmusb::VideoFormat last_video_format;
53         bmusb::AudioFormat last_audio_format;
54         bool first_frame = true;
55         X264Encoder *x264_encoder;
56         AudioEncoder *audio_encoder;
57         static constexpr AVRational video_timebase{ 1, 1000000 };
58 };
59
60 #endif