]> git.sesse.net Git - bmusb/blobdiff - bmusb.cpp
Document alternates 3 and 4.
[bmusb] / bmusb.cpp
index 00f06e443f387f1b0218ae8284a53b00a7b173da..16da5f01e467409188f4cb3ab92335631802d401 100644 (file)
--- 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 <assert.h>
+#include <errno.h>
+#include <libusb.h>
+#include <netinet/in.h>
+#include <sched.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <libusb.h>
-#include <arpa/inet.h>
-#include <unistd.h>
 #include <string.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <assert.h>
-#ifdef __SSE2__
+#ifdef __SSE4_1__
 #include <immintrin.h>
 #endif
+#include "bmusb.h"
+
 #include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <cstddef>
+#include <cstdint>
+#include <deque>
 #include <functional>
 #include <memory>
-#include <deque>
-#include <utility>
 #include <mutex>
-#include <condition_variable>
-#include <thread>
 #include <stack>
-#include <atomic>
-#include "bmusb.h"
+#include <thread>
 
 using namespace std;
 using namespace std::placeholders;
@@ -45,6 +47,9 @@ using namespace std::placeholders;
 
 FILE *audiofp;
 
+thread usb_thread;
+atomic<bool> should_quit;
+
 FrameAllocator::~FrameAllocator() {}
 
 #define NUM_QUEUED_FRAMES 8
@@ -278,7 +283,50 @@ void add_to_frame(FrameAllocator::Frame *current_frame, const char *frame_type_n
        }
 }
 
-#ifdef __SSE2__
+#ifdef __SSE4_1__
+
+#if 0
+void avx2_dump(const char *name, __m256i n)
+{
+       printf("%-10s:", name);
+       printf(" %02x", _mm256_extract_epi8(n, 0));
+       printf(" %02x", _mm256_extract_epi8(n, 1));
+       printf(" %02x", _mm256_extract_epi8(n, 2));
+       printf(" %02x", _mm256_extract_epi8(n, 3));
+       printf(" %02x", _mm256_extract_epi8(n, 4));
+       printf(" %02x", _mm256_extract_epi8(n, 5));
+       printf(" %02x", _mm256_extract_epi8(n, 6));
+       printf(" %02x", _mm256_extract_epi8(n, 7));
+       printf(" ");
+       printf(" %02x", _mm256_extract_epi8(n, 8));
+       printf(" %02x", _mm256_extract_epi8(n, 9));
+       printf(" %02x", _mm256_extract_epi8(n, 10));
+       printf(" %02x", _mm256_extract_epi8(n, 11));
+       printf(" %02x", _mm256_extract_epi8(n, 12));
+       printf(" %02x", _mm256_extract_epi8(n, 13));
+       printf(" %02x", _mm256_extract_epi8(n, 14));
+       printf(" %02x", _mm256_extract_epi8(n, 15));
+       printf(" ");
+       printf(" %02x", _mm256_extract_epi8(n, 16));
+       printf(" %02x", _mm256_extract_epi8(n, 17));
+       printf(" %02x", _mm256_extract_epi8(n, 18));
+       printf(" %02x", _mm256_extract_epi8(n, 19));
+       printf(" %02x", _mm256_extract_epi8(n, 20));
+       printf(" %02x", _mm256_extract_epi8(n, 21));
+       printf(" %02x", _mm256_extract_epi8(n, 22));
+       printf(" %02x", _mm256_extract_epi8(n, 23));
+       printf(" ");
+       printf(" %02x", _mm256_extract_epi8(n, 24));
+       printf(" %02x", _mm256_extract_epi8(n, 25));
+       printf(" %02x", _mm256_extract_epi8(n, 26));
+       printf(" %02x", _mm256_extract_epi8(n, 27));
+       printf(" %02x", _mm256_extract_epi8(n, 28));
+       printf(" %02x", _mm256_extract_epi8(n, 29));
+       printf(" %02x", _mm256_extract_epi8(n, 30));
+       printf(" %02x", _mm256_extract_epi8(n, 31));
+       printf("\n");
+}
+#endif
 
 // Does a memcpy and memchr in one to reduce processing time.
 // Note that the benefit is somewhat limited if your L3 cache is small,
