X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mixer.cpp;h=70175a163c4a2c9a51be1690a9c9c408ac16f81f;hb=9e47a2f661b9d292598ef0277e507458e3dad62f;hp=6ec12e88357b1430ef922cf3dad57d9407cd2e66;hpb=3fd3a00f3f70d28377c4d876746e1a8849e422bd;p=nageru diff --git a/mixer.cpp b/mixer.cpp index 6ec12e8..70175a1 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -51,6 +51,10 @@ #include "v210_converter.h" #include "video_encoder.h" +#undef Status +#include +#include "json.pb.h" + class IDeckLink; class QOpenGLContext; @@ -239,7 +243,7 @@ double JitterHistory::estimate_max_jitter() const if (percentile <= 0.5) { return *next(orders.begin(), elem_idx) * multiplier; } else { - return *prev(orders.end(), elem_idx + 1) * multiplier; + return *prev(orders.end(), orders.size() - elem_idx) * multiplier; } } @@ -352,8 +356,15 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards) // Must be instantiated after VideoEncoder has initialized global_flags.use_zerocopy. theme.reset(new Theme(global_flags.theme_filename, global_flags.theme_dirs, resource_pool.get(), num_cards)); + httpd.add_endpoint("/channels", bind(&Mixer::get_channels_json, this)); + for (int channel_idx = 2; channel_idx < theme->get_num_channels(); ++channel_idx) { + char url[256]; + snprintf(url, sizeof(url), "/channels/%d/color", channel_idx); + httpd.add_endpoint(url, bind(&Mixer::get_channel_color_http, this, unsigned(channel_idx))); + } + // Start listening for clients only once VideoEncoder has written its header, if any. - httpd.start(9095); + httpd.start(global_flags.http_port); // First try initializing the then PCI devices, then USB, then // fill up with fake cards until we have the desired number of cards. @@ -1096,6 +1107,24 @@ void Mixer::trim_queue(CaptureCard *card, size_t safe_queue_length) #endif } +pair Mixer::get_channels_json() +{ + Channels ret; + for (int channel_idx = 2; channel_idx < theme->get_num_channels(); ++channel_idx) { + Channel *channel = ret.add_channel(); + channel->set_index(channel_idx); + channel->set_name(theme->get_channel_name(channel_idx)); + channel->set_color(theme->get_channel_color(channel_idx)); + } + string contents; + google::protobuf::util::MessageToJsonString(ret, &contents); // Ignore any errors. + return make_pair(contents, "text/json"); +} + +pair Mixer::get_channel_color_http(unsigned channel_idx) +{ + return make_pair(theme->get_channel_color(channel_idx), "text/plain"); +} Mixer::OutputFrameInfo Mixer::get_one_frame_from_each_card(unsigned master_card_index, bool master_card_is_output, CaptureCard::NewFrame new_frames[MAX_VIDEO_CARDS], bool has_new_frame[MAX_VIDEO_CARDS]) { @@ -1390,18 +1419,18 @@ void Mixer::render_one_frame(int64_t duration) live_frame.ready_fence = fence; live_frame.input_frames = {}; live_frame.temp_textures = { y_display_tex, cbcr_display_tex }; - output_channel[OUTPUT_LIVE].output_frame(live_frame); + output_channel[OUTPUT_LIVE].output_frame(move(live_frame)); // Set up preview and any additional channels. for (int i = 1; i < theme->get_num_channels() + 2; ++i) { DisplayFrame display_frame; Theme::Chain chain = theme->get_chain(i, pts(), global_flags.width, global_flags.height, input_state); // FIXME: dimensions - display_frame.chain = chain.chain; - display_frame.setup_chain = chain.setup_chain; + display_frame.chain = move(chain.chain); + display_frame.setup_chain = move(chain.setup_chain); display_frame.ready_fence = fence; - display_frame.input_frames = chain.input_frames; + display_frame.input_frames = move(chain.input_frames); display_frame.temp_textures = {}; - output_channel[i].output_frame(display_frame); + output_channel[i].output_frame(move(display_frame)); } } @@ -1521,7 +1550,7 @@ Mixer::OutputChannel::~OutputChannel() } } -void Mixer::OutputChannel::output_frame(DisplayFrame frame) +void Mixer::OutputChannel::output_frame(DisplayFrame &&frame) { // Store this frame for display. Remove the ready frame if any // (it was seemingly never used). @@ -1530,7 +1559,7 @@ void Mixer::OutputChannel::output_frame(DisplayFrame frame) if (has_ready_frame) { parent->release_display_frame(&ready_frame); } - ready_frame = frame; + ready_frame = move(frame); has_ready_frame = true; // Call the callbacks under the mutex (they should be short), @@ -1593,7 +1622,7 @@ bool Mixer::OutputChannel::get_display_frame(DisplayFrame *frame) } if (has_ready_frame) { assert(!has_current_frame); - current_frame = ready_frame; + current_frame = move(ready_frame); ready_frame.ready_fence.reset(); // Drop the refcount. ready_frame.input_frames.clear(); // Drop the refcounts. has_current_frame = true;