NativeRecorder.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /*
  2. * NatCorder
  3. * Copyright (c) 2020 Yusuf Olokoba.
  4. */
  5. namespace NatSuite.Recorders.Internal {
  6. using AOT;
  7. using System;
  8. using System.Runtime.InteropServices;
  9. using System.Threading.Tasks;
  10. public sealed class NativeRecorder : IMediaRecorder {
  11. #region --IMediaRecorder--
  12. public (int width, int height) frameSize {
  13. get {
  14. recorder.FrameSize(out var width, out var height);
  15. return (width, height);
  16. }
  17. }
  18. public NativeRecorder (Func<Bridge.RecordingHandler, IntPtr, IntPtr> recorderCreator) {
  19. this.recordingTask = new TaskCompletionSource<string>();
  20. var handle = GCHandle.Alloc(recordingTask, GCHandleType.Normal);
  21. this.recorder = recorderCreator(OnRecording, (IntPtr)handle);
  22. }
  23. public void CommitFrame<T> (T[] pixelBuffer, long timestamp) where T : struct {
  24. var handle = GCHandle.Alloc(pixelBuffer, GCHandleType.Pinned);
  25. CommitFrame(handle.AddrOfPinnedObject(), timestamp);
  26. handle.Free();
  27. }
  28. public void CommitFrame (IntPtr nativeBuffer, long timestamp) => recorder.CommitFrame(nativeBuffer, timestamp);
  29. public void CommitSamples (float[] sampleBuffer, long timestamp) => recorder.CommitSamples(sampleBuffer, sampleBuffer.Length, timestamp);
  30. public Task<string> FinishWriting () {
  31. recorder.FinishWriting();
  32. return recordingTask.Task;
  33. }
  34. #endregion
  35. #region --Operations--
  36. private readonly IntPtr recorder;
  37. private readonly TaskCompletionSource<string> recordingTask;
  38. [MonoPInvokeCallback(typeof(Bridge.RecordingHandler))]
  39. private static void OnRecording (IntPtr context, IntPtr path) {
  40. // Get task
  41. var handle = (GCHandle)context;
  42. var recordingTask = handle.Target as TaskCompletionSource<string>;
  43. handle.Free();
  44. // Invoke completion task
  45. if (path != IntPtr.Zero)
  46. recordingTask.SetResult(Marshal.PtrToStringAnsi(path));
  47. else
  48. recordingTask.SetException(new Exception(@"Recorder failed to finish writing"));
  49. }
  50. #endregion
  51. }
  52. }