@@ -469,7 +517,7 @@ void decode_packs(const libusb_transfer *xfr,
                const uint8_t *start = xfr->buffer + offset;
                const uint8_t *limit = start + pack->actual_length;
                while (start < limit) {  // Usually runs only one iteration.
-#ifdef __SSE2__
+#ifdef __SSE4_1__
                        start = add_to_frame_fastpath(current_frame, start, limit, sync_pattern[0]);
                        if (start == limit) break;
                        assert(start < limit);
@@ -559,8 +607,6 @@ void BMUSBCapture::cb_xfr(struct libusb_transfer *xfr)
 
 void BMUSBCapture::usb_thread_func()
 {
-       printf("usb thread started\n");
-
        sched_param param;
        memset(&param, 0, sizeof(param));
        param.sched_priority = 1;
@@ -574,7 +620,7 @@ void BMUSBCapture::usb_thread_func()
        }
 }
 
-void BMUSBCapture::start_bm_capture()
+void BMUSBCapture::configure_card()
 {
        if (video_frame_allocator == nullptr) {
                set_video_frame_allocator(new MallocFrameAllocator(FRAME_SIZE));  // FIXME: leak.
@@ -586,7 +632,6 @@ void BMUSBCapture::start_bm_capture()
 
        int rc;
        struct libusb_transfer *xfr;
-       vector<libusb_transfer *> iso_xfrs;
 
        rc = libusb_init(nullptr);
        if (rc < 0) {
@@ -594,7 +639,9 @@ void BMUSBCapture::start_bm_capture()
                exit(1);
        }
 
-       struct libusb_device_handle *devh = libusb_open_device_with_vid_pid(nullptr, 0x1edb, 0xbd3b);
+       //struct libusb_device_handle *devh = libusb_open_device_with_vid_pid(nullptr, 0x1edb, 0xbd3b);
+       //struct libusb_device_handle *devh = libusb_open_device_with_vid_pid(nullptr, 0x1edb, 0xbd4f);
+       struct libusb_device_handle *devh = libusb_open_device_with_vid_pid(nullptr, vid, pid);
        if (!devh) {
                fprintf(stderr, "Error finding USB device\n");
                exit(1);
@@ -635,6 +682,9 @@ void BMUSBCapture::start_bm_capture()
        // 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));
@@ -829,7 +879,7 @@ void BMUSBCapture::start_bm_capture()
                                        size &= ~1023;
                                        size += 1024;
                                }
-                               num_iso_pack = (2 << 20) / size;  // 2 MB.
+                               num_iso_pack = (2 << 18) / size;  // 512 kB.
                                printf("Picking %d packets of 0x%x bytes each\n", num_iso_pack, size);
                        } else {
                                size = 0xc0;
@@ -852,24 +902,24 @@ void BMUSBCapture::start_bm_capture()
                        iso_xfrs.push_back(xfr);
                }
        }
+}
 
-       {
-               int i = 0;
-               for (libusb_transfer *xfr : iso_xfrs) {
-                       rc = libusb_submit_transfer(xfr);
-                       ++i;
-                       if (rc < 0) {
-                               //printf("num_bytes=%d\n", num_bytes);
-                               fprintf(stderr, "Error submitting iso to endpoint 0x%02x, number %d: %s\n",
-                                       xfr->endpoint, i, libusb_error_name(rc));
-                               exit(1);
-                       }
+void BMUSBCapture::start_bm_capture()
+{
+       printf("starting capture\n");
+       int i = 0;
+       for (libusb_transfer *xfr : iso_xfrs) {
+               printf("submitting transfer...\n");
+               int rc = libusb_submit_transfer(xfr);
+               ++i;
+               if (rc < 0) {
+                       //printf("num_bytes=%d\n", num_bytes);
+                       fprintf(stderr, "Error submitting iso to endpoint 0x%02x, number %d: %s\n",
+                               xfr->endpoint, i, libusb_error_name(rc));
+                       exit(1);
                }
        }
 
-       should_quit = false;
-       usb_thread = thread(&BMUSBCapture::usb_thread_func, this);
-
 
 #if 0
        libusb_release_interface(devh, 0);
@@ -881,7 +931,13 @@ out:
 #endif
 }
 
-void BMUSBCapture::stop_bm_capture()
+void BMUSBCapture::start_bm_thread()
+{
+       should_quit = false;
+       usb_thread = thread(&BMUSBCapture::usb_thread_func);
+}
+
+void BMUSBCapture::stop_bm_thread()
 {
        should_quit = true;
        usb_thread.join();