Exemplo n.º 1
0
        // 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);
        }
Exemplo n.º 2
0
        // This will start recording.If the recorder was already recording then the message is ignored.A filename is passed in as a ‘hint’.Since the recorder might
        // already be recording(or might not allow complete flexibility over its filename), the filename might or might not be used.If the filename is empty, or
        // not present, a name will be chosen automatically.
        public bool RecordingStart(String filenameHint = "")
        {
            if (!_canRecord || _recvInstancePtr == IntPtr.Zero)
            {
                return(false);
            }

            bool retVal = false;

            if (String.IsNullOrEmpty(filenameHint))
            {
                retVal = NDIlib.recv_recording_start(_recvInstancePtr, IntPtr.Zero);
            }
            else
            {
                // convert to an unmanaged UTF8 IntPtr
                IntPtr fileNamePtr = UTF.StringToUtf8(filenameHint);

                retVal = NDIlib.recv_recording_start(_recvInstancePtr, IntPtr.Zero);

                // don't forget to free it
                Marshal.FreeHGlobal(fileNamePtr);
            }

            return(retVal);
        }
Exemplo n.º 3
0
        private void CreateRouting()
        {
            if (_routingInstancePtr != IntPtr.Zero)
            {
                NDIlib.routing_destroy(_routingInstancePtr);
                _routingInstancePtr = IntPtr.Zero;
            }

            // Sanity check
            if (_selectedSource == null || String.IsNullOrEmpty(_selectedSource.Name))
            {
                return;
            }

            // .Net interop doesn't handle UTF-8 strings, so do it manually
            // These must be freed later
            IntPtr sourceNamePtr = UTF.StringToUtf8(_routingName);

            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 routing description
            NDIlib.routing_create_t createDesc = new NDIlib.routing_create_t()
            {
                p_ndi_name = sourceNamePtr,
                p_groups   = groupsNamePtr
            };

            // create the NDI routing instance
            _routingInstancePtr = NDIlib.routing_create(ref createDesc);

            // free the strings we allocated
            Marshal.FreeHGlobal(sourceNamePtr);
            Marshal.FreeHGlobal(groupsNamePtr);

            // did it succeed?
            if (_routingInstancePtr == IntPtr.Zero)
            {
                throw new InvalidOperationException("Failed to create routing instance.");
            }

            // update in case we have enough info to start routing
            UpdateRouting();
        }
Exemplo n.º 4
0
        public Finder(bool showLocalSources = false, String[] groups = null, String[] extraIps = null)
        {
            if (!NDIlib.initialize())
            {
                if (!NDIlib.is_supported_CPU())
                {
                    throw new InvalidOperationException("CPU incompatible with NDI.");
                }
                else
                {
                    throw new InvalidOperationException("Unable to initialize NDI.");
                }
            }

            //BindingOperations.EnableCollectionSynchronization(_sourceList, _sourceLock);

            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());
            }

            // This is also optional.
            // The list of additional IP addresses that exist that we should query for
            // sources on. For instance, if you want to find the sources on a remote machine
            // that is not on your local sub-net then you can put a comma seperated list of
            // those IP addresses here and those sources will be available locally even though
            // they are not mDNS discoverable. An example might be "12.0.0.8,13.0.12.8".
            // When none is specified (IntPtr.Zero) the registry is used.
            // Create a UTF-8 buffer from our string
            // Must use Marshal.FreeHGlobal() after use!
            // IntPtr extraIpsPtr = NDI.Common.StringToUtf8("12.0.0.8,13.0.12.8")
            IntPtr extraIpsPtr = IntPtr.Zero;

            // make a flat list of ip addresses as comma separated strings
            if (extraIps != null)
            {
                StringBuilder flatIps = new StringBuilder();
                foreach (String ipStr in extraIps)
                {
                    flatIps.Append(ipStr);
                    if (ipStr != groups.Last())
                    {
                        flatIps.Append(',');
                    }
                }

                extraIpsPtr = UTF.StringToUtf8(flatIps.ToString());
            }

            // how we want our find to operate
            NDIlib.find_create_t findDesc = new NDIlib.find_create_t()
            {
                p_groups           = groupsNamePtr,
                show_local_sources = showLocalSources,
                p_extra_ips        = extraIpsPtr
            };

            // create our find instance
            _findInstancePtr = NDIlib.find_create_v2(ref findDesc);

            // free our UTF-8 buffer if we created one
            if (groupsNamePtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(groupsNamePtr);
            }

            if (extraIpsPtr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(extraIpsPtr);
            }

            // start up a thread to update on
            _findThread = new Thread(FindThreadProc)
            {
                IsBackground = true, Name = "NdiFindThread"
            };
            _findThread.Start();
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// connect to an NDI source in our Dictionary by name
        /// </summary>
        /// <param name="source"></param>
        /// <param name="colorFormat"></param>
        /// <param name="bandwidth"></param>
        /// <param name="allowVideoFields"></param>
        public void Connect(Source source,
                            NDIlib.recv_color_format_e colorFormat = NDIlib.recv_color_format_e.recv_color_format_BGRX_BGRA,
                            NDIlib.recv_bandwidth_e bandwidth      = NDIlib.recv_bandwidth_e.recv_bandwidth_highest,
                            bool allowVideoFields = false)
        {
            //if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            //    return;

            if (String.IsNullOrEmpty(ReceiverName))
            {
                throw new ArgumentException("sourceName can not be null or empty.", ReceiverName);
            }

            // 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 = colorFormat,

                // we want full quality - for small previews or limited bandwidth, choose lowest
                bandwidth = bandwidth,

                // let NDIlib deinterlace for us if needed
                allow_video_fields = allowVideoFields,

                // 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 = UTF.StringToUtf8(ReceiverName));

            // 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();
            }
        }