コード例 #1
0
 /// <summary>
 /// IStartable called by the pipeline when KinectSensor is activated in the pipeline
 /// </summary>
 /// <param name="onCompleted">Unused</param>
 /// <param name="descriptor">Parameter Unused</param>
 void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     if (this.disposed)
     {
         throw new ObjectDisposedException(nameof(KinectFaceDetector));
     }
 }
コード例 #2
0
        public void Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            // start listening
            this.listener           = new SimpleSocketServer(this.localPort);
            this.listener.OnMessage = this.ProcessMessageFromUpstream; // push the data downstream
            this.listener.StartListening();

            // register with facilitator
            facilitator           = new SimpleSocket(this.facilitatorIp, facilitatorPort);
            facilitator.OnMessage = this.ProcessMessageFromUpstream;
            facilitator.Connect();

            var registermsg = $"(register :sender {this.name} :receiver facilitator :content (\"socket://127.0.0.1:{this.localPort}\" nil nil {this.localPort}))";

            facilitator.Send(registermsg);
            facilitator.Close();

            // advertise - skipped
            //string fn = "test";
            //string msgid = nextMsgId();
            //var admsg = $"(advertise :sender {this.name} :receiver facilitator :reply-with {msgid} " +
            //    $":content (ask-all :receiver {this.name} :in-reply-to {msgid} :content {fn}))";
            //facilitator.Connect();
            //facilitator.Send(admsg);
            //facilitator.Close();

            this.ready = true;
            Console.WriteLine("[SocketStringConsumer] ***Ready***\n");
        }
