X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=mixer.cpp;h=6276e2cb20c15b92aaaa4c70dfd00afdf0360322;hb=78e28934f9aecfb4dc9cd573b0c9b4e0bd012729;hp=19cb8bee202dacc708ea9430f4b98a3fa7969807;hpb=4fcae1818506a3df1aba45140909cb7851a0845f;p=nageru diff --git a/mixer.cpp b/mixer.cpp index 19cb8be..6276e2c 100644 --- a/mixer.cpp +++ b/mixer.cpp @@ -32,6 +32,7 @@ #include "context.h" #include "decklink_capture.h" #include "defs.h" +#include "fake_capture.h" #include "flags.h" #include "video_encoder.h" #include "pbo_frame_allocator.h" @@ -163,28 +164,43 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards) // Start listening for clients only once VideoEncoder has written its header, if any. httpd.start(9095); - // First try initializing the PCI devices, then USB, until we have the desired number of cards. + // First try initializing the fake devices, then PCI devices, then USB, + // until we have the desired number of cards. unsigned num_pci_devices = 0, num_usb_devices = 0; unsigned card_index = 0; - IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); - if (decklink_iterator != nullptr) { - for ( ; card_index < num_cards; ++card_index) { - IDeckLink *decklink; - if (decklink_iterator->Next(&decklink) != S_OK) { - break; - } + assert(global_flags.num_fake_cards >= 0); // Enforced in flags.cpp. + unsigned num_fake_cards = global_flags.num_fake_cards; + + assert(num_fake_cards <= num_cards); // Enforced in flags.cpp. + for ( ; card_index < num_fake_cards; ++card_index) { + configure_card(card_index, format, new FakeCapture(card_index)); + } - configure_card(card_index, format, new DeckLinkCapture(decklink, card_index)); - ++num_pci_devices; + if (global_flags.num_fake_cards > 0) { + fprintf(stderr, "Initialized %d fake cards.\n", global_flags.num_fake_cards); + } + + if (card_index < num_cards) { + IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); + if (decklink_iterator != nullptr) { + for ( ; card_index < num_cards; ++card_index) { + IDeckLink *decklink; + if (decklink_iterator->Next(&decklink) != S_OK) { + break; + } + + configure_card(card_index, format, new DeckLinkCapture(decklink, card_index - num_fake_cards)); + ++num_pci_devices; + } + decklink_iterator->Release(); + fprintf(stderr, "Found %d DeckLink PCI card(s).\n", num_pci_devices); + } else { + fprintf(stderr, "DeckLink drivers not found. Probing for USB cards only.\n"); } - decklink_iterator->Release(); - fprintf(stderr, "Found %d DeckLink PCI card(s).\n", num_pci_devices); - } else { - fprintf(stderr, "DeckLink drivers not found. Probing for USB cards only.\n"); } for ( ; card_index < num_cards; ++card_index) { - configure_card(card_index, format, new BMUSBCapture(card_index - num_pci_devices)); + configure_card(card_index, format, new BMUSBCapture(card_index - num_pci_devices - num_fake_cards)); ++num_usb_devices; } @@ -249,6 +265,7 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards) // except the final makeup gain. if (global_flags.flat_audio) { set_locut_enabled(false); + set_gain_staging_auto(false); set_limiter_enabled(false); set_compressor_enabled(false); } @@ -359,7 +376,8 @@ void Mixer::bm_frame(unsigned card_index, uint16_t timecode, } } - int64_t frame_length = int64_t(TIMEBASE * video_format.frame_rate_den) / video_format.frame_rate_nom; + int64_t frame_length = int64_t(TIMEBASE) * video_format.frame_rate_den / video_format.frame_rate_nom; + assert(frame_length > 0); size_t num_samples = (audio_frame.len > audio_offset) ? (audio_frame.len - audio_offset) / audio_format.num_channels / (audio_format.bits_per_sample / 8) : 0; if (num_samples > OUTPUT_FREQUENCY / 10) {