i have a problem with the WaitForStop() function.
In debug mode with single-step it always work. But without break-point sometimes the function never returns.
I spend hours with trying different tipps found with google - but still no success.
For debugging i added a few "Debug.Print" into the WaitForStop function in VideoCaptureDevice.cs:
- Code: Select all
public void WaitForStop( )
{
if ( thread != null )
{
Debug.Print("WaitForStop thread != null");
// wait for thread stop
thread.Join( );
Debug.Print("WaitForStop thread joined!");
Free( );
Debug.Print("WaitForStop Free -> ok");
}
}
A typical output is like this:
WaitForStop thread != null
WaitForStop thread joined!
WaitForStop Free -> ok
WaitForStop thread != null
WaitForStop thread joined!
WaitForStop Free -> ok
WaitForStop thread != null
- here is the "joined" and " Free ok" missing
When the function did not return and i press the pause-button on ide and change to the right thread the IDE shows me as next line 1255 from WorkerThread of VideoCaptureDevice.cs:
- Code: Select all
mediaControl.Stop( );
This is my CloseVideoSource function:
- Code: Select all
private void CloseVideoSource()
{
//if (camDevices != null && camDevices.Current.IsRunning)
//{
// this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (SendOrPostCallback)delegate
// {
camDevices.Current.SignalToStop();
camDevices.Current.WaitForStop();
camDevices.Current.NewFrame -= Current_NewFrame;
camDevices = null;
//}, null);
//}
}
Can anyone of you please have a look at my Source - where is my failure?
Thank you very much!
BR Bernd
Here my full code:
- Code: Select all
using System;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing;
using System.Drawing.Imaging;
namespace WebCamTest
{
public partial class MainWindow : Window
{
public int bestindex = 0;
public int viewindex = 0;
public bool takeSnapshot = false;
public bool okSnapshot = false;
public Bitmap myTestBitmap;
public CameraDevices camDevices;
public VideoCapabilities[] videoCapabilities;
public MainWindow()
{
InitializeComponent();
BT_Connect.IsEnabled = true;
BT_DisConnect.IsEnabled = false;
BT_SnapShot.IsEnabled = false;
}
private void BT_Connect_Click(object sender, RoutedEventArgs e)
{
InitWebCam(false);
BT_Connect.IsEnabled = false;
BT_DisConnect.IsEnabled = true;
BT_SnapShot.IsEnabled = true;
}
private void BT_DisConnect_Click(object sender, RoutedEventArgs e)
{
CloseVideoSource();
BT_Connect.IsEnabled = true;
BT_DisConnect.IsEnabled = false;
BT_SnapShot.IsEnabled = false;
}
private void BT_SnapShot_Click(object sender, RoutedEventArgs e)
{
CloseVideoSource();
InitWebCam(true);
BT_Connect.IsEnabled = false;
BT_DisConnect.IsEnabled = true;
BT_SnapShot.IsEnabled = true;
}
public void InitWebCam(bool highRes)
{
if (camDevices != null)
{
if (camDevices.Current != null)
{
CloseVideoSource();
}
}
camDevices = new CameraDevices();
int CamNumber = 0;
camDevices.SelectCamera(CamNumber);
videoCapabilities = camDevices.videoCapabilities;
//search preview and best resolution
int index = 0;
int oldwidth = 0;
if (!highRes)
{
foreach (VideoCapabilities capabilty in videoCapabilities)
{
if (capabilty.FrameSize.Width == 640)
{
viewindex = index;
}
if (capabilty.FrameSize.Width >= oldwidth)
{
oldwidth = capabilty.FrameSize.Width;
bestindex = index;
}
index++;
}
}
//switch to preview or screenshot resolution
if (highRes)
{
camDevices.Current.VideoResolution = videoCapabilities[bestindex];
}
else
{
camDevices.Current.VideoResolution = videoCapabilities[viewindex];
}
camDevices.Current.NewFrame += Current_NewFrame;
camDevices.Current.Start();
}
private void Current_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
ShowFrame((Bitmap)eventArgs.Frame.Clone());
}
catch (ObjectDisposedException)
{
// not sure, why....
}
}
private void ShowFrame(Bitmap frame)
{
var bitmapSource = CreateBitmapSourceFromGdiBitmap(frame);
if (takeSnapshot)
{
takeSnapshot = false;
myTestBitmap = new Bitmap(frame);
//SaveWebCamSnapshot();
okSnapshot = true;
frame.Dispose();
bitmapSource = null;
Debug.Print(DateTime.Now.ToString("HH:mm:ss.fff") + " new frame end after screenshot");
return;
}
frame.Dispose();
bitmapSource.Freeze();
this.Dispatcher.Invoke(() =>
{
try
{
imgViewer.Source = bitmapSource;
}
catch (Exception e)
{
Debug.Print(e.ToString());
}
});
bitmapSource = null;
}
private void CloseVideoSource()
{
//if (camDevices != null && camDevices.Current.IsRunning)
//{
// this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, (SendOrPostCallback)delegate
// {
camDevices.Current.SignalToStop();
camDevices.Current.WaitForStop();
camDevices.Current.NewFrame -= Current_NewFrame;
camDevices = null;
//}, null);
//}
}
public static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap)
{
if (bitmap == null)
throw new ArgumentNullException("bitmap");
var rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
var bitmapData = bitmap.LockBits(
rect,
ImageLockMode.ReadWrite,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
try
{
var size = (rect.Width * rect.Height) * 4;
return BitmapSource.Create(
bitmap.Width,
bitmap.Height,
bitmap.HorizontalResolution,
bitmap.VerticalResolution,
System.Windows.Media.PixelFormats.Bgra32,
null,
bitmapData.Scan0,
size,
bitmapData.Stride);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
}
public class CameraDevices
{
public FilterInfoCollection Devices { get; private set; }
public VideoCaptureDevice Current { get; private set; }
public VideoCapabilities[] videoCapabilities;
public CameraDevices()
{
Devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
}
public void SelectCamera(int index)
{
if (index >= Devices.Count)
{
throw new ArgumentOutOfRangeException("index");
}
Current = new VideoCaptureDevice(Devices[index].MonikerString);
videoCapabilities = Current.VideoCapabilities;
}
}
}