void mouseReleaseEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
+ // Public due to shared_ptr.
+ struct Frame {
+ unsigned width, height;
+ unsigned chroma_width, chroma_height;
+ VideoWidget *owner; // For the freelist.
+ GLuint pbo;
+ uint8_t *data; // Persistently mapped into the PBO. Y, followed by Cb, followed by Cr.
+ size_t need_flush_len; // 0 = no flush needed.
+ };
+
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.
- struct Frame {
- unsigned width, height;
- unsigned chroma_width, chroma_height;
- std::unique_ptr<uint8_t[]> data; // Y, followed by Cb, followed by Cr.
- };
+ std::shared_ptr<Frame> alloc_frame(unsigned width, unsigned height, unsigned chroma_width, unsigned chroma_height);
+ static void free_frame(Frame *frame);
+
std::mutex current_frame_mu;
std::shared_ptr<Frame> current_frame; // Protected by current_frame_mu.
+ std::mutex freelist_mu;
+ 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;
AVFrameWithDeleter decode_frame(AVFormatContext *format_ctx, AVCodecContext *video_codec_ctx,
const std::string &pathname, int video_stream_index,
bool *error);
- Frame make_video_frame(const AVFrame *frame);
+ std::shared_ptr<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);