]> git.sesse.net Git - nageru/commitdiff
Add a preview display to the frame analyzer window.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 8 May 2017 21:58:02 +0000 (23:58 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 8 May 2017 21:58:23 +0000 (23:58 +0200)
analyzer.cpp
analyzer.h
glwidget.cpp
glwidget.h
mixer.cpp
mixer.h
ui_analyzer.ui

index 353229ee730f10c6562257fd679b1a58842d613a..2ed00f149b1d06924ca7576da16e47e299949d89 100644 (file)
@@ -30,7 +30,9 @@ Analyzer::Analyzer()
        }
 
        connect(ui->grab_btn, &QPushButton::clicked, bind(&Analyzer::grab_clicked, this));
-       //ui->display->set_output(Mixer::OUTPUT_LIVE);
+       connect(ui->input_box, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), bind(&Analyzer::signal_changed, this));
+       signal_changed();
+
        surface = create_surface(QSurfaceFormat::defaultFormat());
        context = create_context(surface);
 
@@ -143,3 +145,8 @@ void Analyzer::grab_clicked()
        check_error();
 }
 
+void Analyzer::signal_changed()
+{
+       Mixer::Output channel = static_cast<Mixer::Output>(ui->input_box->currentData().value<int>());
+       ui->display->set_output(channel);
+}
index d239c0e9da89318d958abf8ced26d2224c058474..3cefdc90991969c990e1385a93c6738e463aad99 100644 (file)
@@ -28,6 +28,7 @@ public:
 
 private:
        void grab_clicked();
+       void signal_changed();
 
        Ui::Analyzer *ui;
        QSurface *surface;
index 27f290db351b755d7e255c174f7ca468589ef624..43517fa882cc988e9f66ca66996a9b785d18cff3 100644 (file)
@@ -40,6 +40,11 @@ GLWidget::GLWidget(QWidget *parent)
 {
 }
 
+GLWidget::~GLWidget()
+{
+       global_mixer->remove_frame_ready_callback(output, this);
+}
+
 void GLWidget::clean_context()
 {
        if (resource_pool != nullptr) {
@@ -57,7 +62,7 @@ void GLWidget::initializeGL()
                global_mainwindow->mixer_created(global_mixer);
                global_mixer->start();
        });
-       global_mixer->set_frame_ready_callback(output, [this]{
+       global_mixer->add_frame_ready_callback(output, this, [this]{
                QMetaObject::invokeMethod(this, "update", Qt::AutoConnection);
        });
        if (output == Mixer::OUTPUT_LIVE) {
index 9095e4894f2a11e062b2a1453b89a50f22c80a50..12757fc5bcbc97dbef4535657fa450ef4881b531 100644 (file)
@@ -30,6 +30,7 @@ class GLWidget : public QGLWidget
 
 public:
        GLWidget(QWidget *parent = 0);
+       ~GLWidget();
 
        void set_output(Mixer::Output output)
        {
index c21ac95943bcbbaa7a6b97e4def90bf6d70770ea..31328212a24dc8a571a758794a82305504d5719c 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -1327,10 +1327,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 +1399,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)
diff --git a/mixer.h b/mixer.h
index 5fb195ec77793faf0a8e9d3989758caf6650b7de..6828bc66364d27d20d9f0a264816d29d42293882 100644 (file)
--- a/mixer.h
+++ b/mixer.h
@@ -139,10 +139,17 @@ public:
                return output_channel[output].get_display_frame(frame);
        }
 
+       // NOTE: Callbacks will be called with a mutex held, so you should probably
+       // not do real work in them.
        typedef std::function<void()> new_frame_ready_callback_t;
-       void set_frame_ready_callback(Output output, new_frame_ready_callback_t callback)
+       void add_frame_ready_callback(Output output, void *key, new_frame_ready_callback_t callback)
        {
-               output_channel[output].set_frame_ready_callback(callback);
+               output_channel[output].add_frame_ready_callback(key, callback);
+       }
+
+       void remove_frame_ready_callback(Output output, void *key)
+       {
+               output_channel[output].remove_frame_ready_callback(key);
        }
 
        // TODO: Should this really be per-channel? Shouldn't it just be called for e.g. the live output?
@@ -457,7 +464,8 @@ private:
                ~OutputChannel();
                void output_frame(DisplayFrame frame);
                bool get_display_frame(DisplayFrame *frame);
-               void set_frame_ready_callback(new_frame_ready_callback_t callback);
+               void add_frame_ready_callback(void *key, new_frame_ready_callback_t callback);
+               void remove_frame_ready_callback(void *key);
                void set_transition_names_updated_callback(transition_names_updated_callback_t callback);
                void set_name_updated_callback(name_updated_callback_t callback);
                void set_color_updated_callback(color_updated_callback_t callback);
@@ -470,7 +478,7 @@ private:
                std::mutex frame_mutex;
                DisplayFrame current_frame, ready_frame;  // protected by <frame_mutex>
                bool has_current_frame = false, has_ready_frame = false;  // protected by <frame_mutex>
-               new_frame_ready_callback_t new_frame_ready_callback;
+               std::map<void *, new_frame_ready_callback_t> new_frame_ready_callbacks;  // protected by <frame_mutex>
                transition_names_updated_callback_t transition_names_updated_callback;
                name_updated_callback_t name_updated_callback;
                color_updated_callback_t color_updated_callback;
index 254014f098f9ce9018fd6e8f6c85cf57e3851eef..b43345add8ec12b6c9523d01d3b7ed9c72f91fdd 100644 (file)
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
+  <widget class="GLWidget" name="display" native="true">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>320</width>
+     <height>180</height>
+    </rect>
+   </property>
+   <property name="autoFillBackground">
+    <bool>false</bool>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">background: rgb(233, 185, 110)</string>
+   </property>
+  </widget>
   <widget class="QComboBox" name="input_box">
    <property name="geometry">
     <rect>
    </property>
   </widget>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>GLWidget</class>
+   <extends>QWidget</extends>
+   <header>glwidget.h</header>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>