The typical use for this would be setting up and tearing down an
OpenGL context or similar. You can fake it easily enough for
startup, but it's much worse for shutdown (which is coming soon).
void BMUSBCapture::dequeue_thread()
{
void BMUSBCapture::dequeue_thread()
{
+ if (has_dequeue_callbacks) {
+ dequeue_init_callback();
+ }
for ( ;; ) {
unique_lock<mutex> lock(queue_lock);
queues_not_empty.wait(lock, [this]{ return !pending_video_frames.empty() && !pending_audio_frames.empty(); });
for ( ;; ) {
unique_lock<mutex> lock(queue_lock);
queues_not_empty.wait(lock, [this]{ return !pending_video_frames.empty() && !pending_audio_frames.empty(); });
audio_frame.frame, AUDIO_HEADER_SIZE, audio_frame.format);
}
}
audio_frame.frame, AUDIO_HEADER_SIZE, audio_frame.format);
}
}
+ if (has_dequeue_callbacks) {
+ dequeue_cleanup_callback();
+ }
}
void BMUSBCapture::start_new_frame(const uint8_t *start)
}
void BMUSBCapture::start_new_frame(const uint8_t *start)
frame_callback = callback;
}
frame_callback = callback;
}
+ // Needs to be run before configure_card().
+ void set_dequeue_thread_callbacks(std::function<void()> init, std::function<void()> cleanup)
+ {
+ dequeue_init_callback = init;
+ dequeue_cleanup_callback = cleanup;
+ has_dequeue_callbacks = true;
+ }
+
void configure_card();
void start_bm_capture();
void configure_card();
void start_bm_capture();
FrameAllocator *audio_frame_allocator = nullptr;
frame_callback_t frame_callback = nullptr;
FrameAllocator *audio_frame_allocator = nullptr;
frame_callback_t frame_callback = nullptr;
+ bool has_dequeue_callbacks = false;
+ std::function<void()> dequeue_init_callback = nullptr;
+ std::function<void()> dequeue_cleanup_callback = nullptr;
+
int current_register = 0;
static constexpr int NUM_BMUSB_REGISTERS = 60;
int current_register = 0;
static constexpr int NUM_BMUSB_REGISTERS = 60;