/// <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)); } }
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"); }
/// <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); } } } }
/// <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(); }
/// <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,
/// <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(); }
/// <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)); }
/// <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; } } } } } }
/// <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); } } }
/// <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(); }
/// <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++; }
/// <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; }
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); } }
/// <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)); }
/// <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; }
/// <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); } }
/// <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); }
/// <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."); } } } }
/// <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); } } }
/// <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++; }
/// <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(); }
/// <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); } }
/// <inheritdoc/> void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor) { onCompleted?.Invoke(); }
/// <inheritdoc /> void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor) { this.onCompleted = onCompleted; this.reader.Seek(descriptor.Interval, descriptor.UseOriginatingTime); this.next.Post(true, descriptor.Start); }
public void Start(Action onCompleted, ReplayDescriptor descriptor) { this.onCompleted = onCompleted; this.turtle.Connect(); this.turtle.PoseChanged += this.OnPoseChanged; }
/// <inheritdoc /> void IStartable.Start(Action onCompleted, ReplayDescriptor descriptor) { this.onCompleted = onCompleted; this.Next(0, default(Envelope)); }
public void Start(Action onCompleted, ReplayDescriptor descriptor) { this.arm.Connect(); this.arm.PositionChanged += this.OnPositionChanged; }
/// <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); }
/// <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(); }
/// <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"); } }