X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bmusb.h;h=4c7254bcb5dea6bb773381c510565cea37035839;hb=c753d698b047822c11f5f97b889649a3e582a4c9;hp=5b7c0f9c8e35a501c91bf40bdc81fb8d79f3770f;hpb=30a75fd8110601c89ecc7c1a0832a96878917cd4;p=bmusb diff --git a/bmusb.h b/bmusb.h index 5b7c0f9..4c7254b 100644 --- a/bmusb.h +++ b/bmusb.h @@ -6,11 +6,14 @@ #include #include #include +#include #include +#include #include #include #include +struct libusb_device_handle; struct libusb_transfer; // An interface for frame allocators; if you do not specify one @@ -57,6 +60,36 @@ class FrameAllocator { virtual void release_frame(Frame frame) = 0; }; +// Audio is more important than video, and also much cheaper. +// By having many more audio frames available, hopefully if something +// starts to drop, we'll have CPU load go down (from not having to +// process as much video) before we have to drop audio. +#define NUM_QUEUED_VIDEO_FRAMES 16 +#define NUM_QUEUED_AUDIO_FRAMES 64 + +class MallocFrameAllocator : public FrameAllocator { +public: + MallocFrameAllocator(size_t frame_size, size_t num_queued_frames); + Frame alloc_frame() override; + void release_frame(Frame frame) override; + +private: + size_t frame_size; + + std::mutex freelist_mutex; + std::stack> freelist; // All of size . +}; + +// Represents an input mode you can tune a card to. +struct VideoMode { + std::string name; + bool autodetect = false; // If true, all the remaining fields are irrelevant. + unsigned width = 0, height = 0; + unsigned frame_rate_num = 0, frame_rate_den = 0; + bool interlaced = false; +}; + +// Represents the format of an actual frame coming in. struct VideoFormat { uint16_t id = 0; // For debugging/logging only. unsigned width = 0, height = 0, second_field_start = 0; @@ -81,6 +114,18 @@ class CaptureInterface { public: virtual ~CaptureInterface() {} + virtual std::map get_available_video_modes() const = 0; + virtual uint32_t get_current_video_mode() const = 0; + virtual void set_video_mode(uint32_t video_mode_id) = 0; + + virtual std::map get_available_video_inputs() const = 0; + virtual void set_video_input(uint32_t video_input_id) = 0; + virtual uint32_t get_current_video_input() const = 0; + + virtual std::map get_available_audio_inputs() const = 0; + virtual void set_audio_input(uint32_t audio_input_id) = 0; + virtual uint32_t get_current_audio_input() const = 0; + // Does not take ownership. virtual void set_video_frame_allocator(FrameAllocator *allocator) = 0; @@ -116,10 +161,25 @@ class BMUSBCapture : public CaptureInterface { ~BMUSBCapture() {} + std::map get_available_video_modes() const override; + uint32_t get_current_video_mode() const override; + void set_video_mode(uint32_t video_mode_id) override; + + virtual std::map get_available_video_inputs() const override; + virtual void set_video_input(uint32_t video_input_id) override; + virtual uint32_t get_current_video_input() const override { return current_video_input; } + + virtual std::map get_available_audio_inputs() const override; + virtual void set_audio_input(uint32_t audio_input_id) override; + virtual uint32_t get_current_audio_input() const override { return current_audio_input; } + // Does not take ownership. void set_video_frame_allocator(FrameAllocator *allocator) override { video_frame_allocator = allocator; + if (owned_video_frame_allocator.get() != allocator) { + owned_video_frame_allocator.reset(); + } } FrameAllocator *get_video_frame_allocator() override @@ -131,6 +191,9 @@ class BMUSBCapture : public CaptureInterface { void set_audio_frame_allocator(FrameAllocator *allocator) override { audio_frame_allocator = allocator; + if (owned_audio_frame_allocator.get() != allocator) { + owned_audio_frame_allocator.reset(); + } } FrameAllocator *get_audio_frame_allocator() override @@ -180,6 +243,8 @@ class BMUSBCapture : public CaptureInterface { static void usb_thread_func(); static void cb_xfr(struct libusb_transfer *xfr); + void update_capture_mode(); + std::string description; FrameAllocator::Frame current_video_frame; @@ -192,6 +257,8 @@ class BMUSBCapture : public CaptureInterface { FrameAllocator *video_frame_allocator = nullptr; FrameAllocator *audio_frame_allocator = nullptr; + std::unique_ptr owned_video_frame_allocator; + std::unique_ptr owned_audio_frame_allocator; frame_callback_t frame_callback = nullptr; std::thread dequeue_thread; @@ -208,6 +275,10 @@ class BMUSBCapture : public CaptureInterface { int card_index; std::vector iso_xfrs; int assumed_frame_width = 1280; + + libusb_device_handle *devh = nullptr; + uint32_t current_video_input = 0x00000000; // HDMI/SDI. + uint32_t current_audio_input = 0x00000000; // Embedded. }; // Get details for the given video format; returns false if detection was incomplete.