Browse Source

aja: Re-work HDMI routing and add missing presets

Paul Hindt 3 năm trước cách đây
mục cha
commit
eafe588bd3

+ 11 - 0
plugins/aja/aja-common.cpp

@@ -987,6 +987,17 @@ bool IsIOSelectionSDI(IOSelection io)
 	return false;
 }
 
+bool IsIOSelectionHDMI(IOSelection io)
+{
+	if (io == IOSelection::HDMI1 || io == IOSelection::HDMI2 ||
+	    io == IOSelection::HDMI3 || io == IOSelection::HDMI4 ||
+	    io == IOSelection::HDMIMonitorIn ||
+	    io == IOSelection::HDMIMonitorOut) {
+		return true;
+	}
+	return false;
+}
+
 std::string MakeCardID(CNTV2Card &card)
 {
 	std::string cardID;

+ 1 - 0
plugins/aja/aja-common.hpp

@@ -97,6 +97,7 @@ extern bool IsSDITwoWireIOSelection(IOSelection io);
 extern bool IsSDIFourWireIOSelection(IOSelection io);
 extern bool IsMonitorOutputSelection(NTV2DeviceID id, IOSelection io);
 extern bool IsIOSelectionSDI(IOSelection io);
+extern bool IsIOSelectionHDMI(IOSelection io);
 
 extern std::string MakeCardID(CNTV2Card &card);
 

+ 4 - 10
plugins/aja/aja-enums.hpp

@@ -72,16 +72,10 @@ enum class RasterDefinition {
 };
 
 enum class HDMIWireFormat {
-	SD_HDMI = 0,
-	HD_YCBCR_LFR = 1,
-	HD_YCBCR_HFR = 2,
-	HD_RGB_LFR = 3,
-	HD_RGB_HFR = 4,
-	UHD_4K_YCBCR_LFR = 5,
-	UHD_4K_YCBCR_HFR = 6,
-	UHD_4K_RGB_LFR = 7,
-	UHD_4K_RGB_HFR = 8,
-	TTAP_PRO = 9,
+	SD_HD_YCBCR = 0,
+	SD_HD_RGB = 1,
+	UHD_4K_YCBCR = 2,
+	UHD_4K_RGB = 3,
 	Unknown
 };
 

+ 2 - 1
plugins/aja/aja-output.cpp

@@ -1076,8 +1076,9 @@ static bool aja_output_start(void *data)
 	}
 
 	// Configures crosspoint routing on AJA card
+	NTV2XptConnections xpt_cnx;
 	if (!aja::Routing::ConfigureOutputRoute(outputProps, NTV2_MODE_DISPLAY,
-						card)) {
+						card, xpt_cnx)) {
 		blog(LOG_ERROR,
 		     "aja_output_start: Error configuring output route!");
 		return false;

+ 304 - 34
plugins/aja/aja-presets.cpp

@@ -40,7 +40,7 @@ void RoutingConfigurator::build_preset_table()
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_CAPTURE,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_RGB_LFR,
+		  HDMIWireFormat::SD_HD_RGB,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
@@ -49,6 +49,41 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  true,
 		  false}},
+		{"HDMI_HD_RGB_HFR_RGB_Capture",
+		 {"HDMI_HD_RGB_HFR_RGB_Capture",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::HD,
+		  HDMIWireFormat::SD_HD_RGB,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  0,
+		  "hdmi[{ch1}][0]->fb[{ch1}][0];",
+		  {},
+		  true,
+		  false}},
+		{"HDMI_UHD_4K_RGB_Capture (io4K+)",
+		 {"HDMI_UHD_4K_RGB_Capture (io4K+)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::UHD_4K_RGB,
+		  VPIDStandard_Unknown,
+		  1,
+		  2,
+		  kEnable4KTSI,
+		  "hdmi[{ch1}][4]->tsi[{ch1}][0];"
+		  "hdmi[{ch1}][5]->tsi[{ch1}][1];"
+		  "hdmi[{ch1}][6]->tsi[{ch2}][0];"
+		  "hdmi[{ch1}][7]->tsi[{ch2}][1];"
+		  "tsi[{ch1}][2]->fb[{ch1}][0];"
+		  "tsi[{ch1}][3]->fb[{ch1}][1];"
+		  "tsi[{ch2}][2]->fb[{ch2}][0];"
+		  "tsi[{ch2}][3]->fb[{ch2}][1];",
+		  {DEVICE_ID_IO4KPLUS},
+		  true,
+		  false}},
 		/*
         * HDMI RGB Display
         */
@@ -57,7 +92,7 @@ void RoutingConfigurator::build_preset_table()
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_DISPLAY,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_RGB_LFR,
+		  HDMIWireFormat::SD_HD_RGB,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
@@ -66,30 +101,63 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  true,
 		  false}},
