VideoWidget(QWidget *parent);
~VideoWidget() { stop(); }
- void open(const std::string &filename);
+ bool open(const std::string &filename); // False on error.
void play();
uint64_t get_position() const { return last_position; } // In milliseconds.
void pause();
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.
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
signals:
void position_changed(uint64_t pos);
+ void mouse_back_clicked();
+ void mouse_forward_clicked();
private:
// Should really have been persistent and a PBO, but this is OK for now.
unsigned chroma_width, chroma_height;
std::unique_ptr<uint8_t[]> data; // Y, followed by Cb, followed by Cr.
};
- std::shared_ptr<Frame> current_frame;
+ std::mutex current_frame_mu;
+ std::shared_ptr<Frame> current_frame; // Protected by current_frame_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 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,
+ 0.0, 0.0, 1.0,
+ };
int64_t pts_origin;
int64_t last_pts;
std::atomic<uint64_t> last_position{0}; // TODO: sort of redundant wrt. last_pts (but this one can be read from the other thread)
- std::atomic<bool> running{false};
+ enum RunState { NOT_RUNNING, STARTING, RUNNING, VIDEO_FILE_ERROR }; // NOT_RUNNING and VIDEO_FILE_ERROR both imply that the thread isn't running and can freely be restarted.
+ std::atomic<RunState> running{NOT_RUNNING};
bool paused = false;
std::chrono::steady_clock::time_point start, next_frame_start, last_frame;
std::string pathname;
+ bool dragging = false;
+ float last_drag_x, last_drag_y;
+
void producer_thread_func();
bool play_video(const std::string &pathname);
void internal_rewind();
Frame make_video_frame(const AVFrame *frame);
bool process_queued_commands(AVFormatContext *format_ctx, AVCodecContext *video_codec_ctx, int video_stream_index, bool *seeked);
void store_pts(int64_t pts);
+
+ void fixup_zoom_matrix();
};
#endif // !defined(_VIDEO_WIDGET_H)