#include "basic_stats.h"
#include "bmusb/bmusb.h"
#include "bmusb/fake_capture.h"
+#ifdef HAVE_CEF
#include "cef_capture.h"
+#endif
#include "chroma_subsampler.h"
#include "context.h"
#include "decklink_capture.h"
}
num_video_inputs = video_inputs.size();
+#ifdef HAVE_CEF
// Same, for HTML inputs.
std::vector<CEFCapture *> html_inputs = theme->get_html_inputs();
for (unsigned html_card_index = 0; html_card_index < html_inputs.size(); ++card_index, ++html_card_index) {
html_inputs[html_card_index]->set_card_index(card_index);
}
num_html_inputs = html_inputs.size();
+#endif
BMUSBCapture::set_card_connected_callback(bind(&Mixer::bm_hotplug_add, this, _1));
BMUSBCapture::start_bm_thread();
}
card->capture.reset(capture);
card->is_fake_capture = (card_type == CardType::FAKE_CAPTURE);
+ card->is_cef_capture = (card_type == CardType::CEF_INPUT);
+ card->may_have_dropped_last_frame = false;
card->type = card_type;
if (card->output.get() != output) {
card->output.reset(output);
new_frame.received_timestamp = video_frame.received_timestamp; // Ignore the audio timestamp.
card->new_frames.push_back(move(new_frame));
card->jitter_history.frame_arrived(video_frame.received_timestamp, frame_length, dropped_frames);
+ card->may_have_dropped_last_frame = false;
}
card->new_frames_changed.notify_all();
}
card->new_frames_changed.notify_all();
--queue_length;
++dropped_frames;
+
+ if (queue_length == 0 && card->is_cef_capture) {
+ card->may_have_dropped_last_frame = true;
+ }
}
card->metric_input_dropped_frames_jitter += dropped_frames;
CaptureCard *card = &cards[card_index];
if (card->new_frames.empty()) { // Starvation.
++card->metric_input_duped_frames;
+ if (card->is_cef_capture && card->may_have_dropped_last_frame) {
+ // Unlike other sources, CEF is not guaranteed to send us a steady
+ // stream of frames, so we'll have to ask it to repaint the frame
+ // we dropped. (may_have_dropped_last_frame is set whenever we
+ // trim the queue completely away, and cleared when we actually
+ // get a new frame.)
+ ((CEFCapture *)card->capture.get())->request_new_frame();
+ }
} else {
new_frames[card_index] = move(card->new_frames.front());
has_new_frame[card_index] = true;
for (const pair<LiveInputWrapper *, FFmpegCapture *> &conn : theme->get_video_signal_connections()) {
conn.first->connect_signal_raw(conn.second->get_card_index(), input_state);
}
+#ifdef HAVE_CEF
for (const pair<LiveInputWrapper *, CEFCapture *> &conn : theme->get_html_signal_connections()) {
conn.first->connect_signal_raw(conn.second->get_card_index(), input_state);
}
+#endif
// If HDMI/SDI output is active and the user has requested auto mode,
// its mode overrides the existing Y'CbCr setting for the chain.