From: Steinar H. Gunderson Date: Sun, 28 May 2017 13:52:53 +0000 (+0200) Subject: In FFmpegCapture, refactor command queue processing into its own function. X-Git-Tag: 1.6.0~6 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=0f5a145f0cd11cb043e1cefc6bf6187bdac31bbd In FFmpegCapture, refactor command queue processing into its own function. --- diff --git a/ffmpeg_capture.cpp b/ffmpeg_capture.cpp index 0fe74a7..b576877 100644 --- a/ffmpeg_capture.cpp +++ b/ffmpeg_capture.cpp @@ -370,7 +370,6 @@ bool FFmpegCapture::play_video(const string &pathname) codec_ctx.get(), avcodec_close); internal_rewind(); - double rate = 1.0; unique_ptr sws_ctx(nullptr, sws_freeContext); int sws_last_width = -1, sws_last_height = -1, sws_last_src_format = -1; @@ -378,34 +377,8 @@ bool FFmpegCapture::play_video(const string &pathname) // Main loop. while (!producer_thread_should_quit.should_quit()) { - // Process any queued commands from other threads. - vector commands; - { - lock_guard lock(queue_mu); - swap(commands, command_queue); - } - for (const QueuedCommand &cmd : commands) { - switch (cmd.command) { - case QueuedCommand::REWIND: - if (av_seek_frame(format_ctx.get(), /*stream_index=*/-1, /*timestamp=*/0, /*flags=*/0) < 0) { - fprintf(stderr, "%s: Rewind failed, stopping play.\n", pathname.c_str()); - } - // If the file has changed since last time, return to get it reloaded. - // Note that depending on how you move the file into place, you might - // end up corrupting the one you're already playing, so this path - // might not trigger. - if (changed_since(pathname, last_modified)) { - return true; - } - internal_rewind(); - break; - - case QueuedCommand::CHANGE_RATE: - start = next_frame_start; - pts_origin = last_pts; - rate = cmd.new_rate; - break; - } + if (process_queued_commands(format_ctx.get(), pathname, last_modified)) { + return true; } // Read packets until we have a frame or there are none left. @@ -549,3 +522,37 @@ void FFmpegCapture::internal_rewind() pts_origin = last_pts = 0; start = next_frame_start = steady_clock::now(); } + +bool FFmpegCapture::process_queued_commands(AVFormatContext *format_ctx, const std::string &pathname, timespec last_modified) +{ + // Process any queued commands from other threads. + vector commands; + { + lock_guard lock(queue_mu); + swap(commands, command_queue); + } + for (const QueuedCommand &cmd : commands) { + switch (cmd.command) { + case QueuedCommand::REWIND: + if (av_seek_frame(format_ctx, /*stream_index=*/-1, /*timestamp=*/0, /*flags=*/0) < 0) { + fprintf(stderr, "%s: Rewind failed, stopping play.\n", pathname.c_str()); + } + // If the file has changed since last time, return to get it reloaded. + // Note that depending on how you move the file into place, you might + // end up corrupting the one you're already playing, so this path + // might not trigger. + if (changed_since(pathname, last_modified)) { + return true; + } + internal_rewind(); + break; + + case QueuedCommand::CHANGE_RATE: + start = next_frame_start; + pts_origin = last_pts; + rate = cmd.new_rate; + break; + } + } + return false; +} diff --git a/ffmpeg_capture.h b/ffmpeg_capture.h index 0142610..cde99c4 100644 --- a/ffmpeg_capture.h +++ b/ffmpeg_capture.h @@ -33,6 +33,8 @@ #include "bmusb/bmusb.h" #include "quittable_sleeper.h" +struct AVFormatContext; + class FFmpegCapture : public bmusb::CaptureInterface { public: @@ -150,6 +152,9 @@ private: bool play_video(const std::string &pathname); void internal_rewind(); + // Returns true if there was an error. + bool process_queued_commands(AVFormatContext *format_ctx, const std::string &pathname, timespec last_modified); + std::string description, filename; uint16_t timecode = 0; unsigned width, height; @@ -157,6 +162,7 @@ private: movit::YCbCrFormat current_frame_ycbcr_format; bool running = false; int card_index = -1; + double rate = 1.0; bool has_dequeue_callbacks = false; std::function dequeue_init_callback = nullptr;