private async Task StopOperationAsync() { Stopwatch.Stop(); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { CaptureElement.Source = null; }); FrameReader.FrameArrived -= FrameReader_FrameArrived; try { await MediaCapture.StopPreviewAsync(); } catch (Exception e) when(e.HResult == unchecked ((int)0xc00dabe4) && MediaCapture.PreviewMediaCapture.CameraStreamState != CameraStreamState.Streaming) { // StopPreview is not idempotent, silence exception when camera is not streaming } await FrameReader.StopAsync(); FrameCollection.Dispose(); CollectedColorFrames.AsParallel().ForAll(frame => frame.Dispose()); CollectedNonIlluminatedInfraredFrames.AsParallel().ForAll(frame => frame.Dispose()); CollectedIlluminatedInfraredFrames.AsParallel().ForAll(frame => frame.Dispose()); CollectedColorFrames.Clear(); CollectedNonIlluminatedInfraredFrames.Clear(); CollectedIlluminatedInfraredFrames.Clear(); await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, DispatcherTimer.Stop); }
private async void FrameCollection_CollectionProgressed(ExampleMediaFrameCollection sender, ExampleMediaFrameCollectionProgressedEventArgs args) { if (IsCollectionCompleted) { // Discard extraneous frames args.Frame.Dispose(); return; } if (args.Frame.SourceKind == MediaFrameSourceKind.Color) { CollectedColorFrames.Add(args.Frame); } else if (args.Frame.SourceKind == MediaFrameSourceKind.Infrared) { if (args.Frame.IsIlluminated == true) { CollectedIlluminatedInfraredFrames.Add(args.Frame); } else { CollectedNonIlluminatedInfraredFrames.Add(args.Frame); } } else { // Don't know how to handle, discard args.Frame.Dispose(); } if (IsCollectionCompleted) { FrameCollection.CollectionProgressed -= FrameCollection_CollectionProgressed; await WriteToDiskAsync(); await StopOperationAsync(); } }
private async Task WriteToDiskAsync() { var diskWriteInputPackages = CollectedColorFrames.Concat(CollectedIlluminatedInfraredFrames).Concat(CollectedNonIlluminatedInfraredFrames) .AsParallel().Select(async frame => { SoftwareBitmap compatibleBitmap = null; Action cleanupAction = () => { }; if (frame.SoftwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 || frame.SoftwareBitmap.BitmapAlphaMode != BitmapAlphaMode.Ignore) { compatibleBitmap = SoftwareBitmap.Convert(frame.SoftwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore); cleanupAction = () => compatibleBitmap.Dispose(); } else { compatibleBitmap = frame.SoftwareBitmap; } var fileName = ((ulong)frame.SystemRelativeTime?.Ticks).ToString("D10"); var encodingOptions = new BitmapPropertySet(); var encoderId = Guid.Empty; if (frame.SourceKind == MediaFrameSourceKind.Color) { fileName = "RGB-" + fileName + ".jpg"; encoderId = BitmapEncoder.JpegEncoderId; encodingOptions.Add("ImageQuality", new BitmapTypedValue( 1.0, // Maximum quality Windows.Foundation.PropertyType.Single)); } else if (frame.SourceKind == MediaFrameSourceKind.Infrared) { if (frame.IsIlluminated == true) { fileName = "IIR-" + fileName; // Illuminated IR } else { fileName = "AIR-" + fileName; // Ambient IR } fileName += ".png"; encoderId = BitmapEncoder.PngEncoderId; } var memoryStream = new InMemoryRandomAccessStream(); BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, memoryStream, encodingOptions); encoder.SetSoftwareBitmap(compatibleBitmap); await encoder.FlushAsync(); return(new { Stream = memoryStream.AsStream(), CleanupAction = cleanupAction, FileName = fileName }); }) .Select(task => task.ToObservable()).Merge().ObserveOn(NewThreadScheduler.Default).ToEnumerable(); // sequentialize awaitables var zipPath = Path.Combine(WorkingFolder.Path, "CollectedData.zip"); using (FileStream zipFileStream = new FileStream(zipPath, FileMode.Create)) { using (ZipArchive archive = new ZipArchive(zipFileStream, ZipArchiveMode.Create)) { foreach (var input in diskWriteInputPackages) { ZipArchiveEntry zipImgFileEntry = archive.CreateEntry(input.FileName, CompressionLevel.NoCompression); using (Stream zipEntryStream = zipImgFileEntry.Open()) { await input.Stream.CopyToAsync(zipEntryStream); } ++WrittenToDiskFramesCount; } ZipArchiveEntry zipMetadataFileEntry = archive.CreateEntry("info.json", CompressionLevel.NoCompression); using (Stream zipEntryStream = zipMetadataFileEntry.Open()) { MetadataWriter.WriteSerialization(zipEntryStream.AsOutputStream(), MediaCapture.Properties); } } } foreach (var input in diskWriteInputPackages) { input.CleanupAction(); input.Stream.Dispose(); } }