]> git.sesse.net Git - pkanalytics/blobdiff - video_widget.h
Support filtering passes by thrower and receiver.
[pkanalytics] / video_widget.h
index 30b4b9b4747343258cc3da68aa7ba8148e72a67b..8d823d8ed69e118fdf47e7ecbe1346b0dc321b5b 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef _VIDEO_WIDGET_H
 #define _VIDEO_WIDGET_H 1
 
-#include <QOpenGLWidget>
+#include <QWidget>
+#include <QOpenGLWindow>
 #include <string>
 #include <atomic>
 #include <thread>
@@ -16,14 +17,18 @@ extern "C" {
 #include "ffmpeg_raii.h"
 #include "quittable_sleeper.h"
 
+class QOpenGLFunctions_4_5_Compatibility;
+
 // Because QVideoWidget sucks, sadly. (Don't use GStreamer, kids.)
 
-class VideoWidget : public QOpenGLWidget {
+class VideoWindow;
+
+class VideoWidget : public QWidget {
        Q_OBJECT
 
 public:
        VideoWidget(QWidget *parent);
-       ~VideoWidget() { stop(); }
+       ~VideoWidget();
 
        bool open(const std::string &filename);  // False on error.
        void play();
@@ -34,9 +39,6 @@ public:
        void seek_frames(int64_t relative_frames);  // Relative seek.
        void seek_absolute(int64_t position_ms);  // Absolute seek.
 
-       void initializeGL() override;
-       void resizeGL(int w, int h) override;
-       void paintGL() override;
        void wheelEvent(QWheelEvent *event) override;
 
        // For dragging, and for back/forward button presses.
@@ -44,7 +46,7 @@ public:
        void mouseReleaseEvent(QMouseEvent *e);
        void mouseMoveEvent(QMouseEvent *e);
 
-       // public due to shared_ptr.
+       // Public due to shared_ptr.
        struct Frame {
                unsigned width, height;
                unsigned chroma_width, chroma_height;
@@ -69,14 +71,6 @@ private:
        std::deque<Frame *> frame_freelist;  // Protected by freelist_mu.
        std::deque<AVFrameWithDeleter> queued_frames;  // Frames decoded but not displayed. Only used when frame-stepping backwards.
 
-       GLuint ycbcr_vertex_shader, ycbcr_fragment_shader, ycbcr_program;
-       GLuint bilinear_sampler;
-
-       GLuint tex[3];
-       GLuint last_width = 0, last_height = 0;
-       GLuint last_chroma_width = 0, last_chroma_height = 0;
-       GLfloat cbcr_offset[2];
-       double display_aspect = 1.0;
        double zoom_matrix[9] = {  // Column-major, to match with OpenGL.
                1.0, 0.0, 0.0,
                0.0, 1.0, 0.0,
@@ -113,6 +107,8 @@ private:
        bool dragging = false;
        float last_drag_x, last_drag_y;
 
+       VideoWindow *video_window;
+
        void producer_thread_func();
        bool play_video(const std::string &pathname);
        void internal_rewind();
@@ -126,4 +122,55 @@ private:
        void fixup_zoom_matrix();
 };
 
+class VideoWindow : public QOpenGLWindow {  // Private implementation of VideoWidget, but moc does not support nested classes.
+       Q_OBJECT;
+
+public:
+       VideoWindow(VideoWidget *video) : video(video) {}
+       void initializeGL() override;
+       void resizeGL(int w, int h) override;
+       void paintGL() override;
+       void set_current_frame(std::shared_ptr<VideoWidget::Frame> new_frame);  // Takes ownership. Thread-safe.
+       void set_cbcr_offset(float x, float y)  // FIXME: Thread-safe?
+       {
+               cbcr_offset[0] = x;
+               cbcr_offset[1] = y;
+       }
+       void set_zoom_matrix(double new_zoom_matrix[9]) {
+               memcpy(zoom_matrix, new_zoom_matrix, sizeof(zoom_matrix));
+               update();
+       }
+
+       void wheelEvent(QWheelEvent *e) override { emit mouse_wheel(e); }
+       void mousePressEvent(QMouseEvent *e) override { emit mouse_pressed(e); }
+       void mouseReleaseEvent(QMouseEvent *e) override { emit mouse_released(e); }
+       void mouseMoveEvent(QMouseEvent *e) override { emit mouse_moved(e); }
+
+signals:
+       void mouse_wheel(QWheelEvent *e);
+       void mouse_pressed(QMouseEvent *e);
+       void mouse_released(QMouseEvent *e);
+       void mouse_moved(QMouseEvent *e);
+
+private:
+       QOpenGLFunctions_4_5_Compatibility *gl = nullptr;
+       VideoWidget *video;
+       GLuint ycbcr_vertex_shader, ycbcr_fragment_shader, ycbcr_program;
+       GLuint bilinear_sampler;
+       GLuint tex[3];
+       GLuint last_width = 0, last_height = 0;
+       GLuint last_chroma_width = 0, last_chroma_height = 0;
+       double display_aspect = 1.0;
+       GLfloat cbcr_offset[2];
+
+       double zoom_matrix[9] = {  // Column-major, to match with OpenGL.
+               1.0, 0.0, 0.0,
+               0.0, 1.0, 0.0,
+               0.0, 0.0, 1.0,
+       };
+
+       std::mutex current_frame_mu;
+       std::shared_ptr<VideoWidget::Frame> current_frame;  // Protected by current_frame_mu.
+};
+
 #endif  // !defined(_VIDEO_WIDGET_H)