queue.pop_front();
queued_frames = std::move(queue);
}
- current_frame.reset(new Frame(make_video_frame(frame.get())));
+ {
+ lock_guard lock(current_frame_mu);
+ current_frame.reset(new Frame(make_video_frame(frame.get())));
+ }
update();
store_pts(frame->pts);
break;
if (frame == nullptr || error) {
return true;
}
- current_frame.reset(new Frame(make_video_frame(frame.get())));
+ {
+ lock_guard lock(current_frame_mu);
+ current_frame.reset(new Frame(make_video_frame(frame.get())));
+ }
update();
store_pts(frame->pts);
}
void VideoWidget::paintGL()
{
- std::shared_ptr<Frame> frame = current_frame;
+ std::shared_ptr<Frame> frame;
+ {
+ lock_guard lock(current_frame_mu);
+ frame = current_frame;
+ }
if (frame == nullptr) {
glClear(GL_COLOR_BUFFER_BIT);
return;
bool finished_wakeup;
finished_wakeup = producer_thread_should_quit.sleep_until(next_frame_start);
if (finished_wakeup) {
- current_frame.reset(new Frame(make_video_frame(frame.get())));
+ {
+ lock_guard lock(current_frame_mu);
+ current_frame.reset(new Frame(make_video_frame(frame.get())));
+ }
last_frame = steady_clock::now();
update();
break;
if (paused) {
// Just paused, so present the frame immediately and then go into deep sleep.
- current_frame.reset(new Frame(make_video_frame(frame.get())));
+ {
+ lock_guard lock(current_frame_mu);
+ current_frame.reset(new Frame(make_video_frame(frame.get())));
+ }
last_frame = steady_clock::now();
update();
break;
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;