コード例 #3
0
ファイル: SimpleReader.cs プロジェクト: jayagupta678/psi
        /// <inheritdoc />
        public void ReadAll(ReplayDescriptor descriptor, CancellationToken cancelationToken = default(CancellationToken))
        {
            var      result = true;
            Envelope e;

            this.reader.Seek(descriptor.Interval, descriptor.UseOriginatingTime);
            while (result || this.reader.IsMoreDataExpected())
            {
                if (cancelationToken.IsCancellationRequested)
                {
                    return;
                }

                result = this.reader.MoveNext(out e);
                if (result)
                {
                    if (this.indexOutputs.ContainsKey(e.SourceId))
                    {
                        var indexEntry = this.reader.ReadIndex();
                        this.indexOutputs[e.SourceId](indexEntry, e);
                    }
                    else
                    {
                        int count        = this.reader.Read(ref this.buffer);
                        var bufferReader = new BufferReader(this.buffer, count);
                        this.outputs[e.SourceId](bufferReader, e);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Called once all the subscriptions are established.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the component finishes</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        public void Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            // start the speech recognition engine
            this.speechRecognitionEngine.RecognizeAsync(RecognizeMode.Multiple);

            // component is considered "completed" once started up
            onCompleted?.Invoke();
        }
コード例 #5
0
ファイル: Dataset.cs プロジェクト: annelo-msft/psi
 /// <summary>
 /// Asynchronously computes a derived partition for each session in the dataset.
 /// </summary>
 /// <param name="computeDerived">The action to be invoked to derive partitions.</param>
 /// <param name="outputPartitionName">The output partition name to be created.</param>
 /// <param name="overwrite">Flag indicating whether the partition should be overwritten.</param>
 /// <param name="outputStoreName">The name of the output data store.</param>
 /// <param name="outputPathFunction">A function to determine output path from the given Session.</param>
 /// <param name="replayDescriptor">The replay descriptor to us.</param>
 /// <param name="progress">An object that can be used for reporting progress.</param>
 /// <param name="cancellationToken">A token for canceling the asynchronous task.</param>
 /// <returns>A task that represents the asynchronous operation.</returns>
 public async Task CreateDerivedPartitionAsync(
     Action <Pipeline, SessionImporter, Exporter> computeDerived,
     string outputPartitionName,
     bool overwrite,
     string outputStoreName,
     Func <Session, string> outputPathFunction,
     ReplayDescriptor replayDescriptor     = null,
     IProgress <(string, double)> progress = null,
コード例 #6
0
        /// <summary>
        /// IStartable called by the pipeline when KinectSensor is activated in the pipeline
        /// </summary>
        /// <param name="onCompleted">Unused</param>
        /// <param name="descriptor">Parameter Unused</param>
        void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            //this.StartKinect();

            // Start streaming audio!
            this.audioStream = this.kinectSensor.AudioSource.Start();

            this.readingThread.Start();
        }
コード例 #7
0
 /// <summary>
 /// Starts playing back audio.
 /// </summary>
 /// <param name="onCompleted">Delegate to call when the execution completed</param>
 /// <param name="descriptor">If set, describes the playback constraints</param>
 public void Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     this.audioDevice = LinuxAudioInterop.Open(
         this.configuration.DeviceName,
         LinuxAudioInterop.Mode.Playback,
         (int)this.configuration.Format.SamplesPerSec,
         this.configuration.Format.Channels,
         LinuxAudioInterop.ConfigurationFormat(this.configuration));
 }
コード例 #8
0
        /// <inheritdoc />
        public void ReadAll(ReplayDescriptor descriptor, CancellationToken cancelationToken = default)
        {
            var      result = true;
            Envelope e;

            this.PsiStoreReader.Seek(descriptor.Interval, true);
            while (result || this.PsiStoreReader.IsMoreDataExpected())
            {
                if (cancelationToken.IsCancellationRequested)
                {
                    return;
                }

                result = this.PsiStoreReader.MoveNext(out e);
                if (result)
                {
                    if (this.indexOutputs.ContainsKey(e.SourceId))
                    {
                        var indexEntry = this.PsiStoreReader.ReadIndex();
                        this.indexOutputs[e.SourceId](indexEntry, e);
                    }
                    else if (this.outputs.ContainsKey(e.SourceId))
                    {
                        int count        = this.PsiStoreReader.Read(ref this.buffer);
                        var bufferReader = new BufferReader(this.buffer, count);

                        // Deserialize the data and call the listeners.  Note that due to polymorphic types, we
                        // may be attempting to create some handlers on the fly which may result in a serialization
                        // exception being thrown due to type mismatch errors.
                        try
                        {
                            this.outputs[e.SourceId](bufferReader, e);
                        }
                        catch (SerializationException ex)
                        {
                            // If any error occurred while processing the message and there are
                            // registered error handlers, stop attempting to process messages
                            // from the stream and notify all registered error handler listeners.
                            // otherwise, rethrow the exception to exit the application.
                            if (this.errorHandlers.ContainsKey(e.SourceId))
                            {
                                this.outputs.Remove(e.SourceId);
                                foreach (Action <SerializationException> errorAction in this.errorHandlers[e.SourceId])
                                {
                                    errorAction.Invoke(ex);
                                }
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }
                }
            }
        }
コード例 #9
0
ファイル: WaveFileStreamReader.cs プロジェクト: yusharth/psi
 /// <inheritdoc />
 public void ReadAll(ReplayDescriptor descriptor, CancellationToken cancelationToken = default)
 {
     this.Seek(descriptor.Interval);
     while (!cancelationToken.IsCancellationRequested && this.Next(out var audio, out var envelope))
     {
         if (descriptor.Interval.PointIsWithin(envelope.OriginatingTime))
         {
             this.InvokeTargets(audio, envelope);
         }
     }
 }
コード例 #10
0
        /// <summary>
        /// Called to start capturing audio from the microphone.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the execution completed</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        public void Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            this.audioDevice = LinuxAudioInterop.Open(
                this.configuration.DeviceName,
                LinuxAudioInterop.Mode.Capture,
                (int)this.configuration.Format.SamplesPerSec,
                this.configuration.Format.Channels,
                LinuxAudioInterop.ConfigurationFormat(this.configuration));

            new Thread(new ThreadStart(() =>
            {
                const int blockSize = 256;
                var format          = this.configuration.Format;
                var length          = blockSize * format.BitsPerSample / 8;
                var buf             = new byte[length];

                while (this.audioDevice != null)
                {
                    try
                    {
                        LinuxAudioInterop.Read(this.audioDevice, buf, blockSize);
                    }
                    catch (Exception ex)
                    {
                        if (this.audioDevice != null)
                        {
                            throw ex;
                        }
                    }

                    // Only create a new buffer if necessary
                    if ((this.buffer.Data == null) || (this.buffer.Length != length))
                    {
                        this.buffer = new AudioBuffer(length, format);
                    }

                    // Copy the data
                    Array.Copy(buf, this.buffer.Data, length);

                    // use the end of the last sample in the packet as the originating time
                    DateTime originatingTime = this.pipeline.GetCurrentTime().AddSeconds(length / format.AvgBytesPerSec);

                    // post the data to the output stream
                    this.audioBuffers.Post(this.buffer, originatingTime);
                }
            }))
            {
                IsBackground = true
            }.Start();
        }
コード例 #11
0
ファイル: PipelineElement.cs プロジェクト: kontogiorgos/psi
        /// <summary>
        /// Activates the entity.
        /// </summary>
        /// <param name="replayContext">If the pipeline is in replay mode, this is set and provides replay information</param>
        internal void Activate(ReplayDescriptor replayContext)
        {
            if (this.activationCount == 0)
            {
                // tell the component it's being activated
                if (this.IsStartable)
                {
                    // activate through the Scheduler to ensure exclusive execution of Start with respect to any receivers.
                    this.pipeline.Scheduler.Schedule(
                        this.syncContext,
                        () => ((IStartable)this.stateObject).Start(this.OnCompleted, replayContext),
                        replayContext.Start);
                }
            }

            this.activationCount++;
        }
コード例 #12
0
        /// <summary>
        /// Called to start capturing audio from the microphone.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the execution completed</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            // publish initial values at startup
            this.AudioLevel.Post(this.audioCaptureDevice.AudioLevel, this.pipeline.GetCurrentTime());

            // register the event handler which will post new captured samples on the output stream
            this.audioCaptureDevice.AudioDataAvailableEvent += this.HandleAudioDataAvailableEvent;

            // register the volume notification event handler
            this.audioCaptureDevice.AudioVolumeNotification += this.HandleAudioVolumeNotification;

            // tell the audio device to start capturing audio
            this.audioCaptureDevice.StartCapture(this.Configuration.TargetLatencyInMs, this.Configuration.Gain, this.Configuration.OutputFormat, this.Configuration.OptimizeForSpeech);

            // Get the actual capture format. This should normally match the configured output format,
            // unless that was null in which case the native device capture format is returned.
            this.sourceFormat = this.Configuration.OutputFormat ?? this.audioCaptureDevice.MixFormat;
        }
コード例 #13
0
ファイル: PersistenceTest.cs プロジェクト: jayagupta678/psi
        public void Seek()
        {
            var count    = 100; // to make sure there are more than one page
            var interval = 1;
            var name     = nameof(this.Seek);
            var factors  = new[] { 1f, 0.5f, 0.1f };
            var buffer   = new byte[1024];

            using (var p = Pipeline.Create("seek"))
            {
                var writeStore = Store.Create(p, name, this.path);
                var seq        = Generators.Sequence(p, 0, i => i + 1, count, TimeSpan.FromMilliseconds(interval));
                seq.Select(i => buffer).Write("unused", writeStore); // a second stream, written but unused, to increase the number of pages in the file
                seq.Write("seq", writeStore);
                p.Run();
            }

            // now replay the contents and verify we can seek
            TimeInterval range;

            using (var p2 = Pipeline.Create("read"))
            {
                var readStore = Store.Open(p2, name, this.path);
                range = readStore.OriginatingTimeInterval;
            }

            Assert.AreEqual((count - 1) * interval, range.Span.TotalMilliseconds);

            foreach (var factor in factors)
            {
                int recount = 0;
                var desc    = new ReplayDescriptor(range.ScaleLeft(factor), true);
                using (var p2 = Pipeline.Create("read"))
                {
                    var readStore = Store.Open(p2, name, this.path);

                    var seq2     = readStore.OpenStream <int>("seq");
                    var verifier = seq2.Do(s => recount++);
                    p2.Run(desc);
                }

                Assert.AreEqual(count * factor, recount);
            }
        }
コード例 #14
0
 /// <summary>
 /// Compute derived partion for each session in the dataset.
 /// </summary>
 /// <param name="dataset">The dataset over which to derive partitions.</param>
 /// <param name="computeDerived">The action to be invoked to derive partitions.</param>
 /// <param name="outputPartitionName">The output partition name to be created.</param>
 /// <param name="overwrite">Flag indicating whether the partition should be overwritten. Default is false.</param>
 /// <param name="outputStoreName">The name of the output data store. Default is null.</param>
 /// <param name="outputStorePath">The path of the output data store. Default is null.</param>
 /// <param name="replayDescriptor">The replay descriptor to us</param>
 /// <returns>A dataset with the newly derived partitions.</returns>
 public static Dataset CreateDerivedPartition(
     this Dataset dataset,
     Action <Pipeline, SessionImporter, Exporter> computeDerived,
     string outputPartitionName,
     bool overwrite                    = false,
     string outputStoreName            = null,
     string outputStorePath            = null,
     ReplayDescriptor replayDescriptor = null)
 {
     return(CreateDerivedPartition <long>(
                dataset,
                (p, si, e, l) => computeDerived(p, si, e),
                0,
                outputPartitionName,
                overwrite,
                outputStoreName,
                outputStorePath,
                replayDescriptor));
 }
コード例 #15
0
ファイル: Timer.cs プロジェクト: kontogiorgos/psi
        /// <summary>
        /// Called when the component is about to start running.
        /// </summary>
        /// <param name="onCompleted">Callback to invoke when done</param>
        /// <param name="replayContext">Describes the playback constraints</param>
        public void Start(Action onCompleted, ReplayDescriptor replayContext)
        {
            if (replayContext.Start == DateTime.MinValue)
            {
                this.startTime = this.pipeline.GetCurrentTime();
            }
            else
            {
                this.startTime = replayContext.Start;
            }

            this.endTime     = replayContext.End;
            this.onCompleted = onCompleted;
            this.currentTime = this.startTime;
            uint realTimeInterval = (uint)this.pipeline.ConvertToRealTime(this.timerInterval).TotalMilliseconds;

            this.timer   = Platform.Specific.TimerStart(realTimeInterval, this.timerDelegate);
            this.running = true;
        }
コード例 #16
0
        /// <summary>
        /// Activates the entity.
        /// </summary>
        /// <param name="replayContext">If the pipeline is in replay mode, this is set and provides replay information</param>
        internal void Start(ReplayDescriptor replayContext)
        {
            if (this.state != State.Initial)
            {
                throw new InvalidOperationException($"Start was called on component {this.Name}, which is has already started (state={this.state}).");
            }

            this.state = State.Active;

            // tell the component it's being activated
            if (this.IsSource)
            {
                // start through the Scheduler to ensure exclusive execution of Start with respect to any receivers.
                this.pipeline.Scheduler.Schedule(
                    this.syncContext,
                    TrackStateObjectOnContext(() => ((ISourceComponent)this.stateObject).Start(this.OnNotifyCompletionTime), this.stateObject, this.pipeline),
                    replayContext.Start);
            }
        }
コード例 #17
0
ファイル: Dataset.cs プロジェクト: annelo-msft/psi
 /// <summary>
 /// Asynchronously computes a derived partition for each session in the dataset.
 /// </summary>
 /// <param name="computeDerived">The action to be invoked to derive partitions.</param>
 /// <param name="outputPartitionName">The output partition name to be created.</param>
 /// <param name="overwrite">Flag indicating whether the partition should be overwritten. Default is false.</param>
 /// <param name="outputStoreName">The name of the output data store. Default is null.</param>
 /// <param name="outputStorePath">The path of the output data store. Default is null.</param>
 /// <param name="replayDescriptor">The replay descriptor to us.</param>
 /// <param name="cancellationToken">A token for canceling the asynchronous task.</param>
 /// <returns>A task that represents the asynchronous operation.</returns>
 public async Task CreateDerivedPartitionAsync(
     Action <Pipeline, SessionImporter, Exporter> computeDerived,
     string outputPartitionName,
     bool overwrite                      = false,
     string outputStoreName              = null,
     string outputStorePath              = null,
     ReplayDescriptor replayDescriptor   = null,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     await this.CreateDerivedPartitionAsync <long>(
         (p, si, e, l) => computeDerived(p, si, e),
         0,
         outputPartitionName,
         overwrite,
         outputStoreName,
         outputStorePath,
         replayDescriptor,
         cancellationToken);
 }
コード例 #18
0
ファイル: JsonStoreReader.cs プロジェクト: maria-chang/psi
        /// <summary>
        /// Seek to envelope in stream according to specified replay descriptor.
        /// </summary>
        /// <param name="descriptor">The replay descriptor.</param>
        public void Seek(ReplayDescriptor descriptor)
        {
            this.descriptor = descriptor;

            // load data
            string dataPath = System.IO.Path.Combine(this.Path, StoreCommon.GetDataFileName(this.Name) + this.Extension);

            this.streamReader?.Dispose();
            this.streamReader     = File.OpenText(dataPath);
            this.jsonReader       = new JsonTextReader(this.streamReader);
            this.validatingReader = new JSchemaValidatingReader(this.jsonReader)
            {
                Schema = this.DataSchema
            };
            this.validatingReader.ValidationEventHandler += (s, e) => throw new InvalidDataException(e.Message);

            // iterate through data store until we either reach the end or we find the start of the replay descriptor
            while (this.validatingReader.Read())
            {
                // data stores are arrays of messages, messages start as objects
                if (this.validatingReader.TokenType == JsonToken.StartObject)
                {
                    // read envelope
                    if (!this.validatingReader.Read() || !this.ReadEnvelope(out this.envelope))
                    {
                        throw new InvalidDataException("Messages must be an ordered object: {\"Envelope\": <Envelope>, \"Data\": <Data>}. Deserialization needs to read the envelope before the data to know what type of data to deserialize.");
                    }

                    if (this.descriptor.Interval.Left < (descriptor.UseOriginatingTime ? this.envelope.OriginatingTime : this.envelope.Time))
                    {
                        // found start of interval
                        break;
                    }

                    // skip data
                    if (!this.ReadData(out this.data))
                    {
                        throw new InvalidDataException("Messages must be an ordered object: {\"Envelope\": <Envelope>, \"Data\": <Data>}. Deserialization needs to read the envelope before the data to know what type of data to deserialize.");
                    }
                }
            }
        }
コード例 #19
0
ファイル: JsonStreamReader.cs プロジェクト: yusharth/psi
        /// <inheritdoc />
        public void ReadAll(ReplayDescriptor descriptor, CancellationToken cancelationToken = default)
        {
            bool hasMoreData = true;

            this.Reader.Seek(descriptor);
            while (hasMoreData)
            {
                if (cancelationToken.IsCancellationRequested)
                {
                    return;
                }

                hasMoreData = this.Reader.MoveNext(out Envelope envelope);
                if (hasMoreData)
                {
                    hasMoreData = this.Reader.Read(out JToken token);
                    this.outputs[envelope.SourceId](token, envelope);
                }
            }
        }
コード例 #20
0
ファイル: PipelineElement.cs プロジェクト: maria-chang/psi
        /// <summary>
        /// Activates the entity.
        /// </summary>
        /// <param name="replayContext">If the pipeline is in replay mode, this is set and provides replay information</param>
        internal void Start(ReplayDescriptor replayContext)
        {
            if (this.activationCount == 0)
            {
                if (this.isFiniteSource)
                {
                    ((IFiniteSourceComponent)this.stateObject).Initialize(this.OnCompleted);
                }

                // tell the component it's being activated
                if (this.OnStartHandler != null)
                {
                    // start through the Scheduler to ensure exclusive execution of Start with respect to any receivers.
                    this.pipeline.Scheduler.Schedule(
                        this.syncContext,
                        this.OnStartHandler,
                        replayContext.Start);
                }
            }

            this.activationCount++;
        }
コード例 #21
0
        /// <summary>
        /// Starts playing back audio.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the execution completed</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        public void Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            // If playing back at greater than original speed (ReplaySpeedFactor < 1),
            // overwrite queued audio since data buffers will be arriving faster than
            // it can be rendered.
            this.overwrite = descriptor.ReplaySpeedFactor < 1;

            // publish initial volume level at startup
            this.AudioLevel.Post(this.audioRenderDevice.AudioLevel, this.pipeline.GetCurrentTime());

            // register the volume changed notification event handler
            this.audioRenderDevice.AudioVolumeNotification += this.HandleVolumeChangedNotification;

            // start the audio renderer
            this.audioRenderDevice.StartRendering(
                this.configuration.BufferLengthSeconds,
                this.configuration.TargetLatencyInMs,
                this.configuration.Gain,
                this.configuration.InputFormat);

            // signal completion of startup
            onCompleted?.Invoke();
        }
