// This will reenable routing if previous cleared. // Should not be needed otherwise since FromSource changes will automatically update. public void UpdateRouting() { // never started before? if (_routingInstancePtr == IntPtr.Zero) { CreateRouting(); return; } // Sanity if (_selectedSource == null || String.IsNullOrEmpty(_selectedSource.Name)) { Clear(); return; } // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ndi_name = UTF.StringToUtf8(_selectedSource.Name) }; if (!NDIlib.routing_change(_routingInstancePtr, ref source_t)) { // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); throw new InvalidOperationException("Failed to change routing."); } // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); }
// connect to an NDI source in our Dictionary by name public void Connect(Source source) { // just in case we're already connected // _delegateUpdateDynImage = UpdateDynImage; Disconnect(); // Sanity if (source == null || (String.IsNullOrEmpty(source.Name))) { return; } // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ndi_name = UTF.StringToUtf8(source.Name) }; // make a description of the receiver we want NDIlib.recv_create_v3_t recvDescription = new NDIlib.recv_create_v3_t() { // the source we selected source_to_connect_to = source_t, // we want BGRA frames for this example color_format = NDIlib.recv_color_format_e.recv_color_format_BGRX_BGRA, // we want full quality - for small previews or limited bandwidth, choose lowest bandwidth = NDIlib.recv_bandwidth_e.recv_bandwidth_highest, // let NDIlib deinterlace for us if needed allow_video_fields = false }; // create a new instance connected to this source _recvInstancePtr = NDIlib.recv_create_v3(ref recvDescription); // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); // did it work? System.Diagnostics.Debug.Assert(_recvInstancePtr != IntPtr.Zero, "Failed to create NDI receive instance."); if (_recvInstancePtr != IntPtr.Zero) { // We are now going to mark this source as being on program output for tally purposes (but not on preview) SetTallyIndicators(true, false); _source = source; // start up a thread to receive on _receiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "NdiReceiveThread" }; _receiveThread.Start(); } }
// connect to an NDI source in our Dictionary by name public void Connect(NDIlib.recv_color_format_e colorFormat) { // just in case we're already connected Disconnect(); // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ndi_name = UTF.StringToUtf8(_sourceName) }; // make a description of the receiver we want NDIlib.recv_create_v3_t recvDescription = new NDIlib.recv_create_v3_t() { // the source we selected source_to_connect_to = source_t, // we want BGRA frames for this example color_format = colorFormat, // we want full quality - for small previews or limited bandwidth, choose lowest bandwidth = _videoEnabled ? NDIlib.recv_bandwidth_e.recv_bandwidth_highest : NDIlib.recv_bandwidth_e.recv_bandwidth_audio_only, // let NDIlib deinterlace for us if needed allow_video_fields = false, // The name of the NDI receiver to create. This is a NULL terminated UTF8 string and should be // the name of receive channel that you have. This is in many ways symettric with the name of // senders, so this might be "Channel 1" on your system. p_ndi_recv_name = UTF.StringToUtf8(_receiverName) }; // create a new instance connected to this source _recvInstancePtr = NDIlib.recv_create_v3(ref recvDescription); // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); Marshal.FreeHGlobal(recvDescription.p_ndi_recv_name); // did it work? System.Diagnostics.Debug.Assert(_recvInstancePtr != IntPtr.Zero, "Failed to create NDI receive instance."); if (_recvInstancePtr != IntPtr.Zero) { // We are now going to mark this source as being on program output for tally purposes (but not on preview) SetTallyIndicators(true, false); // start up a thread to receive on _receiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "NdiExampleReceiveThread" }; _receiveThread.Start(); } }
private void FindThreadProc() { // the size of an NDIlib.source_t, for pointer offsets int SourceSizeInBytes = Marshal.SizeOf(typeof(NDIlib.source_t)); while (!_exitThread) { // Wait up to 500ms sources to change if (NDIlib.find_wait_for_sources(_findInstancePtr, 500)) { uint NumSources = 0; IntPtr SourcesPtr = NDIlib.find_get_current_sources(_findInstancePtr, ref NumSources); // convert each unmanaged ptr into a managed NDIlib.source_t for (int i = 0; i < NumSources; i++) { // source ptr + (index * size of a source) IntPtr p = IntPtr.Add(SourcesPtr, (i * SourceSizeInBytes)); // marshal it to a managed source and assign to our list NDIlib.source_t src = (NDIlib.source_t)Marshal.PtrToStructure(p, typeof(NDIlib.source_t)); // .Net doesn't handle marshaling UTF-8 strings properly String name = UTF.Utf8ToString(src.p_ndi_name); // Add it to the list if not already in the list. // We don't have to remove because NDI applications remember any sources seen during each run. // They might be selected and come back when the connection is restored. if (!_sourceList.Any(item => item.Name == name)) { _sourceList.Enqueue(new Source(src)); } } } } }
// connect to an NDI source in our Dictionary by name void Connect(Source source) { if (FInReceiverName.SliceCount == 0 || String.IsNullOrEmpty(FInReceiverName[0])) { FLogger.Log(LogType.Error, "receiverName can not be null or empty."); } // just in case we're already connected Disconnect(); // Sanity if (source == null || String.IsNullOrEmpty(source.Name)) { return; } // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ndi_name = UTF.StringToUtf8(source.Name) }; // make a description of the receiver we want NDIlib.recv_create_v3_t recvDescription = new NDIlib.recv_create_v3_t() { // the source we selected source_to_connect_to = source_t, // we want BGRA frames for this example //color_format = NDIlib.recv_color_format_e.recv_color_format_BGRX_BGRA, color_format = (NDIlib.recv_color_format_e)Enum.ToObject(typeof(NDIlib.recv_color_format_e), (int)FInColorFormat[0]), // we want full quality - for small previews or limited bandwidth, choose lowest //bandwidth = NDIlib.recv_bandwidth_e.recv_bandwidth_highest, bandwidth = (NDIlib.recv_bandwidth_e)Enum.ToObject(typeof(NDIlib.recv_bandwidth_e), (int)FInBandwidth[0]), // let NDIlib deinterlace for us if needed allow_video_fields = false, // The name of the NDI receiver to create. This is a NULL terminated UTF8 string and should be // the name of receive channel that you have. This is in many ways symettric with the name of // senders, so this might be "Channel 1" on your system. p_ndi_recv_name = UTF.StringToUtf8(FInReceiverName[0]) }; // create a new instance connected to this source _recvInstancePtr = NDIlib.recv_create_v3(ref recvDescription); // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); Marshal.FreeHGlobal(recvDescription.p_ndi_recv_name); // did it work? //System.Diagnostics.Debug.Assert(_recvInstancePtr != IntPtr.Zero, "Failed to create NDI receive instance."); if (_recvInstancePtr == IntPtr.Zero) { FLogger.Log(LogType.Warning, "Failed to create NDI receive instance."); } if (_recvInstancePtr != IntPtr.Zero) { // We are now going to mark this source as being on program output for tally purposes (but not on preview) SetTallyIndicators(true, false); // start up a thread to receive on _receiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "NDIReceiveThread" }; _receiveThread.Start(); } }
// connect to an NDI source in our Dictionary by name private void Connect(Source source) { if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { return; } if (String.IsNullOrEmpty(ReceiverName)) { throw new ArgumentException("sourceName can not be null or empty.", ReceiverName); } using (var volOut = new WasapiOut(NAudio.CoreAudioApi.AudioClientShareMode.Shared, 50)) _volume = volOut.Volume; // just in case we're already connected Disconnect(); // before we are connected, we need to set up our image // it's bad practice to do this in the constructor if (Child == null) { Child = VideoSurface; } // Sanity if (source == null || String.IsNullOrEmpty(source.Name)) { return; } // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ndi_name = UTF.StringToUtf8(source.Name) }; // make a description of the receiver we want NDIlib.recv_create_v3_t recvDescription = new NDIlib.recv_create_v3_t() { // the source we selected source_to_connect_to = source_t, // we want BGRA frames for this example color_format = NDIlib.recv_color_format_e.recv_color_format_BGRX_BGRA, // we want full quality - for small previews or limited bandwidth, choose lowest bandwidth = _lowBandwidth ? NDIlib.recv_bandwidth_e.recv_bandwidth_lowest : NDIlib.recv_bandwidth_e.recv_bandwidth_highest, // let NDIlib deinterlace for us if needed allow_video_fields = false, // The name of the NDI receiver to create. This is a NULL terminated UTF8 string and should be // the name of receive channel that you have. This is in many ways symettric with the name of // senders, so this might be "Channel 1" on your system. p_ndi_recv_name = UTF.StringToUtf8(ReceiverName) }; // create a new instance connected to this source _recvInstancePtr = NDIlib.recv_create_v3(ref recvDescription); // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ndi_name); Marshal.FreeHGlobal(recvDescription.p_ndi_recv_name); // did it work? System.Diagnostics.Debug.Assert(_recvInstancePtr != IntPtr.Zero, "Failed to create NDI receive instance."); if (_recvInstancePtr != IntPtr.Zero) { // We are now going to mark this source as being on program output for tally purposes (but not on preview) SetTallyIndicators(true, false); // start up a thread to receive on _receiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "NdiExampleReceiveThread" }; _receiveThread.Start(); } }
// Construct from NDIlib.source_t public Source(NDIlib.source_t source_t) { Name = UTF.Utf8ToString(source_t.p_ndi_name); }
// connect to an NDI source in our Dictionary by name private void Connect(Source source) { if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { return; } // just in case we're already connected Disconnect(); // before we are connected, we need to set up our image // it's bad practice to do this in the constructor if (Child == null) { Child = VideoSurface; } // Sanity if (source == null || (String.IsNullOrEmpty(source.Name) && String.IsNullOrEmpty(source.IpAddress))) { return; } // a source_t to describe the source to connect to. NDIlib.source_t source_t = new NDIlib.source_t() { p_ip_address = UTF.StringToUtf8(source.IpAddress), p_ndi_name = UTF.StringToUtf8(source.Name) }; // make a description of the receiver we want NDIlib.recv_create_t recvDescription = new NDIlib.recv_create_t() { // the source we selected source_to_connect_to = source_t, // we want BGRA frames for this example color_format = NDIlib.recv_color_format_e.recv_color_format_BGRX_BGRA, // we want full quality - for small previews or limited bandwidth, choose lowest bandwidth = NDIlib.recv_bandwidth_e.recv_bandwidth_highest, // let NDIlib deinterlace for us if needed allow_video_fields = false }; // create a new instance connected to this source _recvInstancePtr = NDIlib.recv_create_v2(ref recvDescription); // free the memory we allocated with StringToUtf8 Marshal.FreeHGlobal(source_t.p_ip_address); Marshal.FreeHGlobal(source_t.p_ndi_name); // did it work? System.Diagnostics.Debug.Assert(_recvInstancePtr != IntPtr.Zero, "Failed to create NDI receive instance."); if (_recvInstancePtr != IntPtr.Zero) { // We are now going to mark this source as being on program output for tally purposes (but not on preview) SetTallyIndicators(true, false); // start up a thread to receive on _receiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "NdiExampleReceiveThread" }; _receiveThread.Start(); } }
public Sender(String sourceName, bool clockVideo = true, bool clockAudio = false, String[] groups = null, String failoverName = null) { if (String.IsNullOrEmpty(sourceName)) { throw new ArgumentException("sourceName can not be null or empty.", sourceName); } if (!NDIlib.initialize()) { if (!NDIlib.is_supported_CPU()) { throw new InvalidOperationException("CPU incompatible with NDI."); } else { throw new InvalidOperationException("Unable to initialize NDI."); } } // .Net interop doesn't handle UTF-8 strings, so do it manually // These must be freed later IntPtr sourceNamePtr = UTF.StringToUtf8(sourceName); IntPtr groupsNamePtr = IntPtr.Zero; // make a flat list of groups if needed if (groups != null) { StringBuilder flatGroups = new StringBuilder(); foreach (String group in groups) { flatGroups.Append(group); if (group != groups.Last()) { flatGroups.Append(','); } } groupsNamePtr = UTF.StringToUtf8(flatGroups.ToString()); } // Create an NDI source description NDIlib.send_create_t createDesc = new NDIlib.send_create_t() { p_ndi_name = sourceNamePtr, p_groups = groupsNamePtr, clock_video = clockVideo, clock_audio = clockAudio }; // create the NDI send instance _sendInstancePtr = NDIlib.send_create(ref createDesc); // free the strings we allocated Marshal.FreeHGlobal(sourceNamePtr); Marshal.FreeHGlobal(groupsNamePtr); // did it succeed? if (_sendInstancePtr == IntPtr.Zero) { throw new InvalidOperationException("Failed to create send instance."); } if (!String.IsNullOrEmpty(failoverName)) { // .Net interop doesn't handle UTF-8 strings, so do it manually // These must be freed later IntPtr failoverNamePtr = UTF.StringToUtf8(failoverName); NDIlib.source_t failoverDesc = new NDIlib.source_t() { p_ndi_name = failoverNamePtr, p_url_address = IntPtr.Zero }; NDIlib.send_set_failover(_sendInstancePtr, ref failoverDesc); // free the strings we allocated Marshal.FreeHGlobal(failoverNamePtr); } }
// Construct from NDIlib.source_t public Source(NDIlib.source_t source_t) { Name = UTF.Utf8ToString(source_t.p_ndi_name); _ipAddress = UTF.Utf8ToString(source_t.p_ip_address); }
private void FindThreadProc() { // the size of an NDIlib.source_t, for pointer offsets int SourceSizeInBytes = Marshal.SizeOf(typeof(NDIlib.source_t)); while (!_exitThread) { // Wait up to 500ms sources to change if (NDIlib.find_wait_for_sources(_findInstancePtr, 500)) { uint NumSources = 0; IntPtr SourcesPtr = NDIlib.find_get_current_sources(_findInstancePtr, ref NumSources); // ここでソースリストを初期化しておく //_sourceList.Clear(); // convert each unmanaged ptr into a managed NDIlib.source_t for (int i = 0; i < NumSources; i++) { // source ptr + (index * size of a source) IntPtr p = IntPtr.Add(SourcesPtr, (i * SourceSizeInBytes)); // marshal it to a managed source and assign to our list NDIlib.source_t src = (NDIlib.source_t)Marshal.PtrToStructure(p, typeof(NDIlib.source_t)); // .Net doesn't handle marshaling UTF-8 strings properly String name = UTF.Utf8ToString(src.p_ndi_name); // Add it to the list if not already in the list. // We don't have to remove because NDI applications remember any sources seen during each run. // They might be selected and come back when the connection is restored. if (!_sourceList.Any(item => item.Name == name)) { // VLCが入っていなければ追加しない if (name.Contains("VLC") == true) { _sourceList.Add(new Source(src)); } } } // ソースリストから要らないソースを除いておく //foreach (var item in _sourceList) //{ // bool exclusion_flag = true; // for (int i = 0; i < NumSources; i++) // { // IntPtr p = IntPtr.Add(SourcesPtr, (i * SourceSizeInBytes)); // NDIlib.source_t src = (NDIlib.source_t)Marshal.PtrToStructure(p, typeof(NDIlib.source_t)); // String name = UTF.Utf8ToString(src.p_ndi_name); // if (item.Name == name) // { // exclusion_flag = false; // break; // } // } // if (exclusion_flag == true) // { // _sourceList.Remove(item); // break; // } //} } } }