FFMpegCore/FFMpegCore/Extend/BitmapVideoFrameWrapper.cs

92 lines
2.8 KiB
C#
Raw Normal View History

2021-05-15 11:19:22 +02:00
using System;
2020-04-27 18:23:31 +02:00
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
2020-04-27 18:23:31 +02:00
using System.Runtime.InteropServices;
using System.Threading;
2020-04-27 18:23:31 +02:00
using System.Threading.Tasks;
2021-05-15 11:19:22 +02:00
using FFMpegCore.Pipes;
2020-04-27 18:23:31 +02:00
namespace FFMpegCore.Extend
{
public class BitmapVideoFrameWrapper : IVideoFrame, IDisposable
{
public int Width => Source.Width;
public int Height => Source.Height;
public string Format { get; private set; }
public Bitmap Source { get; private set; }
public BitmapVideoFrameWrapper(Bitmap bitmap)
{
Source = bitmap ?? throw new ArgumentNullException(nameof(bitmap));
Format = ConvertStreamFormat(bitmap.PixelFormat);
}
public void Serialize(Stream stream)
2020-04-27 18:23:31 +02:00
{
var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat);
try
{
var buffer = new byte[data.Stride * data.Height];
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
stream.Write(buffer, 0, buffer.Length);
2020-04-27 18:23:31 +02:00
}
finally
{
Source.UnlockBits(data);
}
}
public async Task SerializeAsync(Stream stream, CancellationToken token)
2020-04-27 18:23:31 +02:00
{
var data = Source.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, Source.PixelFormat);
try
{
var buffer = new byte[data.Stride * data.Height];
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
await stream.WriteAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false);
2020-04-27 18:23:31 +02:00
}
finally
{
Source.UnlockBits(data);
}
}
public void Dispose()
{
Source.Dispose();
}
private static string ConvertStreamFormat(PixelFormat fmt)
{
switch (fmt)
{
case PixelFormat.Format16bppGrayScale:
return "gray16le";
case PixelFormat.Format16bppRgb555:
return "bgr555le";
2020-04-27 18:23:31 +02:00
case PixelFormat.Format16bppRgb565:
return "bgr565le";
case PixelFormat.Format24bppRgb:
2020-05-12 17:26:52 +02:00
return "bgr24";
2020-04-27 18:23:31 +02:00
case PixelFormat.Format32bppArgb:
2020-05-12 17:26:52 +02:00
return "bgra";
2020-04-27 18:23:31 +02:00
case PixelFormat.Format32bppPArgb:
//This is not really same as argb32
return "argb";
case PixelFormat.Format32bppRgb:
return "rgba";
case PixelFormat.Format48bppRgb:
return "rgb48le";
default:
throw new NotSupportedException($"Not supported pixel format {fmt}");
}
}
}
}