コード例 #22
0
ファイル: PipelineElement.cs プロジェクト: areilly711/psi
        /// <summary>
        /// Activates the entity.
        /// </summary>
        /// <param name="replayContext">If the pipeline is in replay mode, this is set and provides replay information</param>
        internal void Start(ReplayDescriptor replayContext)
        {
            if (this.state != State.Initial)
            {
                throw new InvalidOperationException($"Start was called on component {this.Name}, which is has already started (state={this.state}).");
            }

            this.state = State.Active;

            if (this.isFiniteSource)
            {
                ((IFiniteSourceComponent)this.stateObject).Initialize(this.OnCompleted);
            }

            // tell the component it's being activated
            if (this.OnStartHandler != null)
            {
                // start through the Scheduler to ensure exclusive execution of Start with respect to any receivers.
                this.pipeline.Scheduler.Schedule(
                    this.syncContext,
                    this.OnStartHandler,
                    replayContext.Start);
            }
        }
コード例 #23
0
ファイル: FaceRecognizer.cs プロジェクト: kontogiorgos/psi
 /// <inheritdoc/>
 void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     onCompleted?.Invoke();
 }
コード例 #24
0
ファイル: Importer.cs プロジェクト: kontogiorgos/psi
 /// <inheritdoc />
 void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     this.onCompleted = onCompleted;
     this.reader.Seek(descriptor.Interval, descriptor.UseOriginatingTime);
     this.next.Post(true, descriptor.Start);
 }
