]> git.sesse.net Git - nageru/blobdiff - ffmpeg_capture.h
Factor out rewinding code in its own member function.
[nageru] / ffmpeg_capture.h
index 8c75b4f705c25691bb2a967fc68c11b6d6ebeac0..095078267c1987d67e7e843ded7e90cb57641136 100644 (file)
 //
 // There is currently no audio support. There is also no support for changing
 // the video underway (unlike images), although there really should be.
-// Finally, there is currently no support for controlling the video from Lua.
 
 #include <assert.h>
 #include <stdint.h>
 #include <functional>
 #include <map>
 #include <memory>
+#include <mutex>
 #include <set>
 #include <string>
 #include <thread>
 
 #include "bmusb/bmusb.h"
+#include "quittable_sleeper.h"
 
 class FFmpegCapture : public bmusb::CaptureInterface
 {
@@ -48,6 +49,18 @@ public:
                return card_index;
        }
 
+       void rewind()
+       {
+               std::lock_guard<std::mutex> lock(queue_mu);
+               command_queue.push_back(QueuedCommand { QueuedCommand::REWIND });
+       }
+
+       void change_rate(double new_rate)
+       {
+               std::lock_guard<std::mutex> lock(queue_mu);
+               command_queue.push_back(QueuedCommand { QueuedCommand::CHANGE_RATE, new_rate });
+       }
+
        // CaptureInterface.
        void set_video_frame_allocator(bmusb::FrameAllocator *allocator) override
        {
@@ -128,6 +141,7 @@ public:
 private:
        void producer_thread_func();
        bool play_video(const std::string &pathname);
+       void internal_rewind();
 
        std::string description, filename;
        uint16_t timecode = 0;
@@ -145,8 +159,18 @@ private:
        std::unique_ptr<bmusb::FrameAllocator> owned_audio_frame_allocator;
        bmusb::frame_callback_t frame_callback = nullptr;
 
-       std::atomic<bool> producer_thread_should_quit{false};
+       QuittableSleeper producer_thread_should_quit;
        std::thread producer_thread;
+
+       int64_t pts_origin, last_pts;
+       std::chrono::steady_clock::time_point start, next_frame_start;
+
+       std::mutex queue_mu;
+       struct QueuedCommand {
+               enum Command { REWIND, CHANGE_RATE } command;
+               double new_rate;  // For CHANGE_RATE.
+       };
+       std::vector<QueuedCommand> command_queue;  // Protected by <queue_mu>.
 };
 
 #endif  // !defined(_FFMPEG_CAPTURE_H)