Make webcam handling more stable (fix possible NPE)

This commit is contained in:
Flamefire committed 2014-04-30 22:35:31 +02:00
1 parent c31050926d
commit 63c681a057
6 files changed
+293 -175

No files matched your search

+28 -16
View File
@@ -49,58 +49,70 @@ namespace Vocaluxe.Base
return true; return true;
} }
public static void Close()
{
if (_Webcam == null)
return;
_Webcam.Close();
_Webcam = null;
}
public static bool GetFrame(ref CTexture tex) public static bool GetFrame(ref CTexture tex)
{ {
return _Webcam.GetFrame(ref tex); return _Webcam != null && _Webcam.GetFrame(ref tex);
} }
public static Bitmap GetBitmap() public static Bitmap GetBitmap()
{ {
return _Webcam.GetBitmap(); return _Webcam == null ? null : _Webcam.GetBitmap();
}
public static void Close()
{
if (_Webcam != null)
{
_Webcam.Close();
_Webcam = null;
}
} }
public static void Pause() public static void Pause()
{ {
if (_Webcam == null)
return;
_Webcam.Pause(); _Webcam.Pause();
} }
public static void Start() public static void Start()
{ {
if (_Webcam == null)
return;
_Webcam.Start(); _Webcam.Start();
} }
public static void Stop() public static void Stop()
{ {
if (_Webcam == null)
return;
_Webcam.Stop(); _Webcam.Stop();
} }
public static void Select(SWebcamConfig c) public static bool Select(SWebcamConfig c)
{ {
_Webcam.Select(c); return _Webcam != null && _Webcam.Select(c);
}
public static void DeSelect()
{
if (_Webcam == null)
return;
_Webcam.DeSelect();
} }
public static SWebcamDevice[] GetDevices() public static SWebcamDevice[] GetDevices()
{ {
return _Webcam.GetDevices(); return _Webcam == null ? null : _Webcam.GetDevices();
} }
public static bool IsDeviceAvailable() public static bool IsDeviceAvailable()
{ {
return _Webcam.IsDeviceAvailable(); return (_Webcam != null) && _Webcam.IsDeviceAvailable();
} }
public static bool IsCapturing() public static bool IsCapturing()
{ {
return _Webcam.IsCapturing(); return (_Webcam != null) && _Webcam.IsCapturing();
} }
} }
} }
+174 -92
View File
@@ -15,6 +15,7 @@
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>. // along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion #endregion
using System;
using AForge.Video; using AForge.Video;
using AForge.Video.DirectShow; using AForge.Video.DirectShow;
using System.Collections.Generic; using System.Collections.Generic;
@@ -31,60 +32,27 @@ namespace Vocaluxe.Lib.Webcam
private readonly List<SWebcamDevice> _Devices = new List<SWebcamDevice>(); private readonly List<SWebcamDevice> _Devices = new List<SWebcamDevice>();
private bool _Paused; private bool _Paused;
private VideoCaptureDevice _Webcam; private VideoCaptureDevice _Webcam;
private FilterInfoCollection _WebcamDevices;
private SWebcamConfig _Config; private SWebcamConfig _Config;
private byte[] _Data = new byte[1]; private byte[] _Data;
private static readonly object _MutexData = new object(); private static readonly object _MutexData = new object();
private int _Width, _Height; private int _Width, _Height;
private bool _NewFrameAvailable;
public void Close() private bool _IsCapturing;
{
if (_Webcam == null)
return;
_Webcam.SignalToStop();
_Webcam.WaitForStop();
_Webcam.NewFrame -= _OnFrame;
_Data = new byte[1];
}
public bool GetFrame(ref CTexture frame)
{
lock (_MutexData)
{
if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Width * _Height * 4)
CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _Data);
}
return false;
}
public Bitmap GetBitmap()
{
if (_Webcam != null && _Width > 0 && _Height > 0 && _Data.Length == _Height * _Width * 4)
{
lock (_MutexData)
{
var 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() public bool Init()
{ {
_WebcamDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); FilterInfoCollection webcams = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo info in _WebcamDevices) foreach (FilterInfo info in webcams)
{ {
var tmpdev = new VideoCaptureDevice(info.MonikerString);
if (tmpdev.VideoCapabilities.Length == 0)
continue;
var device = new SWebcamDevice var device = new SWebcamDevice
{ {
Name = info.Name, Name = info.Name,
MonikerString = info.MonikerString, MonikerString = info.MonikerString,
Capabilities = new List<SCapabilities>() Capabilities = new List<SCapabilities>(tmpdev.VideoCapabilities.Length)
}; };
var tmpdev = new VideoCaptureDevice(info.MonikerString);
foreach (VideoCapabilities capabilities in tmpdev.VideoCapabilities) foreach (VideoCapabilities capabilities in tmpdev.VideoCapabilities)
{ {
@@ -101,44 +69,188 @@ namespace Vocaluxe.Lib.Webcam
return true; return true;
} }
private void _OnFrame(object sender, NewFrameEventArgs e) public void Close()
{ {
if (_Paused) DeSelect();
_Devices.Clear();
}
public void DeSelect()
{
if (_Webcam == null)
return; return;
_Webcam.Stop();
_Webcam.NewFrame -= _OnFrame;
_IsCapturing = false;
lock (_MutexData) lock (_MutexData)
{ {
if (_Width != e.Frame.Width || _Height != e.Frame.Height || _Data.Length != e.Frame.Width * e.Frame.Height * 4) _Data = null;
_Data = new byte[4 * e.Frame.Width * e.Frame.Height]; _Webcam = null;
_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() #region ConfigSelection
private static float _GetScore(int value, int valueRequested)
{ {
if (_Webcam != null) if (valueRequested <= 0)
_Paused = true; return 1;
return 1.0f - (float)Math.Abs(value - valueRequested) / Math.Max(value, valueRequested);
}
private static VideoCapabilities _SelectWebcamConfig(VideoCapabilities[] capabilities, SWebcamConfig config)
{
int configTaken = 0;
if (config.Framerate != 0 && config.Height != 0 && config.Width != 0)
{
float bestMatchScore = 0;
for (int i = 0; i < capabilities.Length; i++)
{
float score = _GetScore(capabilities[i].AverageFrameRate, config.Framerate);
score += _GetScore(capabilities[i].FrameSize.Height, config.Height);
score += _GetScore(capabilities[i].FrameSize.Width, config.Width);
if (score >= bestMatchScore)
{
// Take the config with the best score, Higher indizes should indicate a better resolution
// so choose the last one with best score if 2 have equal scores
bestMatchScore = score;
configTaken = i;
}
}
}
return capabilities[configTaken];
}
#endregion
public bool Select(SWebcamConfig config)
{
//Close old camera connection
DeSelect();
if (_Devices.Count < 1)
return false;
string moniker = _Devices[0].MonikerString;
if (config.MonikerString != "")
{
foreach (SWebcamDevice device in _Devices)
{
if (device.MonikerString == config.MonikerString)
{
moniker = device.MonikerString;
break;
}
}
}
_Webcam = new VideoCaptureDevice(moniker);
_Webcam.VideoResolution = _SelectWebcamConfig(_Webcam.VideoCapabilities, config);
_Config.Framerate = _Webcam.VideoResolution.AverageFrameRate;
_Config.Height = _Webcam.VideoResolution.FrameSize.Height;
_Config.Width = _Webcam.VideoResolution.FrameSize.Width;
_Config.MonikerString = _Webcam.Source;
return true;
} }
public void Start() public void Start()
{ {
if (_Webcam == null) if (_Webcam == null)
return; return;
_Webcam.NewFrame -= _OnFrame; if (_IsCapturing)
//Subscribe to NewFrame event {
_Webcam.NewFrame += _OnFrame; if (_Paused)
_Webcam.Start(); {
_Paused = false; _Webcam.NewFrame += _OnFrame;
_Paused = false;
}
}
else
{
//Subscribe to NewFrame event
_Webcam.NewFrame += _OnFrame;
_Paused = false;
_Webcam.Start();
_IsCapturing = true;
}
}
public void Pause()
{
if (_Webcam != null && !_Paused)
{
_Webcam.NewFrame -= _OnFrame;
lock (_MutexData) //Make sure all events are finished or not yet startet for consistency
{
_Paused = true;
}
}
} }
public void Stop() public void Stop()
{ {
if (_Webcam != null) if (_Webcam != null)
{
_Webcam.SignalToStop(); _Webcam.SignalToStop();
_Webcam.NewFrame -= _OnFrame;
lock (_MutexData) //Make sure all events are finished or not yet startet for consistency
{
_IsCapturing = false;
}
}
}
public bool GetFrame(ref CTexture frame)
{
lock (_MutexData)
{
if (_Data != null && _Data.Length == _Width * _Height * 4 && _NewFrameAvailable)
{
CDraw.UpdateOrAddTexture(ref frame, _Width, _Height, _Data);
_NewFrameAvailable = false;
return true;
}
return false;
}
}
public Bitmap GetBitmap()
{
lock (_MutexData)
{
if (_Data != null && _Data.Length == _Width * _Height * 4)
{
var 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;
}
}
private void _OnFrame(object sender, NewFrameEventArgs e)
{
if (_Paused)
return;
if (e.Frame.Width == 0 || e.Frame.Height == 0)
return;
lock (_MutexData)
{
if (!IsCapturing())
return;
if (_Data == null || _Data.Length != e.Frame.Width * e.Frame.Height * 4)
_Data = new byte[e.Frame.Width * e.Frame.Height * 4];
_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);
_NewFrameAvailable = true;
}
} }
public SWebcamDevice[] GetDevices() public SWebcamDevice[] GetDevices()
@@ -148,42 +260,12 @@ namespace Vocaluxe.Lib.Webcam
public bool IsDeviceAvailable() public bool IsDeviceAvailable()
{ {
return _Devices.Count > 0; return _Webcam != null;
} }
public bool IsCapturing() public bool IsCapturing()
{ {
return _Webcam.IsRunning; return _IsCapturing && !_Paused;
}
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.SnapshotResolution.AverageFrameRate;
_Config.Height = _Webcam.SnapshotResolution.FrameSize.Height;
_Config.Width = _Webcam.SnapshotResolution.FrameSize.Width;
_Config.MonikerString = _Webcam.Source;
return true;
} }
public SWebcamConfig GetConfig() public SWebcamConfig GetConfig()
+15 -1
View File
@@ -46,19 +46,33 @@ namespace Vocaluxe.Lib.Webcam
interface IWebcam interface IWebcam
{ {
bool Init(); bool Init();
void Close();
void Start(); void Start();
void Pause(); void Pause();
void Stop(); void Stop();
void Close();
/// <summary>
/// Gets last captured frame. Returns true if frame was updated<br />
/// Note that this will invalidate the last frame and not return it again with this function
/// </summary>
/// <param name="frame"></param>
/// <returns></returns>
bool GetFrame(ref CTexture frame); bool GetFrame(ref CTexture frame);
/// <summary>
/// Gets the last captured frame as a bitma
/// </summary>
/// <param name="frame"></param>
/// <returns>Null if no frame was captured, the bitmap otherwise</returns>
Bitmap GetBitmap(); Bitmap GetBitmap();
SWebcamConfig GetConfig(); SWebcamConfig GetConfig();
SWebcamDevice[] GetDevices(); SWebcamDevice[] GetDevices();
bool IsDeviceAvailable(); bool IsDeviceAvailable();
bool IsCapturing(); bool IsCapturing();
bool Select(SWebcamConfig webcamConfig); bool Select(SWebcamConfig webcamConfig);
void DeSelect();
} }
} }
+30 -38
View File
@@ -154,8 +154,8 @@ namespace Vocaluxe.Screens
public override bool UpdateGame() public override bool UpdateGame()
{ {
CWebcam.GetFrame(ref _WebcamTexture); if (CWebcam.GetFrame(ref _WebcamTexture))
_Statics[_StaticWebcamOutput].Texture = _WebcamTexture; _Statics[_StaticWebcamOutput].Texture = _WebcamTexture;
_SelectSlides[_SelectSlideVideosToBackground].Selection = (int)CConfig.VideosToBackground; _SelectSlides[_SelectSlideVideosToBackground].Selection = (int)CConfig.VideosToBackground;
return true; return true;
} }
@@ -170,7 +170,7 @@ namespace Vocaluxe.Screens
public override void OnClose() public override void OnClose()
{ {
base.OnClose(); base.OnClose();
CWebcam.Close(); CWebcam.Stop();
} }
public override void OnShow() public override void OnShow()
@@ -189,25 +189,20 @@ namespace Vocaluxe.Screens
{ {
if (devices != null && devices.Length > 0) if (devices != null && devices.Length > 0)
{ {
_DeviceNr = 0;
_CapabilityNr = 0;
_GetFirstConfiguredWebcamDevice(ref _DeviceNr, ref _CapabilityNr);
foreach (SWebcamDevice d in devices) foreach (SWebcamDevice d in devices)
_SelectSlides[_SelectSlideWebcamDevices].AddValue(d.Name); _SelectSlides[_SelectSlideWebcamDevices].AddValue(d.Name);
_SelectSlides[_SelectSlideWebcamDevices].Selection = _DeviceNr;
foreach (SCapabilities c in devices[_DeviceNr].Capabilities) int devNr;
_SelectSlides[_SelectSlideWebcamCapabilities].AddValue(c.Width + " x " + c.Height + " @ " + c.Framerate + " FPS "); int capNr;
_Config.MonikerString = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].MonikerString; if (_GetFirstConfiguredWebcamDevice(out devNr, out capNr))
_Config.Width = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Width; {
_Config.Height = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Height; _SelectSlides[_SelectSlideWebcamDevices].Selection = devNr;
_Config.Framerate = _OnDeviceEvent();
devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Framerate; _SelectSlides[_SelectSlideWebcamCapabilities].Selection = capNr;
CWebcam.Close(); _OnCapabilitiesEvent();
CWebcam.Select(CConfig.WebcamConfig);
CWebcam.Start(); ssVisible = true;
ssVisible = true; }
} }
} }
catch (Exception e) catch (Exception e)
@@ -239,7 +234,6 @@ namespace Vocaluxe.Screens
{ {
_SelectSlides[_SelectSlideWebcamCapabilities].Clear(); _SelectSlides[_SelectSlideWebcamCapabilities].Clear();
_DeviceNr = _SelectSlides[_SelectSlideWebcamDevices].Selection; _DeviceNr = _SelectSlides[_SelectSlideWebcamDevices].Selection;
_CapabilityNr = 0;
SWebcamDevice d = CWebcam.GetDevices()[_DeviceNr]; SWebcamDevice d = CWebcam.GetDevices()[_DeviceNr];
for (int i = 0; i < d.Capabilities.Count; i++) for (int i = 0; i < d.Capabilities.Count; i++)
@@ -247,16 +241,8 @@ namespace Vocaluxe.Screens
_SelectSlides[_SelectSlideWebcamCapabilities].AddValue(d.Capabilities[i].Width + " x " + d.Capabilities[i].Height + _SelectSlides[_SelectSlideWebcamCapabilities].AddValue(d.Capabilities[i].Width + " x " + d.Capabilities[i].Height +
" @ " + d.Capabilities[i].Framerate + "FPS"); " @ " + d.Capabilities[i].Framerate + "FPS");
} }
_SelectSlides[_SelectSlideWebcamCapabilities].Selection = 0; _CapabilityNr = -1;
_OnCapabilitiesEvent();
_Config.MonikerString = d.MonikerString;
_Config.Width = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Width;
_Config.Height = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Height;
_Config.Framerate = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Framerate;
CWebcam.Close();
CWebcam.Select(_Config);
CWebcam.Start();
} }
} }
@@ -266,24 +252,27 @@ namespace Vocaluxe.Screens
{ {
_CapabilityNr = _SelectSlides[_SelectSlideWebcamCapabilities].Selection; _CapabilityNr = _SelectSlides[_SelectSlideWebcamCapabilities].Selection;
SWebcamDevice d = CWebcam.GetDevices()[_SelectSlides[_SelectSlideWebcamDevices].Selection]; SWebcamDevice d = CWebcam.GetDevices()[_DeviceNr];
_Config.MonikerString = d.MonikerString; _Config.MonikerString = d.MonikerString;
_Config.Width = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Width; _Config.Width = d.Capabilities[_CapabilityNr].Width;
_Config.Height = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Height; _Config.Height = d.Capabilities[_CapabilityNr].Height;
_Config.Framerate = d.Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Framerate; _Config.Framerate = d.Capabilities[_CapabilityNr].Framerate;
CWebcam.Close();
CWebcam.Select(_Config); CWebcam.Select(_Config);
CWebcam.Start(); CWebcam.Start();
} }
} }
private void _GetFirstConfiguredWebcamDevice(ref int device, ref int capabilities) private bool _GetFirstConfiguredWebcamDevice(out int device, out int capabilities)
{ {
SWebcamDevice[] devices = CWebcam.GetDevices(); SWebcamDevice[] devices = CWebcam.GetDevices();
if (devices == null) if (devices == null)
return; {
device = -1;
capabilities = -1;
return false;
}
for (int i = 0; i < devices.Length; i++) for (int i = 0; i < devices.Length; i++)
{ {
@@ -296,10 +285,13 @@ namespace Vocaluxe.Screens
{ {
device = i; device = i;
capabilities = j; capabilities = j;
return; return true;
} }
} }
} }
device = 0;
capabilities = 0;
return true;
} }
} }
} }
+44 -26
View File
@@ -141,13 +141,13 @@ namespace Vocaluxe.Screens
} }
else if (_Buttons[_ButtonDelete].Selected) else if (_Buttons[_ButtonDelete].Selected)
_DeleteProfile(); _DeleteProfile();
else if (_Buttons[_ButtonWebcam].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonWebcam].Selected)
_OnWebcam(); _OnWebcam();
else if (_Buttons[_ButtonSaveSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonSaveSnapshot].Selected)
_OnSaveSnapshot(); _OnSaveSnapshot();
else if (_Buttons[_ButtonDiscardSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonDiscardSnapshot].Selected)
_OnDiscardSnapshot(); _OnDiscardSnapshot();
else if (_Buttons[_ButtonTakeSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonTakeSnapshot].Selected)
_OnTakeSnapshot(); _OnTakeSnapshot();
break; break;
@@ -235,13 +235,13 @@ namespace Vocaluxe.Screens
CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex, CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex,
(EOffOn)_SelectSlides[_SelectSlideActive].Selection); (EOffOn)_SelectSlides[_SelectSlideActive].Selection);
} }
else if (_Buttons[_ButtonWebcam].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonWebcam].Selected)
_OnWebcam(); _OnWebcam();
else if (_Buttons[_ButtonSaveSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonSaveSnapshot].Selected)
_OnSaveSnapshot(); _OnSaveSnapshot();
else if (_Buttons[_ButtonDiscardSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonDiscardSnapshot].Selected)
_OnDiscardSnapshot(); _OnDiscardSnapshot();
else if (_Buttons[_ButtonTakeSnapshot].Selected && CWebcam.IsDeviceAvailable()) else if (_Buttons[_ButtonTakeSnapshot].Selected)
_OnTakeSnapshot(); _OnTakeSnapshot();
} }
@@ -270,15 +270,16 @@ namespace Vocaluxe.Screens
int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex); int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex);
_SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(avatarID); _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(avatarID);
if (CWebcam.IsDeviceAvailable() && CWebcam.IsCapturing()) if (_Snapshot == null)
{ {
if (_Snapshot == null) if (CWebcam.IsCapturing())
CWebcam.GetFrame(ref _WebcamTexture); {
if (CWebcam.GetFrame(ref _WebcamTexture))
_Statics[_StaticAvatar].Texture = _WebcamTexture; _Statics[_StaticAvatar].Texture = _WebcamTexture;
}
else
_Statics[_StaticAvatar].Texture = CProfiles.GetAvatarTexture(avatarID);
} }
else
_Statics[_StaticAvatar].Texture = CProfiles.GetAvatarTexture(avatarID);
} }
return true; return true;
@@ -310,22 +311,36 @@ namespace Vocaluxe.Screens
private void _OnTakeSnapshot() private void _OnTakeSnapshot()
{ {
_Buttons[_ButtonSaveSnapshot].Visible = true; if (!CWebcam.IsDeviceAvailable())
_Buttons[_ButtonDiscardSnapshot].Visible = true; {
_Buttons[_ButtonWebcam].Visible = false; CDraw.RemoveTexture(ref _WebcamTexture);
_Buttons[_ButtonTakeSnapshot].Visible = false; _Snapshot = null;
_Snapshot = CWebcam.GetBitmap(); _Buttons[_ButtonSaveSnapshot].Visible = false;
_Buttons[_ButtonDiscardSnapshot].Visible = false;
_Buttons[_ButtonTakeSnapshot].Visible = false;
_Buttons[_ButtonWebcam].Visible = false;
}
else
{
CWebcam.Stop(); //Do this first to get consistent frame and bitmap
_Snapshot = CWebcam.GetBitmap();
if (CWebcam.GetFrame(ref _WebcamTexture))
_Statics[_StaticAvatar].Texture = _WebcamTexture;
_Buttons[_ButtonSaveSnapshot].Visible = true;
_Buttons[_ButtonDiscardSnapshot].Visible = true;
_Buttons[_ButtonTakeSnapshot].Visible = false;
_Buttons[_ButtonWebcam].Visible = false;
}
} }
private void _OnDiscardSnapshot() private void _OnDiscardSnapshot()
{ {
CWebcam.Stop();
CDraw.RemoveTexture(ref _WebcamTexture);
_Snapshot = null; _Snapshot = null;
CDraw.RemoveTexture(ref _WebcamTexture);
_Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonSaveSnapshot].Visible = false;
_Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false;
_Buttons[_ButtonTakeSnapshot].Visible = false; _Buttons[_ButtonTakeSnapshot].Visible = false;
_Buttons[_ButtonWebcam].Visible = true; _Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable();
} }
private void _OnSaveSnapshot() private void _OnSaveSnapshot()
@@ -339,13 +354,12 @@ namespace Vocaluxe.Screens
_Snapshot.Save(filename, ImageFormat.Png); _Snapshot.Save(filename, ImageFormat.Png);
_Snapshot = null; _Snapshot = null;
CWebcam.Stop();
CDraw.RemoveTexture(ref _WebcamTexture); CDraw.RemoveTexture(ref _WebcamTexture);
_Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonSaveSnapshot].Visible = false;
_Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false;
_Buttons[_ButtonTakeSnapshot].Visible = false; _Buttons[_ButtonTakeSnapshot].Visible = false;
_Buttons[_ButtonWebcam].Visible = true; _Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable();
int id = CProfiles.NewAvatar(filename); int id = CProfiles.NewAvatar(filename);
CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, id); CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, id);
@@ -354,9 +368,13 @@ namespace Vocaluxe.Screens
private void _OnWebcam() private void _OnWebcam()
{ {
if (!CWebcam.IsDeviceAvailable())
{
_Buttons[_ButtonWebcam].Visible = false;
return;
}
_Snapshot = null; _Snapshot = null;
CWebcam.Start(); CWebcam.Start();
CWebcam.GetFrame(ref _WebcamTexture);
_Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonSaveSnapshot].Visible = false;
_Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false;
_Buttons[_ButtonTakeSnapshot].Visible = true; _Buttons[_ButtonTakeSnapshot].Visible = true;
+2 -2
View File
@@ -235,7 +235,7 @@ namespace Vocaluxe.Screens
case Keys.W: case Keys.W:
if (CWebcam.IsDeviceAvailable()) if (CWebcam.IsDeviceAvailable())
{ {
_Webcam = !_Webcam; _Webcam = !CWebcam.IsCapturing();
if (_Webcam) if (_Webcam)
CWebcam.Start(); CWebcam.Start();
else else
@@ -756,7 +756,7 @@ namespace Vocaluxe.Screens
CParty.FinishedSinging(); CParty.FinishedSinging();
if (_Webcam) if (_Webcam)
CWebcam.Close(); CWebcam.Stop();
} }
private int _FindCurrentLine(CVoice voice, CSongLine[] lines, CSong song) private int _FindCurrentLine(CVoice voice, CSongLine[] lines, CSong song)