]> git.sesse.net Git - bmusb/blobdiff - bmusb.cpp
Yet more 1080p mode corrections.
[bmusb] / bmusb.cpp
index cd4e59c4302b5d6cdba09080cd4b36c7337e7c2a..3d090d746d44effbdf25fc2ee75f528f3c4e919f 100644 (file)
--- a/bmusb.cpp
+++ b/bmusb.cpp
@@ -1,4 +1,4 @@
-// Intensity Shuttle USB3 capture driver, v0.4
+// Intensity Shuttle USB3 capture driver, v0.5.4
 // Can download 8-bit and 10-bit UYVY/v210 frames from HDMI, quite stable
 // (can do captures for hours at a time with no drops), except during startup
 // 576p60/720p60/1080i60 works, 1080p60 does not work (firmware limitation)
@@ -13,6 +13,7 @@
 #include <libusb.h>
 #include <unistd.h>
 #include <netinet/in.h>
+#include <pthread.h>
 #include <sched.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -25,6 +26,7 @@
 
 #include <algorithm>
 #include <atomic>
+#include <chrono>
 #include <condition_variable>
 #include <cstddef>
 #include <cstdint>
@@ -37,6 +39,7 @@
 #include <thread>
 
 using namespace std;
+using namespace std::chrono;
 using namespace std::placeholders;
 
 #define USB_VENDOR_BLACKMAGIC 0x1edb
@@ -109,6 +112,7 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
                // It's a strange thing, but what can you do.
                decoded_video_format->width = 720;
                decoded_video_format->height = 525;
+               decoded_video_format->stride = 720 * 2;
                decoded_video_format->extra_lines_top = 0;
                decoded_video_format->extra_lines_bottom = 0;
                decoded_video_format->frame_rate_nom = 3013;
@@ -121,6 +125,7 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
                        video_format);
                decoded_video_format->width = 0;
                decoded_video_format->height = 0;
+               decoded_video_format->stride = 0;
                decoded_video_format->extra_lines_top = 0;
                decoded_video_format->extra_lines_bottom = 0;
                decoded_video_format->frame_rate_nom = 60;
