+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.
+};
+