-		{"HDMI_HD_RGB_LFR_RGB_Display (TTap Pro)",
-		 {"HDMI_HD_RGB_LFR_RGB_Display (TTap Pro)",
+		{"HDMI_HD_RGB_HFR_RGB_Display",
+		 {"HDMI_HD_RGB_HFR_RGB_Display",
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_DISPLAY,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_RGB_LFR,
+		  HDMIWireFormat::SD_HD_RGB,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
 		  0,
-		  "fb[{ch1}][0]->sdi[{ch1}][0];"
-		  "fb[{ch1}][0]->hdmi[{ch1}][0];",
+		  "fb[{ch1}][0]->hdmi[0][0];",
+		  {},
+		  true,
+		  false}},
+		{"HDMI_RGB_LFR_RGB_Display (TTap Pro)",
+		 {"HDMI_RGB_LFR_RGB_Display (TTap Pro)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::HD,
+		  HDMIWireFormat::SD_HD_RGB,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  kEnable3GOut,
+		  "fb[{ch1}][2]->dlo[{ch1}][0];"
+		  "dlo[{ch1}][0]->sdi[{ch1}][0];"
+		  "dlo[{ch1}][1]->sdi[{ch1}][1];"
+		  "fb[{ch1}][2]->hdmi[{ch1}][0];",
+		  {DEVICE_ID_TTAP_PRO},
+		  true,
+		  false}},
+		{"HDMI_RGB_HFR_RGB_Display (TTap Pro)",
+		 {"HDMI_RGB_HFR_RGB_Display (TTap Pro)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::HD,
+		  HDMIWireFormat::SD_HD_RGB,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  kConvert3GaRGBOut,
+		  "fb[{ch1}][2]->dlo[{ch1}][0];"
+		  "dlo[{ch1}][0]->sdi[{ch1}][0];"
+		  "dlo[{ch1}][1]->sdi[{ch1}][1];"
+		  "fb[{ch1}][2]->hdmi[{ch1}][0];",
 		  {DEVICE_ID_TTAP_PRO},
 		  true,
 		  false}},
 		/*
         * HDMI YCbCr Capture
         */
-		{"HDMI_HD_YCBCR_LFR_YCbCr_Capture",
-		 {"HDMI_HD_YCBCR_LFR_YCbCr_Capture",
+		{"HDMI_HD_LFR_YCbCr_Capture",
+		 {"HDMI_HD_LFR_YCbCr_Capture",
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_CAPTURE,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_YCBCR_LFR,
+		  HDMIWireFormat::SD_HD_YCBCR,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
@@ -98,15 +166,36 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  false,
 		  false}},
+		{"HDMI_UHD_4K_YCbCr_Capture (io4K+)",
+		 {"HDMI_UHD_4K_YCbCr_Capture (io4K+)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::UHD_4K_YCBCR,
+		  VPIDStandard_Unknown,
+		  1,
+		  2,
+		  kEnable4KTSI,
+		  "hdmi[{ch1}][0]->tsi[{ch1}][0];"
+		  "hdmi[{ch1}][1]->tsi[{ch1}][1];"
+		  "hdmi[{ch1}][2]->tsi[{ch2}][0];"
+		  "hdmi[{ch1}][3]->tsi[{ch2}][1];"
+		  "tsi[{ch1}][0]->fb[{ch1}][0];"
+		  "tsi[{ch1}][1]->fb[{ch1}][1];"
+		  "tsi[{ch2}][0]->fb[{ch2}][0];"
+		  "tsi[{ch2}][1]->fb[{ch2}][1];",
+		  {DEVICE_ID_IO4KPLUS},
+		  false,
+		  false}},
 		/*
         * HDMI YCbCr Display
         */
-		{"HDMI_HD_YCBCR_LFR_YCbCr_Display",
-		 {"HDMI_HD_YCBCR_LFR_YCbCr_Display",
+		{"HDMI_HD_LFR_YCbCr_Display",
+		 {"HDMI_HD_LFR_YCbCr_Display",
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_DISPLAY,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_YCBCR_LFR,
+		  HDMIWireFormat::SD_HD_YCBCR,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
@@ -115,12 +204,33 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  false,
 		  false}},
-		{"HDMI_HD_YCBCR_LFR_YCbCr_Display (TTap Pro)",
-		 {"HDMI_HD_YCBCR_LFR_YCbCr_Display (TTap Pro)",
+		{"HDMI_UHD_4K_LFR_YCbCr_Display",
+		 {"HDMI_UHD_4K_LFR_YCbCr_Display",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::UHD_4K_YCBCR,
+		  VPIDStandard_Unknown,
+		  1,
+		  2,
+		  kEnable4KTSI,
+		  "fb[{ch1}][0]->tsi[{ch1}][0];"
+		  "fb[{ch1}][1]->tsi[{ch1}][1];"
+		  "fb[{ch2}][0]->tsi[{ch2}][0];"
+		  "fb[{ch2}][1]->tsi[{ch2}][1];"
+		  "tsi[{ch1}][0]->hdmi[{ch1}][0];"
+		  "tsi[{ch1}][1]->hdmi[{ch1}][1];"
+		  "tsi[{ch2}][0]->hdmi[{ch1}][2];"
+		  "tsi[{ch2}][1]->hdmi[{ch1}][3];",
+		  {},
+		  false,
+		  false}},
+		{"HDMI_HD_LFR_YCbCr_Display (TTap Pro)",
+		 {"HDMI_HD_LFR_YCbCr_Display (TTap Pro)",
 		  ConnectionKind::HDMI,
 		  NTV2_MODE_DISPLAY,
 		  RasterDefinition::HD,
-		  HDMIWireFormat::HD_YCBCR_LFR,
+		  HDMIWireFormat::SD_HD_YCBCR,
 		  VPIDStandard_Unknown,
 		  1,
 		  1,
@@ -130,6 +240,51 @@ void RoutingConfigurator::build_preset_table()
 		  {DEVICE_ID_TTAP_PRO},
 		  false,
 		  false}},
+		{"HDMI_HD_HFR_YCbCr_Display (TTap Pro)",
+		 {"HDMI_HD_HFR_YCbCr_Display (TTap Pro)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::HD,
+		  HDMIWireFormat::SD_HD_YCBCR,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  kEnable3GOut,
+		  "fb[{ch1}][0]->sdi[{ch1}][0];"
+		  "fb[{ch1}][0]->hdmi[{ch1}][0];",
+		  {DEVICE_ID_TTAP_PRO},
+		  false,
+		  false}},
+		{"HDMI_UHD_4K_LFR_YCbCr_Display (TTap Pro)",
+		 {"HDMI_UHD_4K_LFR_YCbCr_Display (TTap Pro)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::UHD_4K_YCBCR,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  kEnable4KTSI | kEnable6GOut,
+		  "fb[{ch1}][0]->sdi[{ch1}][0];"
+		  "fb[{ch1}][0]->hdmi[{ch1}][0];",
+		  {DEVICE_ID_TTAP_PRO},
+		  false,
+		  false}},
+		{"HDMI_UHD_4K_HFR_YCbCr_Display (TTap Pro)",
+		 {"HDMI_UHD_4K_HFR_YCbCr_Display (TTap Pro)",
+		  ConnectionKind::HDMI,
+		  NTV2_MODE_DISPLAY,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::UHD_4K_YCBCR,
+		  VPIDStandard_Unknown,
+		  1,
+		  1,
+		  kEnable4KTSI | kEnable12GOut,
+		  "fb[{ch1}][0]->sdi[{ch1}][0];"
+		  "fb[{ch1}][0]->hdmi[{ch1}][0];",
+		  {DEVICE_ID_TTAP_PRO},
+		  false,
+		  false}},
 		/*
         * SDI RGB Capture
         */
@@ -299,6 +454,32 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  true,
 		  false}},
+		{"UHD4K_ST425_Quad_3Ga_Squares_RGB_Capture",
+		 {"UHD4K_ST425_Quad_3Ga_Squares_RGB_Capture",
+		  ConnectionKind::SDI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::Unknown,
+		  VPIDStandard_1080_3Ga,
+		  4,
+		  4,
+		  kEnable4KSquares,
+		  // SDIs -> Dual-Links
+		  "sdi[{ch1}][0]->dli[{ch1}][0];"
+		  "sdi[{ch1}][1]->dli[{ch1}][1];"
+		  "sdi[{ch2}][0]->dli[{ch2}][0];"
+		  "sdi[{ch2}][1]->dli[{ch2}][1];"
+		  "sdi[{ch3}][0]->dli[{ch3}][0];"
+		  "sdi[{ch3}][1]->dli[{ch3}][1];"
+		  "sdi[{ch4}][0]->dli[{ch4}][0];"
+		  "sdi[{ch4}][1]->dli[{ch4}][1];" // Dual-Links -> Framestores
+		  "dli[{ch1}][0]->fb[{ch1}][0];"
+		  "dli[{ch2}][0]->fb[{ch2}][0];"
+		  "dli[{ch3}][0]->fb[{ch3}][0];"
+		  "dli[{ch4}][0]->fb[{ch4}][0];",
+		  {},
+		  true,
+		  false}},
 		{"UHD4K_ST425_Quad_3Gb_Squares_RGB_Capture",
 		 {"UHD4K_ST425_Quad_3Gb_Squares_RGB_Capture",
 		  ConnectionKind::SDI,
@@ -334,7 +515,7 @@ void RoutingConfigurator::build_preset_table()
 		  VPIDStandard_2160_QuadLink_3Ga,
 		  4,
 		  4,
-		  (kEnable3GOut | kEnable4KTSI),
+		  kEnable4KTSI,
 		  // SDIs -> Dual-Links
 		  "sdi[{ch1}][0]->dli[{ch1}][0];"
 		  "sdi[{ch1}][1]->dli[{ch1}][1];"
@@ -385,18 +566,99 @@ void RoutingConfigurator::build_preset_table()
 		  {},
 		  true,
 		  false}},
-		// TODO(paulh): Find out the proper settings for this route
-		// { "UHD4K_ST2018_6G_Squares_2SI_RGB_Capture", {
-		//     "UHD4K_ST2018_6G_Squares_2SI_RGB_Capture",
-		//     ConnectionKind::SDI,
-		//     NTV2_MODE_CAPTURE,
-		//     2, 2,
-		//     kEnable6GOut,
-		//     "",
-		//     {},
-		//     RasterDefinition::UHD_4K,
-		//     HDMIWireFormat::Unknown,
-		//     VPIDStandard_2160_Single_6Gb, true, false}},
+
+		/////////////////////////////////
+		{"UHD4K_ST2018_6G_Squares_2SI_RGB_Capture",
+		 {"UHD4K_ST2018_6G_Squares_2SI_RGB_Capture",
+		  ConnectionKind::SDI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::Unknown,
+		  VPIDStandard_2160_Single_6Gb,
+		  1,
+		  1,
+		  kEnable4KTSI,
+		  "sdi[{ch1}][0]->dli[{ch1}][0];"
+		  "sdi[{ch1}][1]->dli[{ch1}][1];"
+		  "dli[{ch1}][0]->fb[{ch1}][0];",
+		  {},
+		  true,
+		  false}},
+		{"UHD4K_ST2018_6G_Squares_2SI_RGB_Capture (Kona5/io4K+)",
+		 {"UHD4K_ST2018_6G_Squares_2SI_RGB_Capture (Kona5/io4K+)",
+		  ConnectionKind::SDI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::Unknown,
+		  VPIDStandard_2160_Single_6Gb,
+		  4,
+		  4,
+		  kEnable4KTSI,
+		  "sdi[{ch1}][0]->dli[{ch1}][0];"
+		  "sdi[{ch1}][1]->dli[{ch1}][1];"
+		  "sdi[{ch2}][0]->dli[{ch2}][0];"
+		  "sdi[{ch2}][1]->dli[{ch2}][1];"
+		  "sdi[{ch3}][0]->dli[{ch3}][0];"
+		  "sdi[{ch3}][1]->dli[{ch3}][1];"
+		  "sdi[{ch4}][0]->dli[{ch4}][0];"
+		  "sdi[{ch4}][1]->dli[{ch4}][1];"
+		  "dli[{ch1}][0]->tsi[{ch1}][0];"
+		  "dli[{ch2}][0]->tsi[{ch1}][1];"
+		  "dli[{ch3}][0]->tsi[{ch2}][0];"
+		  "dli[{ch4}][0]->tsi[{ch2}][1];"
+		  "tsi[{ch1}][2]->fb[{ch1}][0];"
+		  "tsi[{ch1}][3]->fb[{ch1}][1];"
+		  "tsi[{ch2}][2]->fb[{ch2}][0];"
+		  "tsi[{ch2}][3]->fb[{ch2}][1];",
+		  {DEVICE_ID_KONA5, DEVICE_ID_IO4KPLUS},
+		  true,
+		  true}},
+		{"UHD4K_ST2018_12G_Squares_2SI_RGB_Capture",
+		 {"UHD4K_ST2018_12G_Squares_2SI_RGB_Capture",
+		  ConnectionKind::SDI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::Unknown,
+		  VPIDStandard_2160_Single_12Gb,
+		  1,
+		  1,
+		  kEnable4KTSI,
+		  "sdi[{ch1}][0]->dli[{ch1}][0];"
+		  "sdi[{ch1}][1]->dli[{ch1}][1];"
+		  "dli[{ch1}][0]->fb[{ch1}][0];",
+		  {},
+		  true,
+		  false}},
+		{"UHD4K_ST2018_12G_Squares_2SI_RGB_Capture (Kona5/io4K+)",
+		 {"UHD4K_ST2018_12G_Squares_2SI_RGB_Capture (Kona5/io4K+)",
+		  ConnectionKind::SDI,
+		  NTV2_MODE_CAPTURE,
+		  RasterDefinition::UHD_4K,
+		  HDMIWireFormat::Unknown,
+		  VPIDStandard_2160_Single_12Gb,
+		  4,
+		  4,
+		  kEnable4KTSI,
+		  "sdi[{ch1}][0]->dli[{ch1}][0];"
+		  "sdi[{ch1}][1]->dli[{ch1}][1];"
+		  "sdi[{ch2}][0]->dli[{ch2}][0];"
+		  "sdi[{ch2}][1]->dli[{ch2}][1];"
+		  "sdi[{ch3}][0]->dli[{ch3}][0];"
+		  "sdi[{ch3}][1]->dli[{ch3}][1];"
+		  "sdi[{ch4}][0]->dli[{ch4}][0];"
+		  "sdi[{ch4}][1]->dli[{ch4}][1];"
+		  "dli[{ch1}][0]->tsi[{ch1}][0];"
+		  "dli[{ch2}][0]->tsi[{ch1}][1];"
+		  "dli[{ch3}][0]->tsi[{ch2}][0];"
+		  "dli[{ch4}][0]->tsi[{ch2}][1];"
+		  "tsi[{ch1}][2]->fb[{ch1}][0];"
+		  "tsi[{ch1}][3]->fb[{ch1}][1];"
+		  "tsi[{ch2}][2]->fb[{ch2}][0];"
+		  "tsi[{ch2}][3]->fb[{ch2}][1];",
+		  {DEVICE_ID_KONA5, DEVICE_ID_IO4KPLUS},
+		  true,
+		  true}},
+		/////////////////////////////////
 		/*
         * SDI RGB Display
         */
@@ -1496,6 +1758,7 @@ bool RoutingConfigurator::FindFirstPreset(ConnectionKind kind, NTV2DeviceID id,
 					  NTV2Mode mode, NTV2VideoFormat vf,
 					  NTV2PixelFormat pf,
 					  VPIDStandard standard,
+					  HDMIWireFormat hwf,
 					  RoutingPreset &preset)
 {
 	if (NTV2DeviceCanDoVideoFormat(id, vf) &&
@@ -1507,23 +1770,30 @@ bool RoutingConfigurator::FindFirstPreset(ConnectionKind kind, NTV2DeviceID id,
 			if (p.second.kind == kind && p.second.mode == mode &&
 			    p.second.raster_def == rd &&
 			    p.second.is_rgb == is_rgb &&
-			    p.second.vpid_standard == standard) {
+			    p.second.vpid_standard == standard &&
+			    p.second.hdmi_wire_format == hwf) {
 				query.push_back(p);
 			}
 		}
 		RoutingPresets device_presets;
-		for (const auto &q : query) {
+		RoutingPresets non_device_presets;
+		for (auto &q : query) {
+			if (q.second.device_ids.size() == 0)
+				non_device_presets.push_back(q.second);
 			for (const auto &device_id : q.second.device_ids) {
-				if (device_id == id)
+				if (device_id == id) {
 					device_presets.push_back(q.second);
+					break;
+				}
 			}
 		}
+
 		if (device_presets.size() > 0) {
 			preset = device_presets.at(0);
 			return true;
 		}
-		if (query.size() > 0) {
-			preset = query.at(0).second;
+		if (non_device_presets.size() > 0) {
+			preset = non_device_presets.at(0);
 			return true;
 		}
 	}

+ 1 - 1
plugins/aja/aja-presets.hpp

@@ -39,7 +39,7 @@ public:
 	bool FindFirstPreset(ConnectionKind kind, NTV2DeviceID id,
 			     NTV2Mode mode, NTV2VideoFormat vf,
 			     NTV2PixelFormat pf, VPIDStandard standard,
-			     RoutingPreset &preset);
+			     HDMIWireFormat hwf, RoutingPreset &preset);
 
 private:
 	void build_preset_table();

+ 101 - 94
plugins/aja/aja-routing.cpp

@@ -6,6 +6,7 @@
 #include <ajabase/common/common.h>
 #include <ajantv2/includes/ntv2card.h>
 #include <ajantv2/includes/ntv2devicefeatures.h>
+#include <ajantv2/includes/ntv2utils.h>
 
 #include <obs-module.h>
 
@@ -205,7 +206,7 @@ void Routing::StopSourceAudio(const SourceProps &props, CNTV2Card *card)
 }
 
 bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
-				   CNTV2Card *card)
+				   CNTV2Card *card, NTV2XptConnections &cnx)
 {
 	if (!card)
 		return false;
@@ -213,13 +214,18 @@ bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
 	bool found_preset = false;
 	auto deviceID = props.deviceID;
 	NTV2VideoFormat vf = props.videoFormat;
-
+	bool is_hfr = NTV2_IS_HIGH_NTV2FrameRate(
+		GetNTV2FrameRateFromVideoFormat(props.videoFormat));
 	auto init_src = props.InitialInputSource();
 	auto init_channel = props.Channel();
+
 	RoutingConfigurator rc;
 	RoutingPreset rp;
+	ConnectionKind kind = ConnectionKind::Unknown;
+	VPIDStandard vpidStandard = VPIDStandard_Unknown;
+	HDMIWireFormat hwf = HDMIWireFormat::Unknown;
 	if (NTV2_INPUT_SOURCE_IS_SDI(init_src)) {
-		auto vpidStandard = VPIDStandard_Unknown;
+		kind = ConnectionKind::SDI;
 		if (props.autoDetect) {
 			auto vpidList = props.vpids;
 			if (vpidList.size() > 0)
@@ -231,40 +237,58 @@ bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
 				props.pixelFormat, props.sdiTransport,
 				props.sdi4kTransport);
 		}
-		if (!rc.FindFirstPreset(ConnectionKind::SDI, props.deviceID,
-					NTV2_MODE_CAPTURE, vf,
-					props.pixelFormat, vpidStandard, rp)) {
-			blog(LOG_WARNING,
-			     "No SDI capture routing preset found!");
-			return false;
-		}
 	} else if (NTV2_INPUT_SOURCE_IS_HDMI(init_src)) {
-		HDMIWireFormat hwf = HDMIWireFormat::Unknown;
+		kind = ConnectionKind::HDMI;
 		if (NTV2_IS_FBF_RGB(props.pixelFormat)) {
-			if (NTV2_IS_HD_VIDEO_FORMAT(vf))
-				hwf = HDMIWireFormat::HD_RGB_LFR;
+			if (NTV2_IS_HD_VIDEO_FORMAT(vf)) {
+				hwf = HDMIWireFormat::SD_HD_RGB;
+			} else if (NTV2_IS_4K_VIDEO_FORMAT(vf)) {
+				hwf = HDMIWireFormat::UHD_4K_RGB;
+			}
 		} else {
-			if (NTV2_IS_HD_VIDEO_FORMAT(vf))
-				hwf = HDMIWireFormat::HD_YCBCR_LFR;
-			else if (NTV2_IS_4K_VIDEO_FORMAT(vf))
-				hwf = HDMIWireFormat::UHD_4K_YCBCR_LFR;
-		}
-		if (!rc.FindFirstPreset(ConnectionKind::HDMI, props.deviceID,
-					NTV2_MODE_CAPTURE, vf,
-					props.pixelFormat, VPIDStandard_Unknown,
-					rp)) {
-			blog(LOG_WARNING,
-			     "No HDMI capture routing preset found!");
-			return false;
+			if (NTV2_IS_HD_VIDEO_FORMAT(vf)) {
+				hwf = HDMIWireFormat::SD_HD_YCBCR;
+			} else if (NTV2_IS_4K_VIDEO_FORMAT(vf)) {
+				hwf = HDMIWireFormat::UHD_4K_YCBCR;
+			}
 		}
+	} else {
+		blog(LOG_WARNING,
+		     "Unsupported connection kind. SDI and HDMI only!");
+		return false;
+	}
+
+	if (!rc.FindFirstPreset(kind, props.deviceID, NTV2_MODE_CAPTURE, vf,
+				props.pixelFormat, vpidStandard, hwf, rp)) {
+		blog(LOG_WARNING, "No SDI capture routing preset found!");
+		return false;
 	}
 
 	LogRoutingPreset(rp);
 
 	// Substitute channel placeholders for actual indices
 	std::string route_string = rp.route_string;
+
+	// Channel-substitution for widgets associated with framestore channel(s)
+	ULWord start_framestore_index =
+		GetIndexForNTV2Channel(props.Framestore());
+	const std::vector<std::string> fs_associated = {"fb", "tsi", "dli"};
+	for (ULWord c = 0; c < NTV2_MAX_NUM_CHANNELS; c++) {
+		for (const auto &name : fs_associated) {
+			std::string placeholder = std::string(
+				name + "[{ch" + aja::to_string(c + 1) + "}]");
+			route_string = aja::replace(
+				route_string, placeholder,
+				name + "[" +
+					aja::to_string(start_framestore_index) +
+					"]");
+		}
+		start_framestore_index++;
+	}
+
+	// Replace other channel placeholders
 	ULWord start_channel_index = GetIndexForNTV2Channel(init_channel);
-	for (ULWord c = 0; c < 8; c++) {
+	for (ULWord c = 0; c < NTV2_MAX_NUM_CHANNELS; c++) {
 		std::string channel_placeholder =
 			std::string("{ch" + aja::to_string(c + 1) + "}");
 		route_string =
@@ -272,7 +296,6 @@ bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
 				     aja::to_string(start_channel_index++));
 	}
 
-	NTV2XptConnections cnx;
 	if (!ParseRouteString(route_string, cnx))
 		return false;
 
@@ -299,9 +322,18 @@ bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
 			(UWord)i, rp.flags & kConvert3GaRGBOut);
 	}
 
+	// Apply HDMI settings
+	if (aja::IsIOSelectionHDMI(props.ioSelect)) {
+		if (NTV2_IS_4K_VIDEO_FORMAT(props.videoFormat))
+			card->SetHDMIV2Mode(NTV2_HDMI_V2_4K_CAPTURE);
+		else
+			card->SetHDMIV2Mode(NTV2_HDMI_V2_HDSD_BIDIRECTIONAL);
+	}
+
 	// Apply Framestore settings
-	for (uint32_t i = (uint32_t)start_channel_index;
-	     i < (start_channel_index + rp.num_framestores); i++) {
+	start_framestore_index = GetIndexForNTV2Channel(props.Framestore());
+	for (uint32_t i = (uint32_t)start_framestore_index;
+	     i < (start_framestore_index + rp.num_framestores); i++) {
 		NTV2Channel channel = GetNTV2ChannelForIndex(i);
 		card->EnableChannel(channel);
 		card->SetMode(channel, mode);
@@ -318,13 +350,15 @@ bool Routing::ConfigureSourceRoute(const SourceProps &props, NTV2Mode mode,
 }
 
 bool Routing::ConfigureOutputRoute(const OutputProps &props, NTV2Mode mode,
-				   CNTV2Card *card)
+				   CNTV2Card *card, NTV2XptConnections &cnx)
 {
 	if (!card)
 		return false;
 
 	bool found_preset = false;
 	auto deviceID = props.deviceID;
+	bool is_hfr = NTV2_IS_HIGH_NTV2FrameRate(
+		GetNTV2FrameRateFromVideoFormat(props.videoFormat));
 	NTV2OutputDestinations outputDests;
 	aja::IOSelectionToOutputDests(props.ioSelect, outputDests);
 	if (outputDests.empty()) {
@@ -336,46 +370,43 @@ bool Routing::ConfigureOutputRoute(const OutputProps &props, NTV2Mode mode,
 
 	RoutingConfigurator rc;
 	RoutingPreset rp;
+	ConnectionKind kind = ConnectionKind::Unknown;
+	VPIDStandard vpidStandard = VPIDStandard_Unknown;
+	HDMIWireFormat hwf = HDMIWireFormat::Unknown;
 	if (NTV2_OUTPUT_DEST_IS_SDI(init_dest)) {
-		VPIDStandard vpidStandard = DetermineVPIDStandard(
-			deviceID, props.ioSelect, props.videoFormat,
-			props.pixelFormat, props.sdiTransport,
-			props.sdi4kTransport);
-		if (!rc.FindFirstPreset(ConnectionKind::SDI, props.deviceID,
-					NTV2_MODE_DISPLAY, props.videoFormat,
-					props.pixelFormat, vpidStandard, rp)) {
-			blog(LOG_WARNING,
-			     "No SDI output routing preset found!");
-			return false;
-		}
+		kind = ConnectionKind::SDI;
+		vpidStandard = DetermineVPIDStandard(deviceID, props.ioSelect,
+						     props.videoFormat,
+						     props.pixelFormat,
+						     props.sdiTransport,
+						     props.sdi4kTransport);
 	} else if (NTV2_OUTPUT_DEST_IS_HDMI(init_dest)) {
-		HDMIWireFormat hwf = HDMIWireFormat::Unknown;
-		// special case devices...
-		if (props.deviceID == DEVICE_ID_TTAP_PRO) {
-			hwf = HDMIWireFormat::TTAP_PRO;
+		kind = ConnectionKind::HDMI;
+		hwf = HDMIWireFormat::Unknown;
+		if (NTV2_IS_FBF_RGB(props.pixelFormat)) {
+			if (NTV2_IS_HD_VIDEO_FORMAT(props.videoFormat)) {
+				hwf = HDMIWireFormat::SD_HD_RGB;
+			} else if (NTV2_IS_4K_VIDEO_FORMAT(props.videoFormat)) {
+				hwf = HDMIWireFormat::UHD_4K_RGB;
+			}
 		} else {
-			// ...all other devices.
-			if (NTV2_IS_FBF_RGB(props.pixelFormat)) {
-				if (NTV2_IS_HD_VIDEO_FORMAT(props.videoFormat))
-					hwf = HDMIWireFormat::HD_RGB_LFR;
-			} else {
-				if (NTV2_IS_HD_VIDEO_FORMAT(
-					    props.videoFormat)) {
-					hwf = HDMIWireFormat::HD_YCBCR_LFR;
-				} else if (NTV2_IS_4K_VIDEO_FORMAT(
-						   props.videoFormat)) {
-					hwf = HDMIWireFormat::UHD_4K_YCBCR_LFR;
-				}
+			if (NTV2_IS_HD_VIDEO_FORMAT(props.videoFormat)) {
+				hwf = HDMIWireFormat::SD_HD_YCBCR;
+			} else if (NTV2_IS_4K_VIDEO_FORMAT(props.videoFormat)) {
+				hwf = HDMIWireFormat::UHD_4K_YCBCR;
 			}
 		}
-		if (!rc.FindFirstPreset(ConnectionKind::HDMI, props.deviceID,
-					NTV2_MODE_DISPLAY, props.videoFormat,
-					props.pixelFormat, VPIDStandard_Unknown,
-					rp)) {
-			blog(LOG_WARNING,
-			     "No HDMI output routing preset found!");
-			return false;
-		}
+	} else {
+		blog(LOG_WARNING,
+		     "Unsupported connection kind. SDI and HDMI only!");
+		return false;
+	}
+
+	if (!rc.FindFirstPreset(kind, props.deviceID, NTV2_MODE_DISPLAY,
+				props.videoFormat, props.pixelFormat,
+				vpidStandard, hwf, rp)) {
+		blog(LOG_WARNING, "No HDMI output routing preset found!");
+		return false;
 	}
 
 	LogRoutingPreset(rp);
@@ -384,8 +415,8 @@ bool Routing::ConfigureOutputRoute(const OutputProps &props, NTV2Mode mode,
 
 	// Replace framestore channel placeholders
 	auto init_channel = NTV2OutputDestinationToChannel(init_dest);
-	ULWord start_framestore_index = InitialFramestoreOutputIndex(
-		deviceID, props.ioSelect, init_channel);
+	ULWord start_framestore_index =
+		GetIndexForNTV2Channel(props.Framestore());
 	if (rp.verbatim) {
 		// Presets marked "verbatim" must only be routed on the specified channels
 		start_framestore_index = 0;
@@ -417,14 +448,14 @@ bool Routing::ConfigureOutputRoute(const OutputProps &props, NTV2Mode mode,
 				     aja::to_string(start_channel_index++));
 	}
 
-	NTV2XptConnections cnx;
 	if (!ParseRouteString(route_string, cnx))
 		return false;
 
 	card->ApplySignalRoute(cnx, false);
 
 	// Apply SDI widget settings
-	if (props.ioSelect != IOSelection::HDMIMonitorOut) {
+	if (props.ioSelect != IOSelection::HDMIMonitorOut ||
+	    props.deviceID == DEVICE_ID_TTAP_PRO) {
 		start_channel_index = GetIndexForNTV2Channel(init_channel);
 		for (uint32_t i = (uint32_t)start_channel_index;
 		     i < (start_channel_index + rp.num_channels); i++) {
@@ -451,8 +482,7 @@ bool Routing::ConfigureOutputRoute(const OutputProps &props, NTV2Mode mode,
 	}
 
 	// Apply Framestore settings
-	start_framestore_index = InitialFramestoreOutputIndex(
-		deviceID, props.ioSelect, init_channel);
+	start_framestore_index = GetIndexForNTV2Channel(props.Framestore());
 	if (rp.verbatim) {
 		start_framestore_index = 0;
 	}
@@ -557,29 +587,6 @@ void Routing::ConfigureOutputAudio(const OutputProps &props, CNTV2Card *card)
 	card->StopAudioOutput(audioSys);
 }
 
-ULWord Routing::InitialFramestoreOutputIndex(NTV2DeviceID deviceID,
-					     IOSelection io,
-					     NTV2Channel init_channel)
-{
-	if (deviceID == DEVICE_ID_TTAP_PRO) {
-		return 0;
-	} else if (deviceID == DEVICE_ID_KONA1) {
-		return 1;
-	} else if (deviceID == DEVICE_ID_IO4K ||
-		   deviceID == DEVICE_ID_IO4KPLUS) {
-		// SDI Monitor output uses framestore 4
-		if (io == IOSelection::SDI5)
-			return 3;
-	}
-
-	// HDMI Monitor output uses framestore 4
-	if (io == IOSelection::HDMIMonitorOut) {
-		return 3;
-	}
-
-	return GetIndexForNTV2Channel(init_channel);
-}
-
 void Routing::LogRoutingPreset(const RoutingPreset &rp)
 {
 	auto hexStr = [&](uint8_t val) -> std::string {

+ 4 - 6
plugins/aja/aja-routing.hpp

@@ -52,15 +52,13 @@ public:
 	static void StopSourceAudio(const SourceProps &props, CNTV2Card *card);
 
 	static bool ConfigureSourceRoute(const SourceProps &props,
-					 NTV2Mode mode, CNTV2Card *card);
+					 NTV2Mode mode, CNTV2Card *card,
+					 NTV2XptConnections &cnx);
 	static bool ConfigureOutputRoute(const OutputProps &props,
-					 NTV2Mode mode, CNTV2Card *card);
+					 NTV2Mode mode, CNTV2Card *card,
+					 NTV2XptConnections &cnx);
 	static void ConfigureOutputAudio(const OutputProps &props,
 					 CNTV2Card *card);
-
-	static ULWord InitialFramestoreOutputIndex(NTV2DeviceID deviceID,
-						   IOSelection io,
-						   NTV2Channel init_channel);
 	static void LogRoutingPreset(const RoutingPreset &rp);
 };
 

+ 3 - 2
plugins/aja/aja-source.cpp

@@ -1023,8 +1023,9 @@ static void aja_source_update(void *data, obs_data_t *settings)
 
 	// Change capture format and restart capture thread
 	if (!initialized || want_props != ajaSource->GetSourceProps()) {
-		aja::Routing::ConfigureSourceRoute(want_props,
-						   NTV2_MODE_CAPTURE, card);
+		NTV2XptConnections xpt_cnx;
+		aja::Routing::ConfigureSourceRoute(
+			want_props, NTV2_MODE_CAPTURE, card, xpt_cnx);
 		ajaSource->Deactivate();
 		initialized = true;
 	}