// changes parameters midway, which is allowed in some formats.
//
// You can get out the audio either as decoded or in raw form (Kaeru uses this).
-// However, the rest of Nageru can't really use the audio for anything yet.
#include <assert.h>
#include <stdint.h>
#include <libavresample/avresample.h>
#include <libavutil/pixfmt.h>
#include <libavutil/rational.h>
+#include <libavutil/samplefmt.h>
}
#include "bmusb/bmusb.h"
producer_thread_should_quit.wakeup();
}
+ std::string get_filename() const
+ {
+ std::lock_guard<std::mutex> lock(filename_mu);
+ return filename;
+ }
+
+ void change_filename(const std::string &new_filename)
+ {
+ std::lock_guard<std::mutex> lock(filename_mu);
+ filename = new_filename;
+ should_interrupt = true;
+ }
+
+ // Will stop the stream even if it's hung on blocking I/O.
+ void disconnect()
+ {
+ should_interrupt = true;
+ }
+
// CaptureInterface.
void set_video_frame_allocator(bmusb::FrameAllocator *allocator) override
{
bmusb::VideoFormat construct_video_format(const AVFrame *frame, AVRational video_timebase);
UniqueFrame make_video_frame(const AVFrame *frame, const std::string &pathname, bool *error);
+ static int interrupt_cb_thunk(void *unique);
+ int interrupt_cb();
+
+ mutable std::mutex filename_mu;
std::string description, filename;
uint16_t timecode = 0;
unsigned width, height;
bool running = false;
int card_index = -1;
double rate = 1.0;
+ std::atomic<bool> should_interrupt{false};
+ bool last_frame_was_connected = true;
bool has_dequeue_callbacks = false;
std::function<void()> dequeue_init_callback = nullptr;
std::thread producer_thread;
int64_t pts_origin, last_pts;
- std::chrono::steady_clock::time_point start, next_frame_start;
+ std::chrono::steady_clock::time_point start, next_frame_start, last_frame;
std::mutex queue_mu;
struct QueuedCommand {