Files
Speykious 3371a2e745 Replace slow Marshal operations with unsafe (#13)
* Remove this bool marshal

* Literally remove all bool marshals

* Remove CharSet.Unicode warning

* Remove most FunctionPtr marshals

* Remove `[return: MarshalAs(...)]`

* Replace all `IntPtr`s with `void*`s

* Replace all `void*.Zero`s with `null`s

* Make native method classes unsafe

* U N S A F E

* Replace `PtrToStructure` with pointer arithmetic

* Run `dotnet format`

* Temp ugly Activator fix

* Remove `.ToPointer()`

* Use `byte` to return a `bool`

* Backwards compatibility with `Activator`

Yeah that sucks :(

* Replace `Marshal.Copy` by pointer arithmetic

* Replace `PtrToStringAnsi()` with `new string()`

* Remove unnecessary usings

* Explicitly type string pointers as `sbyte*`

* It actually doesn't hang?

* `MediaPipeException` -> `MediapipeException`

* Simplify `for` loops

* Remove unnecessary `float*` cast

* Some more explicit types for `ImageFrame`

* Remove unnecessary cast

* Looks like we forgor a `using` 💀

* Create `SafeArrayCopy` helper method

* Document `SafeArrayCopy`
2022-01-28 10:53:30 +01:00

97 lines
3.0 KiB
C#

// Copyright (c) homuler and Vignette
// This file is part of MediaPipe.NET.
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using CommandLine;
using Mediapipe.Net.Calculators;
using Mediapipe.Net.External;
using Mediapipe.Net.Framework.Format;
using Mediapipe.Net.Framework.Protobuf;
using SeeShark;
using SeeShark.FFmpeg;
namespace Mediapipe.Net.Examples.FaceMeshGpu
{
[SupportedOSPlatform("Linux")]
public static class Program
{
private static Camera? camera;
private static FrameConverter? converter;
private static FaceMeshGpuCalculator? calculator;
public static void Main(string[] args)
{
// Get and parse command line arguments
Options parsed = Parser.Default.ParseArguments<Options>(args).Value;
FFmpegManager.SetupFFmpeg("/usr/lib");
Glog.Initialize("stuff");
// Get a camera device
using (CameraManager manager = new CameraManager())
{
try
{
camera = manager.GetCamera(parsed.CameraIndex);
Console.WriteLine($"Using camera {camera.Info}");
}
catch (Exception)
{
Console.Error.WriteLine($"No camera exists at index {parsed.CameraIndex}.");
return;
}
}
camera.OnFrame += onFrame;
calculator = new FaceMeshGpuCalculator();
calculator.OnResult += handleLandmarks;
calculator.Run();
camera.StartCapture();
Console.CancelKeyPress += (sender, eventArgs) => exit();
Console.ReadLine();
}
private static void handleLandmarks(object? sender, List<NormalizedLandmarkList> landmarks)
{
Console.WriteLine($"Got a list of {landmarks[0].Landmark.Count} landmarks at frame {calculator?.CurrentFrame}");
}
private static unsafe void onFrame(object? sender, FrameEventArgs e)
{
if (calculator == null)
return;
var frame = e.Frame;
converter ??= new FrameConverter(frame, PixelFormat.Rgba);
// Don't use a frame if it's not new
if (e.Status != DecodeStatus.NewFrame)
return;
Frame cFrame = converter.Convert(frame);
ImageFrame imgframe;
fixed (byte* rawDataPtr = cFrame.RawData)
{
imgframe = new ImageFrame(ImageFormat.Srgba,
cFrame.Width, cFrame.Height, cFrame.WidthStep, rawDataPtr);
}
using ImageFrame img = calculator.Send(imgframe);
imgframe.Dispose();
}
// Dispose everything on exit
private static void exit()
{
Console.WriteLine("Exiting...");
camera?.Dispose();
converter?.Dispose();
calculator?.Dispose();
}
}
}