X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=video_widget.h;h=4361d3098c8f3fd2d6414d69ebd868f32a3f2ed6;hb=a41db5d218a10c7863952d98eea1daab9f8d0171;hp=e3734f0e5e40c9a08e8437ad39a5cd38001fb02d;hpb=9f71720832fbfdfeb1df6bacdb1cb32f8f13d9a8;p=pkanalytics diff --git a/video_widget.h b/video_widget.h index e3734f0..4361d30 100644 --- a/video_widget.h +++ b/video_widget.h @@ -1,7 +1,8 @@ #ifndef _VIDEO_WIDGET_H #define _VIDEO_WIDGET_H 1 -#include +#include +#include #include #include #include @@ -18,7 +19,9 @@ extern "C" { // Because QVideoWidget sucks, sadly. (Don't use GStreamer, kids.) -class VideoWidget : public QOpenGLWidget { +class VideoWindow; + +class VideoWidget : public QWidget { Q_OBJECT public: @@ -34,9 +37,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. @@ -69,14 +69,6 @@ private: std::deque frame_freelist; // Protected by freelist_mu. std::deque 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 +105,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 +120,54 @@ 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 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: + 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 current_frame; // Protected by current_frame_mu. +}; + #endif // !defined(_VIDEO_WIDGET_H)