コード例 #25
0
 public void Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     this.onCompleted = onCompleted;
     this.turtle.Connect();
     this.turtle.PoseChanged += this.OnPoseChanged;
 }
コード例 #26
0
ファイル: Generator.cs プロジェクト: kontogiorgos/psi
 /// <inheritdoc />
 void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     this.onCompleted = onCompleted;
     this.Next(0, default(Envelope));
 }
コード例 #27
0
 public void Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     this.arm.Connect();
     this.arm.PositionChanged += this.OnPositionChanged;
 }
コード例 #28
0
ファイル: Mpeg4Writer.cs プロジェクト: kontogiorgos/psi
 /// <summary>
 /// Called once all the subscriptions are established.
 /// </summary>
 /// <param name="onCompleted">Delegate to call when the execution completed</param>
 /// <param name="descriptor">If set, describes the playback constraints</param>
 void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
 {
     MP4Writer.Startup();
     this.writer = new MP4Writer();
     this.writer.Open(this.filename, this.configuration.Config);
 }
コード例 #29
0
        /// <summary>
        /// Called once all the subscriptions are established.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the execution completed</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        unsafe void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            this.camera = new MediaCaptureInternal(this.configuration.DeviceId);
            this.camera.Open();
            var isFormatSupported = false;

            foreach (var format in this.camera.SupportedPixelFormats())
            {
                if (format.Pixels == this.configuration.PixelFormat)
                {
                    this.camera.SetVideoFormat(this.configuration.Width, this.configuration.Height, format);
                    isFormatSupported = true;
                }
            }

            if (!isFormatSupported)
            {
                throw new ArgumentException($"Pixel format {this.configuration.PixelFormat} is not supported by the camera");
            }

            var current = this.camera.GetVideoFormat();

            if (current.Width != this.configuration.Width || current.Height != this.configuration.Height)
            {
                throw new ArgumentException($"Width/height {this.configuration.Width}x{this.configuration.Height} is not supported by the camera");
            }

            this.camera.OnFrame += (_, frame) =>
            {
                var originatingTime = this.pipeline.GetCurrentTime();

                if (this.Raw.HasSubscribers)
                {
                    var len = frame.Length;
                    using (Shared <byte[]> shared = RawPool.GetOrCreate(() => new byte[len]))
                    {
                        var buffer = shared.Resource.Length >= len ? shared : new Shared <byte[]>(new byte[len], shared.Recycler);
                        Marshal.Copy(frame.Start, buffer.Resource, 0, len);
                        this.Raw.Post(buffer, originatingTime);
                    }
                }

                if (this.Out.HasSubscribers)
                {
                    using (var sharedImage = ImagePool.GetOrCreate(this.configuration.Width, this.configuration.Height, PixelFormat.BGR_24bpp))
                    {
                        if (this.configuration.PixelFormat == PixelFormatId.BGR24)
                        {
                            sharedImage.Resource.CopyFrom((IntPtr)frame.Start);
                            this.Out.Post(sharedImage, this.pipeline.GetCurrentTime());
                        }
                        else if (this.configuration.PixelFormat == PixelFormatId.YUYV)
                        {
                            // convert YUYV -> BGR24 (see https://msdn.microsoft.com/en-us/library/ms893078.aspx)
                            var len = (int)(frame.Length * 1.5);
                            using (Shared <byte[]> shared = RawPool.GetOrCreate(() => new byte[len]))
                            {
                                var buffer = shared.Resource.Length >= len ? shared : new Shared <byte[]>(new byte[len], shared.Recycler);
                                var bytes  = buffer.Resource;
                                var pY     = (byte *)frame.Start.ToPointer();
                                var pU     = pY + 1;
                                var pV     = pY + 2;
                                for (var i = 0; i < len;)
                                {
                                    var y = (*pY - 16) * 298;
                                    var u = *pU - 128;
                                    var v = *pV - 128;
                                    var b = (y + (516 * u) + 128) >> 8;
                                    var g = (y - (100 * u) - (208 * v) + 128) >> 8;
                                    var r = (y + (409 * v) + 128) >> 8;
                                    bytes[i++] = (byte)(b < 0 ? 0 : b > 255 ? 255 : b);
                                    bytes[i++] = (byte)(g < 0 ? 0 : g > 255 ? 255 : g);
                                    bytes[i++] = (byte)(r < 0 ? 0 : r > 255 ? 255 : r);
                                    pY        += 2;
                                    pU        += 4;
                                    pV        += 4;
                                }

                                this.Raw.Post(buffer, originatingTime);
                            }
                        }
                    }
                }

#if TEST_DROPPED_FRAMES
                System.Threading.Thread.Sleep(1000); // for testing dropped frames
#endif // TEST_DROPPED_FRAMES

                frame.Dispose(); // release back to driver!
            };

            this.camera.StreamBuffers();
        }
