]> git.sesse.net Git - nageru/blobdiff - ffmpeg_capture.h
Tiny comment pickiness.
[nageru] / ffmpeg_capture.h
index daf353eec6bdad339dc5e1ddbf87a4d36709726c..82ccfaf5a97aa810cbedab56c4690b2d1ff0f868 100644 (file)
@@ -6,7 +6,7 @@
 // FFmpeg (thus the name), this means it can handle a very wide array of video
 // formats, and also things like network streaming and V4L capture, but it is
 // also significantly less integrated and optimized than the regular capture
-// cards.  In particular, the frames are always scaled and converted to 8-bit
+// cards. In particular, the frames are always scaled and converted to 8-bit
 // RGBA on the CPU before being sent on to the GPU.
 //
 // Since we don't really know much about the video when building the chains,
@@ -17,9 +17,7 @@
 // CPU conversion), but it would require some more plumbing, and it would also
 // fail if the file changes parameters midway, which is allowed in some formats.
 //
-// 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.
+// There is currently no audio support.
 
 #include <assert.h>
 #include <stdint.h>
@@ -32,6 +30,7 @@
 #include <thread>
 
 #include "bmusb/bmusb.h"
+#include "quittable_sleeper.h"
 
 class FFmpegCapture : public bmusb::CaptureInterface
 {
@@ -55,6 +54,12 @@ public:
                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
        {
@@ -103,22 +108,20 @@ public:
        void configure_card() override;
        void start_bm_capture() override;
        void stop_dequeue_thread() override;
-
-       // TODO: Specify error status through this.
-       bool get_disconnected() const override { return false; }
+       bool get_disconnected() const override { return false; }  // We never unplug.
 
        std::map<uint32_t, bmusb::VideoMode> get_available_video_modes() const;
        void set_video_mode(uint32_t video_mode_id) override {}  // Ignore.
        uint32_t get_current_video_mode() const override { return 0; }
 
        std::set<bmusb::PixelFormat> get_available_pixel_formats() const override {
-               return std::set<bmusb::PixelFormat>{ bmusb::PixelFormat_8BitRGBA };
+               return std::set<bmusb::PixelFormat>{ bmusb::PixelFormat_8BitBGRA };
        }
        void set_pixel_format(bmusb::PixelFormat pixel_format) override {
-               assert(pixel_format == bmusb::PixelFormat_8BitRGBA);
+               assert(pixel_format == bmusb::PixelFormat_8BitBGRA);
        }       
        bmusb::PixelFormat get_current_pixel_format() const override {
-               return bmusb::PixelFormat_8BitRGBA;
+               return bmusb::PixelFormat_8BitBGRA;
        }
 
        std::map<uint32_t, std::string> get_available_video_inputs() const override {
@@ -134,7 +137,9 @@ public:
 
 private:
        void producer_thread_func();
+       void send_disconnected_frame();
        bool play_video(const std::string &pathname);
+       void internal_rewind();
 
        std::string description, filename;
        uint16_t timecode = 0;
@@ -152,12 +157,16 @@ 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 } command;
+               enum Command { REWIND, CHANGE_RATE } command;
+               double new_rate;  // For CHANGE_RATE.
        };
        std::vector<QueuedCommand> command_queue;  // Protected by <queue_mu>.
 };