PDA

View Full Version : How to capture video, snapshot, video?



BennettG
April 13, 2011, 02:21:48
Hi all. I'd like to be able to set up a single TIS USB camera to capture a low-res format , then on command capture a single hi-res snapshot, then return to capturing low-res video.

I'm using IC 3.2 and building with VS2003 C++ with a listener callback and a single-frame sink to capture the video. I use snapImages for the snapshot.

When attempting to capture a snapshot, I stop and close the device, configure for the snapshot format, open, start, grab the snapshot, stop, close, configure for video again, open, start.

I'm having trouble with the listener never getting called when re-starting the video, sometimes even when stopping and restarting my application. I appears to have worse when going from hi-res to low res capture and be sensitive to the FPS when using setFPS.

How would you recommend I code this task? I'd like the approach to not load the CPU lo-res capture, snap an image as quickly as possible and return to video and do it reliably.

Thanks for any help.
Bennett

Stefan Geissler
April 13, 2011, 08:36:20
Hello Bennett,

If the listener is not called, then it is either not attached to the grabber or there is no sink attached to the grabber. From my point of view, it is absolutely no relation to the frame rate.

You may post with a simple project, that reproduces your problem and I will fix it for you.

BennettG
April 13, 2011, 17:13:20
Here is a simple project that runs a listener callback capture first with a hi-res video format, then with low. The listener is not called for the low-res capture run 100% repeatably for both devices I have.

See ReadMe.txt for more notes.

Thanks
Bennett

BennettG
April 14, 2011, 03:36:40
And one.

Here is a simple project that runs a listener callback capture with low, high, low video formats. The listener is not called for the second low-res capture.

It also runs a snapImages in a similar manner which fails in the same way.

both of these run 100% repeatably for the two devices I have.

See ReadMe.txt for more notes.

Thanks
Bennett

Myron69
April 14, 2011, 07:53:34
Hi,

we tried the TestListener project on a quite fast 32-bit Win7 machine, where we did get images (listener call back called)
after change to video size from 2592x1944 to 640x480. So here the setup worked properly.

Then we did the same with a 32-bit Win XP (not so fast machine). Here we did not get images after changing to video size 640x480,
just as described by BennethG. We even increased the collecting time from 5 seconds to 30 seconds without any success.

We used a DMx 72BUC02 camera, so we also changed the color type from RGB32 to Y800 (both in creating sink and setting video format).


Our real problem is that we are using the camera for taking video at 640x480 and taking snapshots in high resolution 2560x1920.
The snapshots are using the external trigger, where it fails for us. We will create another support thread for this.

Best regards,

Myron69

BennettG
April 14, 2011, 17:25:19
After more testing, the app appears sensitive to the lo-res capture frame rate. The second lo-res listener and snapshot capture sessions fail to get images when the requested frame rate is 2-20, 40 and 50 and work for 25-35, 45, 55, 60. Interesting. updated test app attached.

Stefan Geissler
April 15, 2011, 12:01:04
Hello Bennett,

I look into your latest project. However, I have the faint suspect, you program is just fine, but there are problems with the computer caused by the idle states of the CPU. As far as we know, following happens: The communications controller receives a list of commands from the CPU. It starts to execute this list. Now the CPU is idle again and changes in the C3 state for power saving. When the communications controller has finished the command list, it asks the CPU for new commands. While it waits for the CPU coming from C3 into C0, the video capture device keeps sending data, which are not picked up by the communications controller. This causes a buffer overrun and leads to lost data blocks.
The USB camera driver can detect these incomplete images and will drop them. The FireWire camera driver can not detect them and therefore you will see the disturbed images.
In case you use an Intel CPU, you may try Processor Idle State Manger. It tries to prevent the CPU going into C3 state. The program can be downloaded from http://www.imagingcontrol.com/en_US/downloads/tools/

I would like you to try this

BennettG
April 17, 2011, 19:28:08
Hi Stephan. Thanks for looking at this. I downloaded, installed and ran the idle state manager. No change in the test app. I can see the manager hitting 3 of 4 cpus in taskmanager. The test app doesn't drop frames. it doesn't capture any for the second lo-res capture or snap.

Additionally, I note that your IC Capture application does not reliably switch from displaying video {Y800,RGB24,RGB32} 640x480 @ >= 30 FPS to 20,15,10 or 6.23 FPS, failing with the dialog attached. It will start when switched back or if you manually click the live video button twice.

My workaround at this point is to run lo-res in one of the frame rates I can switch to snapshot and back with.

Bennett

Stefan Geissler
April 19, 2011, 11:35:19
Hello Bennett,

we are able to reproduce the problem of switching the video formats. It seems to be a problem of the camera's firmware. I would like you to create a request at http://www.imagingcontrol.com/en_US/support/case/ , so I am able to send you a new firmware, when the problem is solved. This week the engineers are on easter holidays.

Stefan Geissler
May 3, 2011, 10:10:07
Hello,

Today I went much deeper into this problem, in the hope I am able to reproduce the problem. However, I failed. The camera runs flawlessly, resolutions can be changed. I set up the grabber as follows

m_cGrabber.addListener(&m_cListener);
m_pSink = FrameHandlerSink::create( DShowLib::eRGB32, 2 );
m_pSink->setSnapMode( false ); // Automatically copy every frame to the sink and call CListener::frameReady().
m_cGrabber.setSinkType( m_pSink );


In the CListener::frameReady the variable m_bImageReceived is set to true only, if an image was received.

This is the test start function:

