Files
Vocaluxe/Vocaluxe/Lib/Webcam/CAForgeNet.cs
T

203 lines
6.7 KiB
C#

#region license
// /*
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
// */
#endregion
using AForge.Video;
using AForge.Video.DirectShow;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using VocaluxeLib.Draw;
using VocaluxeLib.Menu;
namespace Vocaluxe.Lib.Webcam
{
class CAForgeNet : IWebcam
{
private readonly List<SWebcamDevice> _Devices = new List<SWebcamDevice>();
private bool _Paused;
private VideoCaptureDevice _Webcam;
private FilterInfoCollection _WebcamDevices;
private SWebcamConfig _Config;
private byte[] _Data = new byte[1];
private static readonly object _MutexData = new object();
private int _Width, _Height;
public void Close()
{
if (_Webcam != null)
{
_Webcam.SignalToStop();
_Webcam.WaitForStop();
_Webcam.NewFrame -= _OnFrame;
_Data = new byte[1];
}
}
public bool GetFrame(ref CTexture frame)
{
if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Width * _Height * 4)
{
lock (_MutexData)
{
if (frame.Index == -1 || _Width != frame.OrigSize.Width || _Height != frame.OrigSize.Height)
{
CDraw.RemoveTexture(ref frame);
frame = CDraw.AddTexture(_Width, _Height, _Data);
}
else
CDraw.UpdateTexture(ref frame, _Data);
}
}
return false;
}
public Bitmap GetBitmap()
{
if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Height * _Width * 4)
{
lock (_MutexData)
{
Bitmap bmp = new Bitmap(_Width, _Height);
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(_Data, 0, bitmapdata.Scan0, _Data.Length);
bmp.UnlockBits(bitmapdata);
return bmp;
}
}
return null;
}
public bool Init()
{
_WebcamDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo info in _WebcamDevices)
{
SWebcamDevice device = new SWebcamDevice
{
Name = info.Name,
MonikerString = info.MonikerString,
Capabilities = new List<SCapabilities>()
};
VideoCaptureDevice tmpdev = new VideoCaptureDevice(info.MonikerString);
foreach (VideoCapabilities capabilities in tmpdev.VideoCapabilities)
{
SCapabilities item = new SCapabilities
{
Framerate = capabilities.FrameRate,
Height = capabilities.FrameSize.Height,
Width = capabilities.FrameSize.Width
};
device.Capabilities.Add(item);
}
_Devices.Add(device);
}
return true;
}
private void _OnFrame(object sender, NewFrameEventArgs e)
{
if (!_Paused)
{
lock (_MutexData)
{
if (_Width != e.Frame.Width || _Height != e.Frame.Height || _Data.Length != e.Frame.Width * e.Frame.Height * 4)
_Data = new byte[4 * e.Frame.Width * e.Frame.Height];
_Width = e.Frame.Width;
_Height = e.Frame.Height;
BitmapData bitmapdata = e.Frame.LockBits(new Rectangle(0, 0, _Width, _Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bitmapdata.Scan0, _Data, 0, _Data.Length);
e.Frame.UnlockBits(bitmapdata);
}
}
}
public void Pause()
{
if (_Webcam != null)
_Paused = true;
}
public void Start()
{
if (_Webcam != null)
{
_Webcam.NewFrame -= _OnFrame;
//Subscribe to NewFrame event
_Webcam.NewFrame += _OnFrame;
_Webcam.Start();
_Paused = false;
}
}
public void Stop()
{
if (_Webcam != null)
_Webcam.SignalToStop();
}
public SWebcamDevice[] GetDevices()
{
return _Devices.ToArray();
}
public bool IsDeviceAvailable()
{
return _Devices.Count > 0;
}
public bool Select(SWebcamConfig config)
{
//Close old camera connection
Close();
if (_WebcamDevices == null)
return false;
if (_WebcamDevices.Count < 1)
return false;
//No MonikerString found, try first webcam
_Webcam = config.MonikerString == "" ? new VideoCaptureDevice(_WebcamDevices[0].MonikerString) : new VideoCaptureDevice(config.MonikerString);
if (_Webcam == null)
return false;
if (config.Framerate != 0 && config.Height != 0 && config.Width != 0)
{
_Webcam.DesiredFrameRate = config.Framerate;
_Webcam.DesiredFrameSize = new Size(config.Width, config.Height);
}
_Config.Framerate = _Webcam.DesiredFrameRate;
_Config.Height = _Webcam.DesiredFrameSize.Height;
_Config.Width = _Webcam.DesiredFrameSize.Width;
_Config.MonikerString = _Webcam.Source;
return true;
}
public SWebcamConfig GetConfig()
{
return _Config;
}
}
}