Exemple #1
0
        private CameraServer()
        {
            m_defaultUsbDevice = 0;
            m_lockObject       = new object();
            m_sources          = new Dictionary <string, VideoSource>();
            m_sinks            = new Dictionary <string, VideoSink>();
            m_tables           = new Dictionary <int, ITable>();
            m_publishTable     = NetworkTable.GetTable(PublishName);
            m_nextPort         = BasePort;
            m_addresses        = new List <string>();

            m_videoListener = new VideoListener((vidEvent) =>
            {
                switch (vidEvent.Kind)
                {
                case EventKind.SourceCreated:
                    {
                        // Create subtable for the camera
                        ITable table = m_publishTable.GetSubTable(vidEvent.Name);
                        lock (m_lockObject)
                        {
                            m_tables.Add(vidEvent.SourceHandle, table);
                        }
                        table.PutString("source", MakeSourceValue(vidEvent.SourceHandle));
                        table.PutString("description",
                                        NativeMethods.GetSourceDescription(vidEvent.SourceHandle));
                        table.PutBoolean("connected", NativeMethods.IsSourceConnected(vidEvent.SourceHandle));
                        table.PutStringArray("streams", GetSourceStreamValues(vidEvent.SourceHandle));
                        try
                        {
                            VideoMode mode = NativeMethods.GetSourceVideoMode(vidEvent.SourceHandle);
                            table.SetDefaultString("mode", VideoModeToString(mode));
                            table.PutStringArray("modes", GetSourceModeValues(vidEvent.SourceHandle));
                        }
                        catch (VideoException)
                        {
                            // Do nothing
                        }
                        break;
                    }

                case EventKind.SourceDestroyed:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            table.PutString("source", "");
                            table.PutStringArray("streams", new string[0]);
                            table.PutStringArray("modes", new string[0]);
                        }
                        break;
                    }

                case EventKind.SourceConnected:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            // update the description too (as it may have changed)
                            table.PutString("description",
                                            NativeMethods.GetSourceDescription(vidEvent.SourceHandle));
                            table.PutBoolean("connected", true);
                        }
                        break;
                    }

                case EventKind.SourceDisconnected:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        table?.PutBoolean("connected", false);
                        break;
                    }

                case EventKind.SourceVideoModesUpdated:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            table.PutStringArray("modes", GetSourceModeValues(vidEvent.SourceHandle));
                        }
                        break;
                    }

                case EventKind.SourceVideoModeChanged:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            table.PutString("mode", VideoModeToString(vidEvent.Mode));
                        }
                        break;
                    }

                case EventKind.SourcePropertyCreated:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            PutSourcePropertyValue(table, vidEvent, true);
                        }
                        break;
                    }

                case EventKind.SourcePropertyValueUpdated:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            PutSourcePropertyValue(table, vidEvent, false);
                        }
                        break;
                    }

                case EventKind.SourcePropertyChoicesUpdated:
                    {
                        ITable table = GetSourceTable(vidEvent.SourceHandle);
                        if (table != null)
                        {
                            List <string> choices = NativeMethods.GetEnumPropertyChoices(vidEvent.PropertyHandle);
                            table.PutStringArray($"PropertyInfo/{vidEvent.Name}/choices", choices);
                        }
                        break;
                    }

                case EventKind.SinkSourceChanged:
                case EventKind.SinkCreated:
                case EventKind.SinkDestroyed:
                    {
                        UpdateStreamValues();
                        break;
                    }

                case EventKind.NetworkInterfacesChanged:
                    {
                        m_addresses = NativeMethods.GetNetworkInterfaces();
                        break;
                    }

                default:
                    break;
                }
            }, (EventKind)0x4fff, true);

            m_tableListener = NtCore.AddEntryListener($"{PublishName}/", (uid, key, value, flags) =>
            {
                string relativeKey = key.Substring(PublishName.Length + 1);

                int subKeyIndex = relativeKey.IndexOf('/');
                if (subKeyIndex == -1)
                {
                    return;
                }
                string sourceName = relativeKey.Substring(0, subKeyIndex);
                VideoSource source;
                if (!m_sources.TryGetValue(sourceName, out source))
                {
                    return;
                }

                relativeKey = relativeKey.Substring(subKeyIndex + 1);

                string propName;
                if (relativeKey == "mode")
                {
                    // reset to current mode
                    NtCore.SetEntryString(key, VideoModeToString(source.GetVideoMode()));
                    return;
                }
                else if (relativeKey.StartsWith("Property/"))
                {
                    propName = relativeKey.Substring(9);
                }
                else if (relativeKey.StartsWith("RawProperty/"))
                {
                    propName = relativeKey.Substring(12);
                }
                else
                {
                    return;
                }

                VideoProperty prop = source.GetProperty(propName);
                switch (prop.Kind)
                {
                case PropertyKind.None:
                    return;

                case PropertyKind.Boolean:
                    NtCore.SetEntryBoolean(key, prop.Get() != 0);
                    break;

                case PropertyKind.Integer:
                case PropertyKind.Enum:
                    NtCore.SetEntryDouble(key, prop.Get());
                    break;

                case PropertyKind.String:
                    NtCore.SetEntryString(key, prop.GetString());
                    break;

                default:
                    return;
                }
            }, NotifyFlags.NotifyImmediate | NotifyFlags.NotifyUpdate);
        }