コード例 #30
0
ファイル: MediaCapture.cs プロジェクト: kontogiorgos/psi
        /// <summary>
        /// Called once all the subscriptions are established.
        /// </summary>
        /// <param name="onCompleted">Delegate to call when the execution completed</param>
        /// <param name="descriptor">If set, describes the playback constraints</param>
        void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor)
        {
            MediaCaptureDevice.Initialize();
            CaptureFormat found = null;

            foreach (var device in MediaCaptureDevice.AllDevices)
            {
                if (!device.Attach(this.configuration.UseInSharedMode))
                {
                    continue;
                }

                Trace.WriteLine($"MediaCapture - Searching for width={this.configuration.Width} height={this.configuration.Height} deviceId={this.configuration.DeviceId}");
                Trace.WriteLine($"MediaCapture - Found: Name: '{device.FriendlyName}' SymLink: {device.SymbolicLink}");
                Trace.WriteLine($"MediaCapture -   Current   - Width: {device.CurrentFormat.nWidth} Height: {device.CurrentFormat.nHeight} Type: {device.CurrentFormat.subType.Name}/{device.CurrentFormat.subType.Guid} Framerate: {device.CurrentFormat.nFrameRateNumerator}/{device.CurrentFormat.nFrameRateDenominator}");

                if (string.IsNullOrEmpty(this.configuration.DeviceId) || device.FriendlyName == this.configuration.DeviceId || device.SymbolicLink == this.configuration.DeviceId)
                {
                    foreach (var format in device.Formats)
                    {
                        Trace.WriteLine($"MediaCapture -   Supported - Width: {format.nWidth} Height: {format.nHeight} Type: {format.subType.Name}/{format.subType.Guid} Framerate: {format.nFrameRateNumerator}/{format.nFrameRateDenominator}");
                        if (this.configuration.Width == format.nWidth && this.configuration.Height == format.nHeight)
                        {
                            // found suitable width/height
                            if (this.configuration.Framerate == format.nFrameRateNumerator / format.nFrameRateDenominator)
                            {
                                // found suitable framerate
                                if (found == null || this.configuration.Framerate == found.nFrameRateNumerator / found.nFrameRateDenominator)
                                {
                                    // found first suitable or closer framerate match
                                    this.camera = device;
                                    found       = format;
                                }
                            }
                        }
                    }
                }

                if (found != null)
                {
                    Trace.WriteLine($"MediaCapture - Using - Width: {found.nWidth} Height: {found.nHeight} Type: {found.subType.Name}/{found.subType.Guid} Framerate: {found.nFrameRateNumerator}/{found.nFrameRateDenominator}");
                    break;
                }
            }

            if (found != null)
            {
                this.camera.CurrentFormat = found;
                this.deviceInfo           = new MediaCaptureInfo(this.camera);
                var width  = this.camera.CurrentFormat.nWidth;
                var height = this.camera.CurrentFormat.nHeight;

                // Get default settings for other properties.
                var currentConfig = this.GetDeviceConfiguration();
                this.configuration.BacklightCompensation = currentConfig.BacklightCompensation;
                this.configuration.Brightness            = currentConfig.Brightness;
                this.configuration.ColorEnable           = currentConfig.ColorEnable;
                this.configuration.Contrast     = currentConfig.Contrast;
                this.configuration.Gain         = currentConfig.Gain;
                this.configuration.Gamma        = currentConfig.Gamma;
                this.configuration.Hue          = currentConfig.Hue;
                this.configuration.Saturation   = currentConfig.Saturation;
                this.configuration.Sharpness    = currentConfig.Sharpness;
                this.configuration.WhiteBalance = currentConfig.WhiteBalance;
                this.configuration.Focus        = currentConfig.Focus;

                this.SetDeviceConfiguration(this.configuration);

                this.camera.CaptureSample((data, length, timestamp) =>
                {
                    var time = DateTime.FromFileTimeUtc(timestamp);
                    using (var sharedImage = ImagePool.GetOrCreate(this.configuration.Width, this.configuration.Height, Microsoft.Psi.Imaging.PixelFormat.BGR_24bpp))
                    {
                        sharedImage.Resource.CopyFrom(data);

                        var originatingTime = this.pipeline.GetCurrentTimeFromElapsedTicks(timestamp);
                        this.Out.Post(sharedImage, originatingTime);
                    }
                });
            }
            else
            {
                throw new ArgumentException("Camera specification not found");
            }
        }