From 63c681a0576cd3b8cb85d8bdb5299698ee49aee7 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Wed, 30 Apr 2014 22:35:31 +0200 Subject: [PATCH] Make webcam handling more stable (fix possible NPE) --- Vocaluxe/Base/CWebcam.cs | 44 ++-- Vocaluxe/Lib/Webcam/CAForgeNet.cs | 266 ++++++++++++++++-------- Vocaluxe/Lib/Webcam/IWebcam.cs | 16 +- Vocaluxe/Screens/CScreenOptionsVideo.cs | 68 +++--- Vocaluxe/Screens/CScreenProfiles.cs | 70 ++++--- Vocaluxe/Screens/CScreenSing.cs | 4 +- 6 files changed, 293 insertions(+), 175 deletions(-) diff --git a/Vocaluxe/Base/CWebcam.cs b/Vocaluxe/Base/CWebcam.cs index 0b7dcb46..af66025a 100644 --- a/Vocaluxe/Base/CWebcam.cs +++ b/Vocaluxe/Base/CWebcam.cs @@ -49,58 +49,70 @@ namespace Vocaluxe.Base return true; } + public static void Close() + { + if (_Webcam == null) + return; + _Webcam.Close(); + _Webcam = null; + } + public static bool GetFrame(ref CTexture tex) { - return _Webcam.GetFrame(ref tex); + return _Webcam != null && _Webcam.GetFrame(ref tex); } public static Bitmap GetBitmap() { - return _Webcam.GetBitmap(); - } - - public static void Close() - { - if (_Webcam != null) - { - _Webcam.Close(); - _Webcam = null; - } + return _Webcam == null ? null : _Webcam.GetBitmap(); } public static void Pause() { + if (_Webcam == null) + return; _Webcam.Pause(); } public static void Start() { + if (_Webcam == null) + return; _Webcam.Start(); } public static void Stop() { + if (_Webcam == null) + return; _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() { - return _Webcam.GetDevices(); + return _Webcam == null ? null : _Webcam.GetDevices(); } public static bool IsDeviceAvailable() { - return _Webcam.IsDeviceAvailable(); + return (_Webcam != null) && _Webcam.IsDeviceAvailable(); } public static bool IsCapturing() { - return _Webcam.IsCapturing(); + return (_Webcam != null) && _Webcam.IsCapturing(); } } } \ No newline at end of file diff --git a/Vocaluxe/Lib/Webcam/CAForgeNet.cs b/Vocaluxe/Lib/Webcam/CAForgeNet.cs index c83b1d8c..13bc4d20 100644 --- a/Vocaluxe/Lib/Webcam/CAForgeNet.cs +++ b/Vocaluxe/Lib/Webcam/CAForgeNet.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #endregion +using System; using AForge.Video; using AForge.Video.DirectShow; using System.Collections.Generic; @@ -31,60 +32,27 @@ namespace Vocaluxe.Lib.Webcam private readonly List _Devices = new List(); private bool _Paused; private VideoCaptureDevice _Webcam; - private FilterInfoCollection _WebcamDevices; private SWebcamConfig _Config; - private byte[] _Data = new byte[1]; + private byte[] _Data; private static readonly object _MutexData = new object(); private int _Width, _Height; - - public void Close() - { - 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; - } + private bool _NewFrameAvailable; + private bool _IsCapturing; public bool Init() { - _WebcamDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); - foreach (FilterInfo info in _WebcamDevices) + FilterInfoCollection webcams = new FilterInfoCollection(FilterCategory.VideoInputDevice); + foreach (FilterInfo info in webcams) { + var tmpdev = new VideoCaptureDevice(info.MonikerString); + if (tmpdev.VideoCapabilities.Length == 0) + continue; var device = new SWebcamDevice { Name = info.Name, MonikerString = info.MonikerString, - Capabilities = new List() + Capabilities = new List(tmpdev.VideoCapabilities.Length) }; - var tmpdev = new VideoCaptureDevice(info.MonikerString); foreach (VideoCapabilities capabilities in tmpdev.VideoCapabilities) { @@ -101,44 +69,188 @@ namespace Vocaluxe.Lib.Webcam return true; } - private void _OnFrame(object sender, NewFrameEventArgs e) + public void Close() { - if (_Paused) + DeSelect(); + _Devices.Clear(); + } + + public void DeSelect() + { + if (_Webcam == null) return; + _Webcam.Stop(); + _Webcam.NewFrame -= _OnFrame; + _IsCapturing = false; 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); + _Data = null; + _Webcam = null; } } - public void Pause() + #region ConfigSelection + private static float _GetScore(int value, int valueRequested) { - if (_Webcam != null) - _Paused = true; + if (valueRequested <= 0) + 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() { if (_Webcam == null) return; - _Webcam.NewFrame -= _OnFrame; - //Subscribe to NewFrame event - _Webcam.NewFrame += _OnFrame; - _Webcam.Start(); - _Paused = false; + if (_IsCapturing) + { + if (_Paused) + { + _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() { if (_Webcam != null) + { _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() @@ -148,42 +260,12 @@ namespace Vocaluxe.Lib.Webcam public bool IsDeviceAvailable() { - return _Devices.Count > 0; + return _Webcam != null; } public bool IsCapturing() { - return _Webcam.IsRunning; - } - - 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; + return _IsCapturing && !_Paused; } public SWebcamConfig GetConfig() diff --git a/Vocaluxe/Lib/Webcam/IWebcam.cs b/Vocaluxe/Lib/Webcam/IWebcam.cs index aa108411..98ae1804 100644 --- a/Vocaluxe/Lib/Webcam/IWebcam.cs +++ b/Vocaluxe/Lib/Webcam/IWebcam.cs @@ -46,19 +46,33 @@ namespace Vocaluxe.Lib.Webcam interface IWebcam { bool Init(); + void Close(); void Start(); void Pause(); void Stop(); - void Close(); + /// + /// Gets last captured frame. Returns true if frame was updated
+ /// Note that this will invalidate the last frame and not return it again with this function + ///
+ /// + /// bool GetFrame(ref CTexture frame); + + /// + /// Gets the last captured frame as a bitma + /// + /// + /// Null if no frame was captured, the bitmap otherwise Bitmap GetBitmap(); + SWebcamConfig GetConfig(); SWebcamDevice[] GetDevices(); bool IsDeviceAvailable(); bool IsCapturing(); bool Select(SWebcamConfig webcamConfig); + void DeSelect(); } } \ No newline at end of file diff --git a/Vocaluxe/Screens/CScreenOptionsVideo.cs b/Vocaluxe/Screens/CScreenOptionsVideo.cs index d1b446c8..a4cd2268 100644 --- a/Vocaluxe/Screens/CScreenOptionsVideo.cs +++ b/Vocaluxe/Screens/CScreenOptionsVideo.cs @@ -154,8 +154,8 @@ namespace Vocaluxe.Screens public override bool UpdateGame() { - CWebcam.GetFrame(ref _WebcamTexture); - _Statics[_StaticWebcamOutput].Texture = _WebcamTexture; + if (CWebcam.GetFrame(ref _WebcamTexture)) + _Statics[_StaticWebcamOutput].Texture = _WebcamTexture; _SelectSlides[_SelectSlideVideosToBackground].Selection = (int)CConfig.VideosToBackground; return true; } @@ -170,7 +170,7 @@ namespace Vocaluxe.Screens public override void OnClose() { base.OnClose(); - CWebcam.Close(); + CWebcam.Stop(); } public override void OnShow() @@ -189,25 +189,20 @@ namespace Vocaluxe.Screens { if (devices != null && devices.Length > 0) { - _DeviceNr = 0; - _CapabilityNr = 0; - _GetFirstConfiguredWebcamDevice(ref _DeviceNr, ref _CapabilityNr); - foreach (SWebcamDevice d in devices) _SelectSlides[_SelectSlideWebcamDevices].AddValue(d.Name); - _SelectSlides[_SelectSlideWebcamDevices].Selection = _DeviceNr; - foreach (SCapabilities c in devices[_DeviceNr].Capabilities) - _SelectSlides[_SelectSlideWebcamCapabilities].AddValue(c.Width + " x " + c.Height + " @ " + c.Framerate + " FPS "); - _Config.MonikerString = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].MonikerString; - _Config.Width = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Width; - _Config.Height = devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Height; - _Config.Framerate = - devices[_SelectSlides[_SelectSlideWebcamDevices].Selection].Capabilities[_SelectSlides[_SelectSlideWebcamCapabilities].Selection].Framerate; - CWebcam.Close(); - CWebcam.Select(CConfig.WebcamConfig); - CWebcam.Start(); - ssVisible = true; + int devNr; + int capNr; + if (_GetFirstConfiguredWebcamDevice(out devNr, out capNr)) + { + _SelectSlides[_SelectSlideWebcamDevices].Selection = devNr; + _OnDeviceEvent(); + _SelectSlides[_SelectSlideWebcamCapabilities].Selection = capNr; + _OnCapabilitiesEvent(); + + ssVisible = true; + } } } catch (Exception e) @@ -239,7 +234,6 @@ namespace Vocaluxe.Screens { _SelectSlides[_SelectSlideWebcamCapabilities].Clear(); _DeviceNr = _SelectSlides[_SelectSlideWebcamDevices].Selection; - _CapabilityNr = 0; SWebcamDevice d = CWebcam.GetDevices()[_DeviceNr]; 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 + " @ " + d.Capabilities[i].Framerate + "FPS"); } - _SelectSlides[_SelectSlideWebcamCapabilities].Selection = 0; - - _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(); + _CapabilityNr = -1; + _OnCapabilitiesEvent(); } } @@ -266,24 +252,27 @@ namespace Vocaluxe.Screens { _CapabilityNr = _SelectSlides[_SelectSlideWebcamCapabilities].Selection; - SWebcamDevice d = CWebcam.GetDevices()[_SelectSlides[_SelectSlideWebcamDevices].Selection]; + SWebcamDevice d = CWebcam.GetDevices()[_DeviceNr]; _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; + _Config.Width = d.Capabilities[_CapabilityNr].Width; + _Config.Height = d.Capabilities[_CapabilityNr].Height; + _Config.Framerate = d.Capabilities[_CapabilityNr].Framerate; - CWebcam.Close(); CWebcam.Select(_Config); CWebcam.Start(); } } - private void _GetFirstConfiguredWebcamDevice(ref int device, ref int capabilities) + private bool _GetFirstConfiguredWebcamDevice(out int device, out int capabilities) { SWebcamDevice[] devices = CWebcam.GetDevices(); if (devices == null) - return; + { + device = -1; + capabilities = -1; + return false; + } for (int i = 0; i < devices.Length; i++) { @@ -296,10 +285,13 @@ namespace Vocaluxe.Screens { device = i; capabilities = j; - return; + return true; } } } + device = 0; + capabilities = 0; + return true; } } } \ No newline at end of file diff --git a/Vocaluxe/Screens/CScreenProfiles.cs b/Vocaluxe/Screens/CScreenProfiles.cs index 106c3a04..2c29383d 100644 --- a/Vocaluxe/Screens/CScreenProfiles.cs +++ b/Vocaluxe/Screens/CScreenProfiles.cs @@ -141,13 +141,13 @@ namespace Vocaluxe.Screens } else if (_Buttons[_ButtonDelete].Selected) _DeleteProfile(); - else if (_Buttons[_ButtonWebcam].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonWebcam].Selected) _OnWebcam(); - else if (_Buttons[_ButtonSaveSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonSaveSnapshot].Selected) _OnSaveSnapshot(); - else if (_Buttons[_ButtonDiscardSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonDiscardSnapshot].Selected) _OnDiscardSnapshot(); - else if (_Buttons[_ButtonTakeSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonTakeSnapshot].Selected) _OnTakeSnapshot(); break; @@ -235,13 +235,13 @@ namespace Vocaluxe.Screens CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex, (EOffOn)_SelectSlides[_SelectSlideActive].Selection); } - else if (_Buttons[_ButtonWebcam].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonWebcam].Selected) _OnWebcam(); - else if (_Buttons[_ButtonSaveSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonSaveSnapshot].Selected) _OnSaveSnapshot(); - else if (_Buttons[_ButtonDiscardSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonDiscardSnapshot].Selected) _OnDiscardSnapshot(); - else if (_Buttons[_ButtonTakeSnapshot].Selected && CWebcam.IsDeviceAvailable()) + else if (_Buttons[_ButtonTakeSnapshot].Selected) _OnTakeSnapshot(); } @@ -270,15 +270,16 @@ namespace Vocaluxe.Screens int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex); _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(avatarID); - if (CWebcam.IsDeviceAvailable() && CWebcam.IsCapturing()) + if (_Snapshot == null) { - if (_Snapshot == null) - CWebcam.GetFrame(ref _WebcamTexture); - - _Statics[_StaticAvatar].Texture = _WebcamTexture; + if (CWebcam.IsCapturing()) + { + if (CWebcam.GetFrame(ref _WebcamTexture)) + _Statics[_StaticAvatar].Texture = _WebcamTexture; + } + else + _Statics[_StaticAvatar].Texture = CProfiles.GetAvatarTexture(avatarID); } - else - _Statics[_StaticAvatar].Texture = CProfiles.GetAvatarTexture(avatarID); } return true; @@ -310,22 +311,36 @@ namespace Vocaluxe.Screens private void _OnTakeSnapshot() { - _Buttons[_ButtonSaveSnapshot].Visible = true; - _Buttons[_ButtonDiscardSnapshot].Visible = true; - _Buttons[_ButtonWebcam].Visible = false; - _Buttons[_ButtonTakeSnapshot].Visible = false; - _Snapshot = CWebcam.GetBitmap(); + if (!CWebcam.IsDeviceAvailable()) + { + CDraw.RemoveTexture(ref _WebcamTexture); + _Snapshot = null; + _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() { - CWebcam.Stop(); - CDraw.RemoveTexture(ref _WebcamTexture); _Snapshot = null; + CDraw.RemoveTexture(ref _WebcamTexture); _Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonTakeSnapshot].Visible = false; - _Buttons[_ButtonWebcam].Visible = true; + _Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable(); } private void _OnSaveSnapshot() @@ -339,13 +354,12 @@ namespace Vocaluxe.Screens _Snapshot.Save(filename, ImageFormat.Png); _Snapshot = null; - CWebcam.Stop(); CDraw.RemoveTexture(ref _WebcamTexture); _Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonTakeSnapshot].Visible = false; - _Buttons[_ButtonWebcam].Visible = true; + _Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable(); int id = CProfiles.NewAvatar(filename); CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, id); @@ -354,9 +368,13 @@ namespace Vocaluxe.Screens private void _OnWebcam() { + if (!CWebcam.IsDeviceAvailable()) + { + _Buttons[_ButtonWebcam].Visible = false; + return; + } _Snapshot = null; CWebcam.Start(); - CWebcam.GetFrame(ref _WebcamTexture); _Buttons[_ButtonSaveSnapshot].Visible = false; _Buttons[_ButtonDiscardSnapshot].Visible = false; _Buttons[_ButtonTakeSnapshot].Visible = true; diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 32e0442e..c7956c9c 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -235,7 +235,7 @@ namespace Vocaluxe.Screens case Keys.W: if (CWebcam.IsDeviceAvailable()) { - _Webcam = !_Webcam; + _Webcam = !CWebcam.IsCapturing(); if (_Webcam) CWebcam.Start(); else @@ -756,7 +756,7 @@ namespace Vocaluxe.Screens CParty.FinishedSinging(); if (_Webcam) - CWebcam.Close(); + CWebcam.Stop(); } private int _FindCurrentLine(CVoice voice, CSongLine[] lines, CSong song)