public VideoPreviewViewmodel() { View = new VideoPreviewView { DataContext = this }; _videoSources = new ObservableCollection <string>(new[] { Common.Properties.Resources._none_ }); _videoSource = _videoSources.FirstOrDefault(); CommandRefreshSources = new UICommand { ExecuteDelegate = RefreshSources, CanExecuteDelegate = o => _ndiFindInstance != IntPtr.Zero }; CommandGotoNdiWebsite = new UICommand { ExecuteDelegate = GotoNdiWebsite }; CommandShowPopup = new UICommand { ExecuteDelegate = o => DisplayPopup = true }; CommandHidePopup = new UICommand { ExecuteDelegate = o => DisplayPopup = false }; InitNdiFind(); if (_ndiFindInstance != IntPtr.Zero) { Task.Run(() => { if (Ndi.NDIlib_find_wait_for_sources(_ndiFindInstance, 5000)) { Thread.Sleep(3000); Application.Current?.Dispatcher.BeginInvoke((Action) delegate { RefreshSources(null); }); } }); } }
private void Connect(string sourceName) { if (string.IsNullOrEmpty(sourceName) || _ndiSources == null || !_ndiSources.ContainsKey(sourceName)) { return; } NDIlib_source_t source = _ndiSources[sourceName]; NDIlib_recv_create_t recvDescription = new NDIlib_recv_create_t() { source_to_connect_to = source, color_format = NDIlib_recv_color_format_e.NDIlib_recv_color_format_e_BGRX_BGRA, bandwidth = NDIlib_recv_bandwidth_e.NDIlib_recv_bandwidth_lowest }; _ndiReceiveInstance = Ndi.NDIlib_recv_create(ref recvDescription); if (_ndiReceiveInstance != IntPtr.Zero) { // start up a thread to receive on _ndiReceiveThread = new Thread(ReceiveThreadProc) { IsBackground = true, Name = "Newtek Ndi video preview plugin receive thread" }; _ndiReceiveThread.Start(); } }
protected override void OnDispose() { Disconnect(); if (_ndiFindInstance != IntPtr.Zero) { Ndi.NDIlib_find_destroy(_ndiFindInstance); } }
private void ReceiveThreadProc() { var recvInstance = _ndiReceiveInstance; if (recvInstance == IntPtr.Zero) { return; } while (!_exitReceiveThread) { NDIlib_video_frame_t videoFrame = new NDIlib_video_frame_t(); NDIlib_audio_frame_t audioFrame = new NDIlib_audio_frame_t(); NDIlib_metadata_frame_t metadataFrame = new NDIlib_metadata_frame_t(); switch (Ndi.NDIlib_recv_capture(recvInstance, ref videoFrame, ref audioFrame, ref metadataFrame, 1000)) { case NDIlib_frame_type_e.NDIlib_frame_type_video: if (videoFrame.p_data == IntPtr.Zero) { Ndi.NDIlib_recv_free_video(recvInstance, ref videoFrame); break; } int yres = (int)videoFrame.yres; int xres = (int)videoFrame.xres; double dpiY = 96.0 * (videoFrame.picture_aspect_ratio / ((double)xres / yres)); int stride = (int)videoFrame.line_stride_in_bytes; int bufferSize = yres * stride; Application.Current?.Dispatcher.BeginInvoke(new Action(delegate { if (VideoBitmap == null || VideoBitmap.PixelWidth != xres || VideoBitmap.PixelHeight != yres) { VideoBitmap = new WriteableBitmap(xres, yres, 96, dpiY, System.Windows.Media.PixelFormats.Pbgra32, null); } // update the writeable bitmap VideoBitmap.Lock(); VideoBitmap.WritePixels(new Int32Rect(0, 0, xres, yres), videoFrame.p_data, bufferSize, stride); VideoBitmap.Unlock(); Ndi.NDIlib_recv_free_video(recvInstance, ref videoFrame); })); break; case NDIlib_frame_type_e.NDIlib_frame_type_audio: Ndi.NDIlib_recv_free_audio(recvInstance, ref audioFrame); break; case NDIlib_frame_type_e.NDIlib_frame_type_metadata: Ndi.NDIlib_recv_free_metadata(recvInstance, ref metadataFrame); break; } } Debug.WriteLine(this, "Receive thread exited"); }
/// <summary> /// Method accepts address in form ndi://ip_address:port and ndi://ip_address:ndi_name /// </summary> /// <param name="sourceUrl"></param> public void SetSource(string sourceUrl) { if (string.IsNullOrWhiteSpace(sourceUrl)) { return; } Uri sourceUri = null; if ((Uri.TryCreate(sourceUrl, UriKind.Absolute, out sourceUri) && sourceUri.Scheme == "ndi") || string.Equals(sourceUrl.Substring(0, sourceUrl.IndexOf(':')), "ndi", StringComparison.InvariantCultureIgnoreCase)) { Application.Current.Dispatcher.BeginInvoke((Action) delegate { if (_ndiSources == null) { return; } string source = null; if (sourceUri != null) { source = _ndiSources.FirstOrDefault(s => Ndi.Utf8ToString(s.Value.p_ip_address) == sourceUri.Host).Key; } else { string address = sourceUrl.Substring(sourceUrl.IndexOf("//") + 2); if (!string.IsNullOrWhiteSpace(address)) { string host = address.Substring(0, address.IndexOf(':')); string name = address.Substring(address.IndexOf(':') + 1); var ndi = _ndiSources.FirstOrDefault(s => { string ndiFullAddress = Ndi.Utf8ToString(s.Value.p_ip_address); string ndiFullName = Ndi.Utf8ToString(s.Value.p_ndi_name); int openingBraceIndex = ndiFullName.IndexOf('(', 1); int closingBraceIndex = ndiFullName.IndexOf(')', openingBraceIndex); if (openingBraceIndex > 0 && closingBraceIndex > openingBraceIndex && ndiFullAddress.Substring(0, ndiFullAddress.IndexOf(':')).Equals(host, StringComparison.InvariantCultureIgnoreCase) && ndiFullName.Substring(openingBraceIndex + 1, closingBraceIndex - openingBraceIndex - 1).Equals(name, StringComparison.InvariantCultureIgnoreCase)) { return(true); } return(false); }).Key; } } if (!string.IsNullOrWhiteSpace(source)) { VideoSource = source; } }); } }
private void Disconnect() { if (_ndiReceiveThread != null) { _exitReceiveThread = true; _ndiReceiveThread.Join(1000); } _ndiReceiveThread = null; _exitReceiveThread = false; Ndi.NDIlib_recv_destroy(_ndiReceiveInstance); _ndiReceiveInstance = IntPtr.Zero; }
private void InitNdiFind() { Ndi.AddRuntimeDir(); var findDesc = new NDIlib_find_create_t() { p_groups = IntPtr.Zero, show_local_sources = true, p_extra_ips = IntPtr.Zero }; _ndiFindInstance = Ndi.NDIlib_find_create2(ref findDesc); }
public VideoPreviewViewmodel() { View = new VideoPreviewView { DataContext = this }; _videoSources = new ObservableCollection <string>(new[] { Common.Properties.Resources._none_ }); _videoSource = _videoSources.FirstOrDefault(); CommandRefreshSources = new UICommand { ExecuteDelegate = RefreshSources, CanExecuteDelegate = o => _ndiFindInstance != IntPtr.Zero }; CommandGotoNdiWebsite = new UICommand { ExecuteDelegate = GotoNdiWebsite }; CommandShowPopup = new UICommand { ExecuteDelegate = o => DisplayPopup = true }; CommandHidePopup = new UICommand { ExecuteDelegate = o => DisplayPopup = false }; InitNdiFind(); var sourcesPoolThread = new Thread(() => { while (_ndiFindInstance != IntPtr.Zero) { if (Ndi.NDIlib_find_wait_for_sources(_ndiFindInstance, int.MaxValue)) { OnUiThread(() => RefreshSources(null)); } } }) { Name = "NDI source list pooling thread", Priority = ThreadPriority.BelowNormal, IsBackground = true }; sourcesPoolThread.Start(); }
private static void RefreshSources() { var numSources = 0; var ndiSources = Ndi.NDIlib_find_get_current_sources(NdiFindInstance, ref numSources); if (numSources <= 0) { return; } var sourceSizeInBytes = Marshal.SizeOf(typeof(NDIlib_source_t)); var sources = new Dictionary <string, NDIlib_source_t>(); for (var i = 0; i < numSources; i++) { var p = IntPtr.Add(ndiSources, (i * sourceSizeInBytes)); var src = (NDIlib_source_t)Marshal.PtrToStructure(p, typeof(NDIlib_source_t)); var ndiName = Ndi.Utf8ToString(src.p_ndi_name); sources.Add(ndiName, src); Debug.WriteLine($"Added source name:{Ndi.Utf8ToString(src.p_ndi_name)} address :{Ndi.Utf8ToString(src.p_ip_address)}"); } _ndiSources = sources; SourceRefreshed?.Invoke(null, EventArgs.Empty); }
static VideoPreviewViewmodel() { Ndi.AddRuntimeDir(); var findDesc = new NDIlib_find_create_t { p_groups = IntPtr.Zero, show_local_sources = true, p_extra_ips = IntPtr.Zero }; NdiFindInstance = Ndi.NDIlib_find_create2(ref findDesc); var sourcesPoolThread = new Thread(() => { try { while (true) { if (Ndi.NDIlib_find_wait_for_sources(NdiFindInstance, int.MaxValue)) { RefreshSources(); } } } catch (Exception e) { Console.WriteLine(e); } }) { Name = "NDI source list pooling thread", Priority = ThreadPriority.BelowNormal, IsBackground = true }; sourcesPoolThread.Start(); }
private void RefreshSources(object obj) { if (_ndiFindInstance != IntPtr.Zero) { int numSources = 0; var ndi_sources = Ndi.NDIlib_find_get_current_sources(_ndiFindInstance, ref numSources); if (numSources > 0) { int SourceSizeInBytes = System.Runtime.InteropServices.Marshal.SizeOf(typeof(NDIlib_source_t)); Dictionary <string, NDIlib_source_t> sources = new Dictionary <string, NDIlib_source_t>(); for (int i = 0; i < numSources; i++) { IntPtr p = IntPtr.Add(ndi_sources, (i * SourceSizeInBytes)); NDIlib_source_t src = (NDIlib_source_t)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(NDIlib_source_t)); var ndiName = Ndi.Utf8ToString(src.p_ndi_name); sources.Add(ndiName, src); Debug.WriteLine($"Added source name:{Ndi.Utf8ToString(src.p_ndi_name)} address :{Ndi.Utf8ToString(src.p_ip_address)}"); } // removing non-existing sources var notExistingSources = _videoSources.Where(s => !(sources.ContainsKey(s) || s == Common.Properties.Resources._none_)).ToArray(); foreach (var source in notExistingSources) { _videoSources.Remove(source); } //adding new sources foreach (var source in sources) { if (!_videoSources.Contains(source.Key)) { _videoSources.Add(source.Key); } } _ndiSources = sources; } } }
protected void gridOrganisation_SortOrderCommand(object sender, Ndi.HelpDesk.WebControls.DataGridSortOrderCommandEventArgs e) { DataGrid dataGrid = (DataGrid)sender; ShowGrid(dataGrid, 0, dataGrid.CurrentSortExpression, e.SortOrder); }