8 #include "cef_capture.h"
9 #include "nageru_cef_app.h"
13 #include <cef_browser.h>
14 #include <cef_client.h>
16 #include "bmusb/bmusb.h"
19 using namespace std::chrono;
20 using namespace bmusb;
22 extern CefRefPtr<NageruCefApp> cef_app;
24 CEFCapture::CEFCapture(const string &url, unsigned width, unsigned height)
25 : cef_client(new NageruCEFClient(width, height, this)),
31 snprintf(buf, sizeof(buf), "CEF card %d", card_index + 1);
35 CEFCapture::~CEFCapture()
37 if (has_dequeue_callbacks) {
38 dequeue_cleanup_callback();
42 void CEFCapture::OnPaint(const void *buffer, int width, int height)
44 steady_clock::time_point timestamp = steady_clock::now();
46 VideoFormat video_format;
47 video_format.width = width;
48 video_format.height = height;
49 video_format.stride = width * 4;
50 video_format.frame_rate_nom = 60; // FIXME
51 video_format.frame_rate_den = 1;
52 video_format.has_signal = true;
53 video_format.is_connected = true;
55 FrameAllocator::Frame video_frame = video_frame_allocator->alloc_frame();
56 if (video_frame.data != nullptr) {
57 assert(video_frame.size >= unsigned(width * height * 4));
58 assert(!video_frame.interleaved);
59 memcpy(video_frame.data, buffer, width * height * 4);
60 video_frame.len = video_format.stride * height;
61 video_frame.received_timestamp = timestamp;
63 frame_callback(timecode++,
64 video_frame, 0, video_format,
65 FrameAllocator::Frame(), 0, AudioFormat());
68 #define FRAME_SIZE (8 << 20) // 8 MB.
70 void CEFCapture::configure_card()
72 if (video_frame_allocator == nullptr) {
73 owned_video_frame_allocator.reset(new MallocFrameAllocator(FRAME_SIZE, NUM_QUEUED_VIDEO_FRAMES));
74 set_video_frame_allocator(owned_video_frame_allocator.get());
78 void CEFCapture::start_bm_capture()
80 cef_app->initialize_cef();
82 CefBrowserSettings browser_settings;
83 browser_settings.web_security = cef_state_t::STATE_DISABLED;
84 browser_settings.webgl = cef_state_t::STATE_ENABLED;
85 browser_settings.windowless_frame_rate = 60;
87 CefWindowInfo window_info;
88 window_info.SetAsWindowless(0);
89 CefBrowserHost::CreateBrowser(window_info, cef_client, start_url, browser_settings, nullptr);
92 void CEFCapture::stop_dequeue_thread()
94 lock_guard<mutex> lock(browser_mutex);
95 cef_app->close_browser(browser);
96 browser = nullptr; // Or unref_cef() will be sad.
100 std::map<uint32_t, VideoMode> CEFCapture::get_available_video_modes() const
105 snprintf(buf, sizeof(buf), "%ux%u", width, height);
108 mode.autodetect = false;
110 mode.height = height;
111 mode.frame_rate_num = 60; // FIXME
112 mode.frame_rate_den = 1;
113 mode.interlaced = false;
115 return {{ 0, mode }};
118 std::map<uint32_t, std::string> CEFCapture::get_available_video_inputs() const
120 return {{ 0, "HTML video input" }};
123 std::map<uint32_t, std::string> CEFCapture::get_available_audio_inputs() const
125 return {{ 0, "Fake HTML audio input (silence)" }};
128 void CEFCapture::set_video_mode(uint32_t video_mode_id)
130 assert(video_mode_id == 0);
133 void CEFCapture::set_video_input(uint32_t video_input_id)
135 assert(video_input_id == 0);
138 void CEFCapture::set_audio_input(uint32_t audio_input_id)
140 assert(audio_input_id == 0);
143 void NageruCEFClient::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height)
145 parent->OnPaint(buffer, width, height);
148 bool NageruCEFClient::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect &rect)
150 rect = CefRect(0, 0, width, height);