X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Fcef_encoder_adapter.h;fp=nageru%2Fcef_encoder_adapter.h;h=989520c74d42f4e3fcd18f9e2e2b990f51fbf334;hb=5963b81ab39d0509f42ed503cf5322147ebb1a7e;hp=0000000000000000000000000000000000000000;hpb=f1d22d113f924803ee0e0f33b81f0720f9378eae;p=nageru diff --git a/nageru/cef_encoder_adapter.h b/nageru/cef_encoder_adapter.h new file mode 100644 index 0000000..989520c --- /dev/null +++ b/nageru/cef_encoder_adapter.h @@ -0,0 +1,60 @@ +#ifndef _CEF_ENCODER_ADAPTER +#define _CEF_ENCODER_ADAPTER 1 + +#include +#include +#include +#include +#include +#include +#include + +#include "nageru/quittable_sleeper.h" +#include "shared/ffmpeg_raii.h" + +extern "C" { +#include +#include +#include +} + +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 get_last_frame() const; + + mutable std::mutex mu; // Protects all data members. + std::unique_ptr 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