fwrite(audio_start + AUDIO_HEADER_SIZE, 1, audio_len - AUDIO_HEADER_SIZE, audiofp);
}
-void BMUSBCapture::dequeue_thread()
+void BMUSBCapture::dequeue_thread_func()
{
if (has_dequeue_callbacks) {
dequeue_init_callback();
}
- for ( ;; ) {
+ while (!dequeue_thread_should_quit) {
unique_lock<mutex> lock(queue_lock);
- queues_not_empty.wait(lock, [this]{ return !pending_video_frames.empty() && !pending_audio_frames.empty(); });
+ queues_not_empty.wait(lock, [this]{ return dequeue_thread_should_quit || (!pending_video_frames.empty() && !pending_audio_frames.empty()); });
uint16_t video_timecode = pending_video_frames.front().timecode;
uint16_t audio_timecode = pending_audio_frames.front().timecode;
if (audio_frame_allocator == nullptr) {
set_audio_frame_allocator(new MallocFrameAllocator(65536)); // FIXME: leak.
}
- thread(&BMUSBCapture::dequeue_thread, this).detach();
+ dequeue_thread_should_quit = false;
+ dequeue_thread = thread(&BMUSBCapture::dequeue_thread_func, this);
int rc;
struct libusb_transfer *xfr;
#endif
}
+void BMUSBCapture::stop_dequeue_thread()
+{
+ dequeue_thread_should_quit = true;
+ queues_not_empty.notify_all();
+ dequeue_thread.join();
+}
+
void BMUSBCapture::start_bm_thread()
{
should_quit = false;
void configure_card();
void start_bm_capture();
+ void stop_dequeue_thread();
static void start_bm_thread();
static void stop_bm_thread();
void start_new_frame(const uint8_t *start);
void queue_frame(uint16_t format, uint16_t timecode, FrameAllocator::Frame frame, std::deque<QueuedFrame> *q);
- void dequeue_thread();
+ void dequeue_thread_func();
static void usb_thread_func();
static void cb_xfr(struct libusb_transfer *xfr);
FrameAllocator *audio_frame_allocator = nullptr;
frame_callback_t frame_callback = nullptr;
+ std::thread dequeue_thread;
+ std::atomic<bool> dequeue_thread_should_quit;
bool has_dequeue_callbacks = false;
std::function<void()> dequeue_init_callback = nullptr;
std::function<void()> dequeue_cleanup_callback = nullptr;