Trying to build 2D barcode scanner on basis of DxSnap project. According to my algorythm after entering in "detect" mode I'm planning to take many pictures while focuse immage an pass them to process for Zxing library. I was planning to make bitmap grabbing and 2D barcode extracing from picture in separate thread but got proble in more simplefied task. I can't grab many pictures in cycle:
private void button2_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
for (int i = 0; i < 10; i++)
{
// Release any previous buffer
if (m_ip != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(m_ip);
m_ip = IntPtr.Zero;
}
// capture image
m_ip = cam.Click();
Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, m_ip);
// If the image is upsidedown
b.RotateFlip(RotateFlipType.RotateNoneFlipY);
//pictureBox1.Image = b;
Console.WriteLine("click done");
}
Cursor.Current = Cursors.Default;
}
During second cycle I have exception "Timeout waiting to get picture".
If I add sleep line in cycle System.Threading.Thread.Sleep(1000); it solves the problem. But why I should add it?
In case I run picture taking in separate thread I have xception "Specified cast is not valid"
in catch block of sample DxSnap Capture class:
public IntPtr Click()
{
int hr;
// get ready to wait for new image
m_PictureReady.Reset();
m_ipBuffer = Marshal.AllocCoTaskMem(Math.Abs(m_stride) * m_videoHeight);
try
{
m_WantOne = true;
// If we are using a still pin, ask for a picture
if (m_VidControl != null)
{
// Tell the camera to send an image
hr = m_VidControl.SetMode(m_pinStill, VideoControlFlags.Trigger);
DsError.ThrowExceptionForHR(hr);
}
// Start waiting
if (!m_PictureReady.WaitOne(90000, false))
{
throw new Exception("Timeout waiting to get picture");
}
}
catch
{
Marshal.FreeCoTaskMem(m_ipBuffer);
m_ipBuffer = IntPtr.Zero;
throw;
}
// Got one
return m_ipBuffer;
}
The code DxSnap uses to signal that an image is needed and to return that image is (in retrospect) pretty bad. I was younger then.
Part of your problem might be that m_WantOne might not get updated the way you expect. You could try marking it as volatile. Might help.
As for threading, the problem comes from creating objects in one thread and trying to use them in another. There are ways to do this (see MTAThread), but that can lead to other problems. Better is to create and access all the DS objects from the same thread. Note that the pointer sent back from Click is just a pointer to memory (ie NOT a DS object) and can cross threads just fine.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
Trying to build 2D barcode scanner on basis of DxSnap project. According to my algorythm after entering in "detect" mode I'm planning to take many pictures while focuse immage an pass them to process for Zxing library. I was planning to make bitmap grabbing and 2D barcode extracing from picture in separate thread but got proble in more simplefied task. I can't grab many pictures in cycle:
During second cycle I have exception "Timeout waiting to get picture".
If I add sleep line in cycle System.Threading.Thread.Sleep(1000); it solves the problem. But why I should add it?
In case I run picture taking in separate thread I have xception "Specified cast is not valid"
in catch block of sample DxSnap Capture class:
Calling side code:
How to deal in case I need to proceed it in separate thread?
Last edit: column 2018-11-10
The code DxSnap uses to signal that an image is needed and to return that image is (in retrospect) pretty bad. I was younger then.
Part of your problem might be that m_WantOne might not get updated the way you expect. You could try marking it as volatile. Might help.
As for threading, the problem comes from creating objects in one thread and trying to use them in another. There are ways to do this (see MTAThread), but that can lead to other problems. Better is to create and access all the DS objects from the same thread. Note that the pointer sent back from Click is just a pointer to memory (ie NOT a DS object) and can cross threads just fine.