From bba613bc569c8be83ef0ed46c7c0fea64b2a2ba7 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Tue, 13 Aug 2019 16:35:43 +0200 Subject: [PATCH] AJA: added option 'clear-routing' --- src/video_capture/aja.cpp | 18 ++++++++++++++---- src/video_display/aja.cpp | 35 ++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/video_capture/aja.cpp b/src/video_capture/aja.cpp index bf663fbc4..37e36f2e5 100644 --- a/src/video_capture/aja.cpp +++ b/src/video_capture/aja.cpp @@ -168,6 +168,7 @@ class vidcap_state_aja { NTV2TCSource mTimeCodeSource{}; ///< @brief Time code source bool mCheckFor4K{false}; uint32_t mAudioInLastAddress{}; ///< @brief My record of the location of the last audio sample captured + bool mClearRouting{false}; AJAStatus SetupVideo(); AJAStatus SetupAudio(); @@ -192,6 +193,8 @@ vidcap_state_aja::vidcap_state_aja(unordered_map const & paramet mProgressive = true; } else if (it.first == "4K" || it.first == "4k") { mCheckFor4K = true; + } else if (it.first == "clear-routing") { + mClearRouting = true; } else if (it.first == "device") { mDeviceIndex = stol(it.second, nullptr, 10); } else if (it.first == "channel") { @@ -286,6 +289,10 @@ void vidcap_state_aja::Init() if (!mDevice.Open (mDeviceIndex)) throw string("Unable to open device."); + if (mClearRouting) { + CHECK_OK(mDevice.ClearRouting(), "ClearRouting", NOOP); + } + ULWord fourcc = app; #ifndef _MSC_VER if (get_commandline_param("aja-fourcc")) { @@ -866,15 +873,15 @@ bool vidcap_state_aja::IsInput3Gb(const NTV2InputSource inputSource) static void show_help() { cout << "Usage:\n"; - cout << rang::style::bold << rang::fg::red << "\t-t aja[:device=]" << rang::fg::reset << "[:progressive][:4K][:channel=][:codec=][:connection=][:format=] -r [embedded|AESEBU|analog]\n" << rang::style::reset; + cout << rang::style::bold << rang::fg::red << "\t-t aja" << rang::fg::reset << "[[:4K][:clear-routing][:channel=][:codec=][:connection=][:device=][:format=][:progressive]|:help] -r [embedded|AESEBU|analog]\n" << rang::style::reset; cout << "where\n"; - cout << rang::style::bold << "\tprogressive\n" << rang::style::reset; - cout << "\t\tVideo input is progressive.\n"; - cout << rang::style::bold << "\t4K\n" << rang::style::reset; cout << "\t\tVideo input is 4K.\n"; + cout << rang::style::bold << "\tclear-routing\n" << rang::style::reset << + "\t\tremove all existing signal paths for device\n"; + cout << rang::style::bold << "\tchannel\n" << rang::style::reset; cout << "\t\tChannel number to use (indexed from 1). Doesn't need to be set for SDI, useful for HDMI (capture and display should have different channel numbers if both used, also other than 1 if SDI1 is in use).\n"; @@ -892,6 +899,9 @@ static void show_help() { } cout << "\n"; + cout << rang::style::bold << "\tprogressive\n" << rang::style::reset; + cout << "\t\tVideo input is progressive.\n"; + cout << "\n"; printf("Available devices:\n"); diff --git a/src/video_display/aja.cpp b/src/video_display/aja.cpp index f2ee8f053..9089dcb4d 100644 --- a/src/video_display/aja.cpp +++ b/src/video_display/aja.cpp @@ -133,7 +133,8 @@ namespace aja { struct display { display(string const &device_id, NTV2OutputDestination outputDestination, - NTV2Channel outputChannel, bool withAudio, bool novsync, int buf_len); + NTV2Channel outputChannel, bool withAudio, bool novsync, int buf_len, + bool clearRouting); ~display(); void Init(); AJAStatus SetUpVideo(); @@ -186,7 +187,7 @@ struct display { static void show_help(); }; -display::display(string const &device_id, NTV2OutputDestination outputDestination, NTV2Channel outputChannel, bool withAudio, bool novsync, int buf_len) : max_frame_queue_len(buf_len), mNovsync(novsync), mOutputDestination(outputDestination), mOutputChannel(outputChannel), mWithAudio(withAudio) { +display::display(string const &device_id, NTV2OutputDestination outputDestination, NTV2Channel outputChannel, bool withAudio, bool novsync, int buf_len, bool clearRouting) : max_frame_queue_len(buf_len), mNovsync(novsync), mOutputDestination(outputDestination), mOutputChannel(outputChannel), mWithAudio(withAudio) { if (!CNTV2DeviceScanner::GetFirstDeviceFromArgument(device_id, mDevice)) { throw runtime_error(string("Device '") + device_id + "' not found!"); } @@ -195,6 +196,10 @@ display::display(string const &device_id, NTV2OutputDestination outputDestinatio throw runtime_error(string("Device '") + device_id + "' not ready!"); } + if (clearRouting) { + CHECK(mDevice.ClearRouting()); + } + mDeviceID = mDevice.GetDeviceID(); // Keep this ID handy -- it's used frequently mDoMultiChannel = NTV2DeviceCanDoMultiFormat(mDeviceID); @@ -642,10 +647,16 @@ void aja::display::print_stats() { void aja::display::show_help() { cout << "Usage:\n" "\t" << rang::style::bold << rang::fg::red << "-d aja" << rang::fg::reset << - "[:device=][:connection=][:channel=][:novsync][:buffers=][:help] [-r embedded]\n" << rang::style::reset << + "[[:buffers=][:channel=][:clear-routing][:connection=][:device=][:novsync]|:help] [-r embedded]\n" << rang::style::reset << "where\n"; - cout << rang::style::bold << "\tdevice\n" << rang::style::reset << - "\t\tdevice identifier (number or name)\n"; + + cout << rang::style::bold << "\tbuffers\n" << rang::style::reset << + "\t\tuse output buffers (default is " << DEFAULT_MAX_FRAME_QUEUE_LEN << ") - higher values increase stability\n" + "\t\tbut may also increase latency (when VBlank is enabled)\n"; + + cout << rang::style::bold << "\tclear-routing\n" << rang::style::reset << + "\t\tremove all existing signal paths for device\n"; + cout << rang::style::bold << "\tconnection\n" << rang::style::reset << "\t\tone of: "; NTV2OutputDestination dest = NTV2OutputDestination(); @@ -663,13 +674,12 @@ void aja::display::show_help() { cout << rang::style::bold << "\tchannel\n" << rang::style::reset << "\t\tchannel number to use (indexed from 1). Doesn't need to be set for SDI, useful for HDMI (capture and display should have different channel numbers if both used, also other than 1 if SDI1 is in use, see \"-t aja:help\" to see number of available channels).\n"; + cout << rang::style::bold << "\tdevice\n" << rang::style::reset << + "\t\tdevice identifier (number or name)\n"; + cout << rang::style::bold << "\tnovsync\n" << rang::style::reset << "\t\tdisable sync on VBlank (may improve latency at the expense of tearing)\n"; - cout << rang::style::bold << "\tbuffers\n" << rang::style::reset << - "\t\tuse output buffers (default is " << DEFAULT_MAX_FRAME_QUEUE_LEN << ") - higher values increase stability\n" - "\t\tbut may also increase latency (when VBlank is enabled)\n"; - cout << rang::style::bold << "\t-r embedded\n" << rang::style::reset << "\t\treceive also audio and embed it to SDI\n"; @@ -824,7 +834,8 @@ LINK_SPEC void *display_aja_init(struct module * /* parent */, const char *fmt, { string device_idx{"0"}; string connection; - bool novsync = false; + bool novsync = false, + clear_routing = false; int buf_len = DEFAULT_MAX_FRAME_QUEUE_LEN; NTV2OutputDestination outputDestination = NTV2_OUTPUTDESTINATION_SDI1; NTV2Channel outputChannel = NTV2_CHANNEL_INVALID; // if unchanged, select according to output destination @@ -836,6 +847,8 @@ LINK_SPEC void *display_aja_init(struct module * /* parent */, const char *fmt, if (strcmp("help", item) == 0) { aja::display::show_help(); return aja_display_init_noerr; + } else if (strcmp("clear-routing", item) == 0) { + clear_routing = true; } else if (strstr(item, "connection=") != nullptr) { string connection = item + strlen("connection="); NTV2OutputDestination dest = NTV2OutputDestination(); @@ -872,7 +885,7 @@ LINK_SPEC void *display_aja_init(struct module * /* parent */, const char *fmt, } try { - auto s = new aja::display(device_idx, outputDestination, outputChannel, (flags & DISPLAY_FLAG_AUDIO_ANY) != 0u, novsync, buf_len); + auto s = new aja::display(device_idx, outputDestination, outputChannel, (flags & DISPLAY_FLAG_AUDIO_ANY) != 0u, novsync, buf_len, clear_routing); return s; } catch (runtime_error &e) { LOG(LOG_LEVEL_ERROR) << MODULE_NAME << e.what() << "\n";