void CMy72erTestDlg::StartNewTest()
{
m_cGrabber.stopLive();
m_cGrabber.closeDev();
m_cGrabber.openDev("DFx 72BUC02");

//if( m_cGrabber.getAcqSizeMaxX() == 640 )
if( m_FormatToggle == 0)
{
m_cGrabber.setVideoFormat("RGB32 (2592x1944)");
m_cGrabber.setFrameRate( (long)(1000.0f/5.99f));
m_FormatToggle = 1;
}
else
{
m_cGrabber.setVideoFormat("RGB32 (640x480)");
m_cGrabber.setFrameRate( (long)(1000.0f/53.37f));
m_FormatToggle = 0;
}

m_cListener.m_bImageReceived = false;
m_iTries = 10;

if( m_cGrabber.startLive() )
{
SetTimer(2,500,NULL);
}
else
{
MessageBox("StartLive failed","Test",MB_OK);
}
}

The "m_FormatToggle" variable is used to know, which format is used last time.

The verification for images is done in the timer event handler. It simply checks the m_bImageReceived and uses a timeout defined by the countdown of m_iTries:


void CMy72erTestDlg::OnTimer(UINT_PTR nIDEvent)
{
KillTimer( nIDEvent);
if( nIDEvent == 1)
{
StartNewTest();
}

if( nIDEvent == 2 )
{
if( m_cListener.m_bImageReceived)
{
if( m_chkTest.GetCheck() )
{
StartNewTest();
}
}
else
{
if( m_iTries > 0 )
{
m_iTries--;
SetTimer(2,500,NULL);
}
else
{
MessageBox("Keine Bilder: " + CString(m_cGrabber.getVideoFormat().c_str()));
}
}
}

CDialog::OnTimer(nIDEvent);
}


If found in your sample following issues:
You donot need to close the device in order to set the video format. This is time consuming only. Simply a call to "stopLive" will do the job.

Secondly, the ring buffer size in the sink should be at least 2.

Third, this sink needs only to be created once. It will be adapted to the video format's size, when startLive() is called.

In the sample program I found, that the there is waited for one second only. However, the DFK 72AUC02 needs more than one second to start if it is in high resolution/low frame rate mode.

Myron69
May 3, 2011, 12:20:15
Hello Stefan

BennetG's code still fails to work often.

What's wrong with BennetG's code?
How is BennetG misusing your API?

Your example stops, closes and opens the device each time you change resolution. That differs from BennetG's example and that might re-initialise something in the camera/usb bus that makes your code work!

We still have a problem in our application when taking snapshot which often creates timeouts and we think that this problem relates to the same problem as shown/described in the BennetG example code.

Regards,

Myron69 aka Jesper Myron Jeppesen, ChemoMetec A/S, Denmark

PS. Our cameras are of type DMx 72BUC02

Stefan Geissler
May 3, 2011, 14:10:26
I found following:
Changing from

m_cGrabber.setVideoFormat("RGB32 (2592x1944)");
m_cGrabber.setFrameRate( (long)(1000.0f/5.99f));

to


m_cGrabber.setVideoFormat("RGB32 (640x480)");
m_cGrabber.setFrameRate( (long)(1000.0f/30.0f));

and back again just works fine.

But:
Changing from

m_cGrabber.setVideoFormat("RGB32 (2592x1944)");
m_cGrabber.setFrameRate( (long)(1000.0f/5.99f));

to


m_cGrabber.setVideoFormat("RGB32 (640x480)");
m_cGrabber.setFrameRate( (long)(1000.0f/39.0f));
will not start the camera.

Therefore, I suggest to use 30 fps for your low resolution video.

BennettG
May 3, 2011, 18:55:58
Thanks Stephan. I refactored my little test app to run without closing the device as you describe.

First, thanks for the good info on the long-lived listener and frame sink and that open/close are not required to change formats. That will help achieve faster snapshot timing.

My notes:

1. The key detail that Jesper and I noted is that 640x480 capture will not reliably start after 2592x1944 capture at frame rates of 10,15, 20,40,50 FPS. It will start reliably @ 25,30,35,45,55,60 FPS.
2. As I noted above in this thread, the TIS IC Capture application behaves in a similar manner for a number of video formats when switching from a higher, working frame rate to a lower one. (ie 1024x768 starts at 25fps but won't at 10 or 15.) The app will start live video for some of the lower rates but not others.
3. I discovered that I must call prepareLive after changing the format so that the MemBuffer passed to the listener frameReady is the correct size. The sequence of operations in pseudocode is then:


setVideoFormat
setFPS
prepareLive
startLive
capture....
stopLive

4. I can reliably capture @ 2592x1944 with a 1-second timeout. I will change to 2 seconds.
5. I can reliably capture with a 1-frame sink. I will change to your recommended 2 frames.

For now, I will choose a format and rate that will start reliably in IC Capture.

Thanks
Bennett

Stefan Geissler
May 11, 2011, 11:30:58
1. The key detail that Jesper and I noted is that 640x480 capture will not reliably start after 2592x1944 capture at frame rates of 10,15, 20,40,50 FPS. It will start reliably @ 25,30,35,45,55,60 FPS.
Interresting. I did not knew in that in detail. However, the engineers are working on this.

2. As I noted above in this thread, the TIS IC Capture application behaves in a similar manner for a number of video formats when switching from a higher, working frame rate to a lower one. (ie 1024x768 starts at 25fps but won't at 10 or 15.) The app will start live video for some of the lower rates but not others.
This is to be expected, because the problem is caused by the camera.

3. I discovered that I must call prepareLive after changing the format so that the MemBuffer passed to the listener frameReady is the correct size. The sequence of operations in pseudocode is then:
This is correct

I can reliably capture @ 2592x1944 with a 1-second timeout. I will change to 2 seconds.
Good

I can reliably capture with a 1-frame sink. I will change to your recommended 2 frames.
Good too.