]> git.sesse.net Git - pkanalytics/blobdiff - video_widget.cpp
Propagate errors on video opening back to the UI.
[pkanalytics] / video_widget.cpp
index 7bafa64e4b0a00f444eecbb40b2ef09d776cf98f..e6708a9257cb8f4c5834fae55d720b94b1d826ae 100644 (file)
@@ -594,30 +594,40 @@ void VideoWidget::fixup_zoom_matrix()
        zoom_matrix[7] = std::max(zoom_matrix[7], 1.0 - zoom_matrix[4]);  // Top side (y=1).
 }
 
-void VideoWidget::open(const string &filename)
+bool VideoWidget::open(const string &filename)
 {
        stop();
        internal_rewind();
        pathname = filename;
        play();
+
+       while (running == STARTING) {
+               // Poor man's condition variable...
+               usleep(10000);
+               sched_yield();
+       }
+       return (running != VIDEO_FILE_ERROR);   
 }
 
 void VideoWidget::play()
 {
-       if (running) {
+       if (running != NOT_RUNNING && running != VIDEO_FILE_ERROR) {
                std::lock_guard<std::mutex> lock(queue_mu);
                command_queue.push_back(QueuedCommand { QueuedCommand::RESUME });
                producer_thread_should_quit.wakeup();
                return;
        }
-       running = true;
+       running = STARTING;
        producer_thread_should_quit.unquit();
+       if (producer_thread.joinable()) {
+               producer_thread.join();
+       }
        producer_thread = std::thread(&VideoWidget::producer_thread_func, this);
 }
 
 void VideoWidget::pause()
 {
-       if (!running) {
+       if (running == NOT_RUNNING || running == VIDEO_FILE_ERROR) {
                return;
        }
        std::lock_guard<std::mutex> lock(queue_mu);
@@ -627,7 +637,7 @@ void VideoWidget::pause()
 
 void VideoWidget::seek(int64_t relative_seek_ms)
 {
-       if (!running) {
+       if (running == NOT_RUNNING || running == VIDEO_FILE_ERROR) {
                return;
        }
        std::lock_guard<std::mutex> lock(queue_mu);
@@ -637,7 +647,7 @@ void VideoWidget::seek(int64_t relative_seek_ms)
 
 void VideoWidget::seek_frames(int64_t relative_seek_frames)
 {
-       if (!running) {
+       if (running == NOT_RUNNING || running == VIDEO_FILE_ERROR) {
                return;
        }
        std::lock_guard<std::mutex> lock(queue_mu);
@@ -647,7 +657,7 @@ void VideoWidget::seek_frames(int64_t relative_seek_frames)
 
 void VideoWidget::seek_absolute(int64_t position_ms)
 {
-       if (!running) {
+       if (running == NOT_RUNNING || running == VIDEO_FILE_ERROR) {
                return;
        }
        std::lock_guard<std::mutex> lock(queue_mu);
@@ -657,10 +667,9 @@ void VideoWidget::seek_absolute(int64_t position_ms)
 
 void VideoWidget::stop()
 {
-       if (!running) {
+       if (running == NOT_RUNNING || running == VIDEO_FILE_ERROR) {
                return;
        }
-       running = false;
        producer_thread_should_quit.quit();
        producer_thread.join();
 }
@@ -669,7 +678,9 @@ void VideoWidget::producer_thread_func()
 {
        if (!producer_thread_should_quit.should_quit()) {
                if (!play_video(pathname)) {
-                       // TODO: Send the error back to the UI somehow.
+                       running = VIDEO_FILE_ERROR;
+               } else {
+                       running = NOT_RUNNING;
                }
        }
 }
@@ -875,6 +886,8 @@ bool VideoWidget::play_video(const string &pathname)
 
        internal_rewind();
 
+       running = RUNNING;
+
        // Main loop.
        int consecutive_errors = 0;
        double rate = 1.0;