private static MediaPlayerState BuildOne(IBMDSwitcherMediaPlayer props, AtemStateBuilderSettings updateSettings, bool hasClips) { var state = new MediaPlayerState(); if (hasClips) { state.ClipStatus = new MediaPlayerState.ClipStatusState(); } props.GetSource(out _BMDSwitcherMediaPlayerSourceType type, out uint index); state.Source.SourceType = AtemEnumMaps.MediaPlayerSourceMap.FindByValue(type); state.Source.SourceIndex = index; if (state.ClipStatus != null) { props.GetPlaying(out int playing); state.ClipStatus.Playing = playing != 0; props.GetLoop(out int loop); state.ClipStatus.Loop = loop != 0; if (updateSettings.TrackMediaClipFrames) { props.GetAtBeginning(out int atBegining); state.ClipStatus.AtBeginning = atBegining != 0; props.GetClipFrame(out uint clipFrame); state.ClipStatus.ClipFrame = clipFrame; } } return(state); }
public static IReadOnlyList <MediaPlayerState> Build(IBMDSwitcher switcher, AtemStateBuilderSettings updateSettings, bool hasClips) { var iterator = AtemSDKConverter.CastSdk <IBMDSwitcherMediaPlayerIterator>(switcher.CreateIterator); return(AtemSDKConverter.IterateList <IBMDSwitcherMediaPlayer, MediaPlayerState>(iterator.Next, (media, id) => BuildOne(media, updateSettings, hasClips))); }
public AtemSdkClientWrapper(string address, AtemStateBuilderSettings updateSettings, int id) { var logRepository = LogManager.GetRepository(Assembly.GetExecutingAssembly()); XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config")); if (!logRepository.Configured) // Default to all on the console { BasicConfigurator.Configure(logRepository); } Id = id; _updateSettings = updateSettings; _switcherDiscovery = new CBMDSwitcherDiscovery(); Assert.NotNull(_switcherDiscovery); _BMDSwitcherConnectToFailure failReason = 0; try { _switcherDiscovery.ConnectTo(address, out _sdkSwitcher, out failReason); } catch (COMException) { throw new Exception($"SDK Connection failure: {failReason}"); } //_sdkSwitcher.AddCallback(new SwitcherConnectionMonitor()); // TODO - make this monitor work better! _sdkState = new AtemSDKStateMonitor(_sdkSwitcher); _sdkState.OnStateChange += (s) => OnSdkStateChange?.Invoke(s); }
public AtemTestHelper(AtemSdkClientWrapper client, ITestOutputHelper output, AtemMockServer mockServer, AtemStateBuilderSettings stateSettings) { _mockServer = mockServer; SdkClient = client; Output = output; StateSettings = stateSettings; SyncStates(); _mockServer.LibReceive += LibAtemReceive; AssertStatesMatch(); }
private void RunTest(string caseId) { if (caseId == "") { return; } var commandData = DumpParser.BuildCommands(DeviceTestCases.Version, caseId); /* * var result = new List<string>(); * foreach (byte[] payload in commandData) * { * foreach (ParsedCommand rawCmd in ReceivedPacket.ParseCommands(payload)) * { * if (CommandParser.Parse(caseId.Item1, rawCmd) == null) * { * _output.WriteLine("{0} - {1}", rawCmd.Name, rawCmd.BodyLength); * result.Add(rawCmd.Name); * } * } * } * Assert.Empty(result); * // */ using var server = new AtemMockServer("127.0.0.1", commandData, DeviceTestCases.Version); var stateSettings = new AtemStateBuilderSettings(); using var helper = new AtemSdkClientWrapper("127.0.0.1", stateSettings, 1); var libAtemState = AtemTestHelper.SanitiseStateIncompabalities(DeviceTestCases.Version, GetLibAtemState(stateSettings, "127.0.0.1")); var sdkState = helper.BuildState(); List <string> before = AtemStateComparer.AreEqual(sdkState, libAtemState); if (before.Count != 0 && _output != null) { _output.WriteLine("state mismatch:"); before.ForEach(_output.WriteLine); } Assert.Empty(before); }
// public AtemClient LibAtemClient { get; } // private bool _isDisposing; // private bool _libAtemConnected; public AtemMockServerPoolItem(string caseId, AtemStateBuilderSettings builderSettings, string bindIp) { _builderSettings = builderSettings; _bindIp = bindIp; _sdkClients = new Queue <AtemSdkClientWrapper>(); _updatingClients = new List <AtemSdkClientWrapper>(); _nextSdkId = 0; List <byte[]> payloads = DumpParser.BuildCommands(DeviceTestCases.Version, caseId); // IReadOnlyList<ICommand> commands = DumpParser.ParseToCommands(DeviceTestCases.Version, payloads); // Build the device profile // var deviceProfileBuilder = new DeviceProfile.DeviceProfileHandler(); // deviceProfileBuilder.HandleCommands(null, commands); // DeviceProfile = deviceProfileBuilder.Profile; // Build a default state // var state = new AtemState(); // commands.ForEach(cmd => AtemStateBuilder.Update(state, cmd, builderSettings)); // DefaultState = state; Server = new AtemMockServer(bindIp, payloads, DeviceTestCases.Version); /* * var connectionEvent = new AutoResetEvent(false); * LibAtemClient = new AtemClient(bindIp, false); * LibAtemClient.OnDisconnect += o => { Assert.True(_isDisposing, "LibAtem: Disconnect before disposing"); }; * LibAtemClient.OnConnection += o => * { * Assert.False(_libAtemConnected, "LibAtem: Got reconnect"); * _libAtemConnected = true; * connectionEvent.Set(); * }; * LibAtemClient.Connect(); * * //SdkClient = new AtemSdkClientWrapper(bindIp", StateSettings); * * Assert.True(connectionEvent.WaitOne(TimeSpan.FromSeconds(3)), "LibAtem: Connection attempt timed out"); */ }
public static void Build(AtemState state, IBMDSwitcherCameraControl camera, AtemStateBuilderSettings updateSettings) { camera.GetPeriodicFlushInterval(out uint interval); state.CameraControl.PeriodicFlushInterval = interval; IBMDSwitcherCameraControlParameterIterator iterator = AtemSDKConverter.CastSdk <IBMDSwitcherCameraControlParameterIterator>(camera.CreateIterator); uint lastDevice = uint.MaxValue; uint lastCategory = 0u; uint lastParameter = 0u; for (iterator.Next(out var device, out var category, out var parameter); ; iterator.Next(out device, out category, out parameter)) { if (device == lastDevice && category == lastCategory && parameter == lastParameter) { break; } lastDevice = device; lastCategory = category; lastParameter = parameter; if (device == 0) { continue; } if (!state.CameraControl.Cameras.TryGetValue(device, out CameraControlState.CameraState cState)) { cState = state.CameraControl.Cameras[device] = new CameraControlState.CameraState(); } CameraControlGetCommand cmd = BuildCommand(camera, device, category, parameter); CameraControlUtil.ApplyToState(cState, cmd, updateSettings.IgnoreUnknownCameraControlProperties); } }
/* * [Fact] * public void TestStateReal() * { * var stateSettings = new AtemStateBuilderSettings(); * using var helper = new AtemSdkClientWrapper("10.42.13.95", stateSettings); * * var libAtemState = GetLibAtemState(stateSettings, "10.42.13.95"); * * List<string> before = AtemStateComparer.AreEqual(helper.State, libAtemState); * if (before.Count != 0 && _output != null) * { * _output.WriteLine("state mismatch:"); * before.ForEach(_output.WriteLine); * } * Assert.Empty(before); * } */ private AtemState GetLibAtemState(AtemStateBuilderSettings stateSettings, string address) { using var client = new AtemClient(address, false); var state = new AtemState(); AutoResetEvent handshakeEvent = new AutoResetEvent(false); bool handshakeFinished = false; client.OnReceive += (o, cmds) => { cmds.ForEach(cmd => AtemStateBuilder.Update(state, cmd, stateSettings)); if (!handshakeFinished && cmds.Any(c => c is InitializationCompleteCommand)) { handshakeEvent.Set(); handshakeFinished = true; } }; client.Connect(); Assert.True(handshakeEvent.WaitOne(5000)); return(state); }
public static AtemState Build(IBMDSwitcher switcher, AtemStateBuilderSettings updateSettings) { var state = new AtemState(); switcher.GetProductName(out string productName); state.Info.ProductName = productName; switcher.GetVideoMode(out _BMDSwitcherVideoMode videoMode); state.Settings.VideoMode = AtemEnumMaps.VideoModesMap.FindByValue(videoMode); #if !ATEM_v8_1 switcher.GetTimeCodeMode(out _BMDSwitcherTimeCodeMode timeCodeMode); if (timeCodeMode != 0) { state.Settings.TimeCodeMode = AtemEnumMaps.TimeCodeModeMap.FindByValue(timeCodeMode); } #endif switcher.GetTimeCodeLocked(out int locked); state.Info.TimecodeLocked = locked != 0; switcher.GetTimeCode(out byte hours, out byte minutes, out byte seconds, out byte frames, out int dropFrame); state.Info.LastTimecode = new Timecode { Hour = hours, Minute = minutes, Second = seconds, Frame = frames, DropFrame = dropFrame != 0 }; switcher.GetAreOutputsConfigurable(out int configurable); state.Info.OnlyConfigurableOutputs = configurable != 0; state.Info.HasCameraControl = switcher is IBMDSwitcherCameraControl; state.Info.AdvancedChromaKeyers = MixEffectStateBuilder.SupportsAdvancedChromaKeyers(switcher); try { switcher.Get3GSDIOutputLevel(out _BMDSwitcher3GSDIOutputLevel outputLevel); state.Settings.SDI3GLevel = AtemEnumMaps.SDI3GOutputLevelMap.FindByValue(outputLevel); } catch (Exception) { // This call fails on models which dont do 3g sdi state.Settings.SDI3GLevel = 0; } try { switcher.GetSuperSourceCascade(out int cascade); state.Settings.SuperSourceCascade = cascade != 0; } catch (Exception) { // This call fails on models which dont have multiple ssrc state.Settings.SuperSourceCascade = false; } switcher.GetPowerStatus(out _BMDSwitcherPowerStatus powerStatus); state.Power = new[] { powerStatus.HasFlag(_BMDSwitcherPowerStatus.bmdSwitcherPowerStatusSupply1), powerStatus.HasFlag(_BMDSwitcherPowerStatus.bmdSwitcherPowerStatusSupply2), }; bool supportsDownConvert = true; bool supportsMultiviewer = true; var modes = new List <VideoModeInfo>(); var allModes = Enum.GetValues(typeof(_BMDSwitcherVideoMode)).OfType <_BMDSwitcherVideoMode>().ToArray(); foreach (_BMDSwitcherVideoMode mode in allModes) { switcher.DoesSupportVideoMode(mode, out int supported); if (supported == 0) { continue; } switcher.DoesVideoModeChangeRequireReconfiguration(mode, out int requiresReconfig); var multiviewModes = new List <VideoMode>(); if (supportsMultiviewer) { try { foreach (_BMDSwitcherVideoMode mvMode in allModes) { switcher.DoesSupportMultiViewVideoMode(mode, mvMode, out int mvSupported); if (mvSupported != 0) { multiviewModes.Add(AtemEnumMaps.VideoModesMap.FindByValue(mvMode)); } } } catch (NotImplementedException) { supportsMultiviewer = false; } } var downConvertModes = new List <VideoMode>(); if (supportsDownConvert) { try { foreach (_BMDSwitcherVideoMode dcMode in allModes) { switcher.DoesSupportDownConvertedHDVideoMode(mode, dcMode, out int convertSupported); if (convertSupported != 0) { downConvertModes.Add(AtemEnumMaps.VideoModesMap.FindByValue(dcMode)); } } } catch (NotImplementedException) { supportsDownConvert = false; } } modes.Add(new VideoModeInfo { Mode = AtemEnumMaps.VideoModesMap.FindByValue(mode), RequiresReconfig = requiresReconfig != 0, MultiviewModes = multiviewModes.ToArray(), DownConvertModes = downConvertModes.ToArray(), }); } state.Info.SupportedVideoModes = modes.OrderBy(s => s.Mode).ToList(); if (supportsMultiviewer) { foreach (VideoModeInfo mode in state.Info.SupportedVideoModes) { switcher.GetMultiViewVideoMode(AtemEnumMaps.VideoModesMap[mode.Mode], out _BMDSwitcherVideoMode mvMode); state.Settings.MultiviewVideoModes[mode.Mode] = AtemEnumMaps.VideoModesMap.FindByValue(mvMode); } } if (supportsDownConvert) { foreach (VideoModeInfo mode in state.Info.SupportedVideoModes) { switcher.GetDownConvertedHDVideoMode(AtemEnumMaps.VideoModesMap[mode.Mode], out _BMDSwitcherVideoMode dcMode); state.Settings.DownConvertVideoModes[mode.Mode] = AtemEnumMaps.VideoModesMap.FindByValue(dcMode); } } try { switcher.GetMethodForDownConvertedSD(out _BMDSwitcherDownConversionMethod downConvertMethod); state.Settings.DownConvertMode = AtemEnumMaps.SDDownconvertModesMap.FindByValue(downConvertMethod); } catch (Exception) { // Not supported } switcher.DoesSupportAutoVideoMode(out int autoModeSupported); state.Info.SupportsAutoVideoMode = autoModeSupported != 0; if (state.Info.SupportsAutoVideoMode) { switcher.GetAutoVideoMode(out int autoVideoMode); state.Settings.AutoVideoMode = autoVideoMode != 0; switcher.GetAutoVideoModeDetected(out int detected); state.Settings.DetectedVideoMode = detected != 0; } DveInfo(state, switcher); SourceStateBuilder.Build(state, switcher); Hyperdecks(state, switcher); SerialPorts(state, switcher); Macros(state.Macros, switcher); MediaPoolStateBuilder.Build(state.MediaPool, switcher); MixMinusOutputs(state, switcher); StreamingStateBuilder.Build(state, switcher); RecordingStateBuilder.Build(state, switcher); state.DownstreamKeyers = DownstreamKeyerStateBuilder.Build(switcher); state.MediaPlayers = MediaPlayerStateBuilder.Build(switcher, updateSettings, state.MediaPool.Clips.Count > 0); state.MixEffects = MixEffectStateBuilder.Build(switcher); MultiViewerStateBuilder.Build(switcher, state); if (switcher is IBMDSwitcherFairlightAudioMixer fairlight) { state.Fairlight = FairlightAudioMixerStateBuilder.Build(fairlight); } if (switcher is IBMDSwitcherAudioMixer audioMixer) { state.Audio = AudioStateBuilder.Build(audioMixer); } #if !ATEM_v8_1 TalkbackStateBuilder.Build(state, switcher); #endif if (switcher is IBMDSwitcherCameraControl camera) { CameraControlBuilder.Build(state, camera, updateSettings); } return(state); }
public AtemServerClientPool() { _pool = new Dictionary <string, AtemMockServerPoolItem>(); StateSettings = new AtemStateBuilderSettings(); }