]> git.sesse.net Git - nageru/blobdiff - mixer.cpp
Tiny comment pickiness.
[nageru] / mixer.cpp
index c21ac95943bcbbaa7a6b97e4def90bf6d70770ea..1a76ac39c5c4226bab61b22b7af0f0ae0f841c18 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -206,6 +206,7 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards)
          mixer_surface(create_surface(format)),
          h264_encoder_surface(create_surface(format)),
          decklink_output_surface(create_surface(format)),
+         ycbcr_interpretation(global_flags.ycbcr_interpretation),
          audio_mixer(num_cards)
 {
        CHECK(init_movit(MOVIT_SHADER_DIR, MOVIT_DEBUG_OFF));
@@ -1081,6 +1082,17 @@ void Mixer::render_one_frame(int64_t duration)
                printf("Timecode: '%s'\n", timecode_text.c_str());
        }
 
+       // Update Y'CbCr settings for all cards.
+       {
+               unique_lock<mutex> lock(card_mutex);
+               for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
+                       YCbCrInterpretation *interpretation = &ycbcr_interpretation[card_index];
+                       input_state.ycbcr_coefficients_auto[card_index] = interpretation->ycbcr_coefficients_auto;
+                       input_state.ycbcr_coefficients[card_index] = interpretation->ycbcr_coefficients;
+                       input_state.full_range[card_index] = interpretation->full_range;
+               }
+       }
+
        // Get the main chain from the theme, and set its state immediately.
        Theme::Chain theme_main_chain = theme->get_chain(0, pts(), global_flags.width, global_flags.height, input_state);
        EffectChain *chain = theme_main_chain.chain;
@@ -1282,6 +1294,18 @@ void Mixer::channel_clicked(int preview_num)
        theme->channel_clicked(preview_num);
 }
 
+YCbCrInterpretation Mixer::get_input_ycbcr_interpretation(unsigned card_index) const
+{
+       unique_lock<mutex> lock(card_mutex);
+       return ycbcr_interpretation[card_index];
+}
+
+void Mixer::set_input_ycbcr_interpretation(unsigned card_index, const YCbCrInterpretation &interpretation)
+{
+       unique_lock<mutex> lock(card_mutex);
+       ycbcr_interpretation[card_index] = interpretation;
+}
+
 void Mixer::start_mode_scanning(unsigned card_index)
 {
        assert(card_index < num_cards);
@@ -1327,10 +1351,12 @@ void Mixer::OutputChannel::output_frame(DisplayFrame frame)
                }
                ready_frame = frame;
                has_ready_frame = true;
-       }
 
-       if (new_frame_ready_callback) {
-               new_frame_ready_callback();
+               // Call the callbacks under the mutex (they should be short),
+               // so that we don't race against a callback removal.
+               for (const auto &key_and_callback : new_frame_ready_callbacks) {
+                       key_and_callback.second();
+               }
        }
 
        // Reduce the number of callbacks by filtering duplicates. The reason
@@ -1397,9 +1423,16 @@ bool Mixer::OutputChannel::get_display_frame(DisplayFrame *frame)
        return true;
 }
 
-void Mixer::OutputChannel::set_frame_ready_callback(Mixer::new_frame_ready_callback_t callback)
+void Mixer::OutputChannel::add_frame_ready_callback(void *key, Mixer::new_frame_ready_callback_t callback)
 {
-       new_frame_ready_callback = callback;
+       unique_lock<mutex> lock(frame_mutex);
+       new_frame_ready_callbacks[key] = callback;
+}
+
+void Mixer::OutputChannel::remove_frame_ready_callback(void *key)
+{
+       unique_lock<mutex> lock(frame_mutex);
+       new_frame_ready_callbacks.erase(key);
 }
 
 void Mixer::OutputChannel::set_transition_names_updated_callback(Mixer::transition_names_updated_callback_t callback)