@@ -135,6 +140,7 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
        if (video_format == 0xe901 || video_format == 0xe9c1 || video_format == 0xe801) {
                decoded_video_format->width = 720;
                decoded_video_format->height = 480;
+               decoded_video_format->stride = 720 * 2;
                decoded_video_format->extra_lines_top = 17;
                decoded_video_format->extra_lines_bottom = 28;
                decoded_video_format->frame_rate_nom = 30000;
@@ -148,6 +154,7 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
        if (video_format == 0xe909 || video_format == 0xe9c9 || video_format == 0xe809 || video_format == 0xebe9 || video_format == 0xebe1) {
                decoded_video_format->width = 720;
                decoded_video_format->height = 576;
+               decoded_video_format->stride = 720 * 2;
                decoded_video_format->extra_lines_top = 22;
                decoded_video_format->extra_lines_bottom = 27;
                decoded_video_format->frame_rate_nom = 25;
@@ -172,19 +179,20 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
                { 0x0103, 1280,  720,   0, 25,  5,    60,    1, false },  // 720p60.
                { 0x0125, 1280,  720,   0, 25,  5,    60,    1, false },  // 720p60.
                { 0x0121, 1280,  720,   0, 25,  5, 60000, 1001, false },  // 720p59.94.
-               { 0x01c3, 1920, 1080,   0,  0,  0,    30,    1, false },  // 1080p30.
+               { 0x01c3, 1920, 1080,   0, 41,  4,    30,    1, false },  // 1080p30.
                { 0x0003, 1920, 1080, 583, 20, 25,    30,    1,  true },  // 1080i60.
-               { 0x01e1, 1920, 1080,   0,  0,  0, 30000, 1001, false },  // 1080p29.97.
+               { 0x01e1, 1920, 1080,   0, 41,  4, 30000, 1001, false },  // 1080p29.97.
                { 0x0021, 1920, 1080, 583, 20, 25, 30000, 1001,  true },  // 1080i59.94.
-               { 0x0063, 1920, 1080,   0,  0,  0,    25,    1, false },  // 1080p25.
-               { 0x0043, 1920, 1080,   0,  0,  0,    25,    1,  true },  // 1080p50.
-               { 0x008e, 1920, 1080,   0,  0,  0,    24,    1, false },  // 1080p24.
-               { 0x00a1, 1920, 1080,   0,  0,  0, 24000, 1001, false },  // 1080p23.98.
+               { 0x0063, 1920, 1080,   0, 41,  4,    25,    1, false },  // 1080p25.
+               { 0x0043, 1920, 1080, 583, 20, 25,    25,    1,  true },  // 1080i50.
+               { 0x0083, 1920, 1080,   0, 41,  4,    24,    1, false },  // 1080p24.
+               { 0x00a1, 1920, 1080,   0, 41,  4, 24000, 1001, false },  // 1080p23.98.
        };
        for (const VideoFormatEntry &entry : entries) {
                if (normalized_video_format == entry.normalized_video_format) {
                        decoded_video_format->width = entry.width;
                        decoded_video_format->height = entry.height;
+                       decoded_video_format->stride = entry.width * 2;
                        decoded_video_format->second_field_start = entry.second_field_start;
                        decoded_video_format->extra_lines_top = entry.extra_lines_top;
                        decoded_video_format->extra_lines_bottom = entry.extra_lines_bottom;
@@ -198,6 +206,7 @@ bool decode_video_format(uint16_t video_format, VideoFormat *decoded_video_forma
        printf("Unknown video format 0x%04x (normalized 0x%04x). Assuming 720p60.\n", video_format, normalized_video_format);
        decoded_video_format->width = 1280;
        decoded_video_format->height = 720;
+       decoded_video_format->stride = 1280 * 2;
        decoded_video_format->frame_rate_nom = 60;
        decoded_video_format->frame_rate_den = 1;
        return false;
@@ -287,6 +296,10 @@ void dump_audio_block(uint8_t *audio_start, size_t audio_len)
 
 void BMUSBCapture::dequeue_thread_func()
 {
+       char thread_name[16];
+       snprintf(thread_name, sizeof(thread_name), "bmusb_dequeue_%d", card_index);
+       pthread_setname_np(pthread_self(), thread_name);
+
        if (has_dequeue_callbacks) {
                dequeue_init_callback();
        }
@@ -362,6 +375,8 @@ void BMUSBCapture::start_new_frame(const uint8_t *start)
        uint16_t timecode = (start[1] << 8) | start[0];
 
        if (current_video_frame.len > 0) {
+               current_video_frame.received_timestamp = steady_clock::now();
+
                // If format is 0x0800 (no signal), add a fake (empty) audio
                // frame to get it out of the queue.
                // TODO: Figure out if there are other formats that come with
@@ -405,6 +420,7 @@ void BMUSBCapture::start_new_audio_block(const uint8_t *start)
        uint16_t format = (start[3] << 8) | start[2];
        uint16_t timecode = (start[1] << 8) | start[0];
        if (current_audio_frame.len > 0) {
+               current_audio_frame.received_timestamp = steady_clock::now();
                //dump_audio_block();
                queue_frame(format, timecode, current_audio_frame, &pending_audio_frames);
        }
@@ -536,6 +552,10 @@ const uint8_t *add_to_frame_fastpath(FrameAllocator::Frame *current_frame, const
 
 #else  // defined(HAS_MULTIVERSIONING)
 
+__attribute__((target("sse4.1")))
+const uint8_t *add_to_frame_fastpath_core(FrameAllocator::Frame *current_frame, const uint8_t *aligned_start, const uint8_t *limit, const char sync_char);
+
+__attribute__((target("avx2")))
 const uint8_t *add_to_frame_fastpath_core(FrameAllocator::Frame *current_frame, const uint8_t *aligned_start, const uint8_t *limit, const char sync_char);
 
 // Does a memcpy and memchr in one to reduce processing time.
@@ -877,6 +897,7 @@ void BMUSBCapture::usb_thread_func()
        if (sched_setscheduler(0, SCHED_RR, &param) == -1) {
                printf("couldn't set realtime priority for USB thread: %s\n", strerror(errno));
        }
+       pthread_setname_np(pthread_self(), "bmusb_usb_drv");
        while (!should_quit) {
                timeval sec { 1, 0 };
                int rc = libusb_handle_events_timeout(nullptr, &sec);
@@ -1105,6 +1126,11 @@ void BMUSBCapture::configure_card()
        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));
+               if (rc == LIBUSB_ERROR_NOT_FOUND) {
+                       fprintf(stderr, "This is usually because the card came up in USB2 mode.\n");
+                       fprintf(stderr, "In particular, this tends to happen if you boot up with the\n");
+                       fprintf(stderr, "card plugged in; just unplug and replug it, and it usually works.\n");
+               }
                exit(1);
        }
        rc = libusb_set_interface_alt_setting(devh, /*interface=*/0, /*alternate_setting=*/2);