X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bmusb.cpp;h=6867805e719e4c6983af99063f343cbb2dd94b1f;hb=76d42863dafcc8ab3b60df73c0caae9f98545a2a;hp=3c86d358d4ca87acfa6251d267c21653b9879488;hpb=fbff3e4f576c0525241f0f02ad0fd31d215aaa71;p=bmusb diff --git a/bmusb.cpp b/bmusb.cpp index 3c86d35..6867805 100644 --- a/bmusb.cpp +++ b/bmusb.cpp @@ -4,29 +4,31 @@ // 576p60/720p60/1080i60 works, 1080p60 does not work (firmware limitation) // Audio comes out as 8-channel 24-bit raw audio. +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include #include -#include -#include -#include #ifdef __SSE4_1__ #include #endif +#include "bmusb.h" + #include +#include +#include +#include +#include +#include #include #include -#include -#include #include -#include -#include #include -#include -#include "bmusb.h" +#include using namespace std; using namespace std::placeholders; @@ -50,7 +52,7 @@ atomic should_quit; FrameAllocator::~FrameAllocator() {} -#define NUM_QUEUED_FRAMES 8 +#define NUM_QUEUED_FRAMES 16 class MallocFrameAllocator : public FrameAllocator { public: MallocFrameAllocator(size_t frame_size); @@ -142,11 +144,14 @@ void dump_audio_block(uint8_t *audio_start, size_t audio_len) fwrite(audio_start + AUDIO_HEADER_SIZE, 1, audio_len - AUDIO_HEADER_SIZE, audiofp); } -void BMUSBCapture::dequeue_thread() +void BMUSBCapture::dequeue_thread_func() { - for ( ;; ) { + if (has_dequeue_callbacks) { + dequeue_init_callback(); + } + while (!dequeue_thread_should_quit) { unique_lock 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; @@ -179,6 +184,9 @@ void BMUSBCapture::dequeue_thread() 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) @@ -605,8 +613,6 @@ void BMUSBCapture::cb_xfr(struct libusb_transfer *xfr) void BMUSBCapture::usb_thread_func() { - printf("usb thread started\n"); - sched_param param; memset(¶m, 0, sizeof(param)); param.sched_priority = 1; @@ -628,7 +634,8 @@ void BMUSBCapture::configure_card() 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; @@ -682,6 +689,9 @@ void BMUSBCapture::configure_card() // Alternate setting 1 is output, alternate setting 2 is input. // Card is reset when switching alternates, so the driver uses // this “double switch” when it wants to reset. + // + // There's also alternate settings 3 and 4, which seem to be + // like 1 and 2 except they advertise less bandwidth needed. rc = libusb_set_interface_alt_setting(devh, /*interface=*/0, /*alternate_setting=*/1); if (rc < 0) { fprintf(stderr, "Error setting alternate 1: %s\n", libusb_error_name(rc)); @@ -928,6 +938,13 @@ out: #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;