PDA

View Full Version : ¿How to stop thread that is capturing from a webcam?



JoseTlaseca
27th August 2008, 22:15
Hello everybody.

I have a little problem.

I have an app with two buttons, one for start an image capturing thread from a webcam and show them, and the another one is for stop thread (wich means stop capturing).
My thread's run method look like this:


void thread::run()
{

while(1)
{
webcam_read_frame(parent_thread->cam_fd, parent_thread->pixelImagen);

if(parent_thread->need_update)
{
QCustomEvent *evento = new QCustomEvent(QEvent::User);
parent_thread->need_update = false;
QApplication::postEvent(parent_thread, evento);
}
}
}

The idea is the thread keep running 'till i push "stop" button.



The code for my stop buttons is:


void gui_tracksys::slot_pushButtonStop_clicked()
{
webcam_close(cam_fd); //this line stops capture and close webcam

//also delete other things like QImage, QPixmap, QPainter, etc...

if (myThread->running())
{
myThread->terminate();
myThread->wait(5000);
delete myThread;
}
}


I see the problem is I keep calling webcam_read_frame() after I've called webcam_close(), because when i click "stop" the first thing i do is close webcam and thread still running, so the run method try to call webcam_read_frame() but cam doesn't exist anymore.
I've tried to stop thread first and then close webcam, but this cause my app becomes unresponsive and need to click "x" (window close button) and then click "force close" when asked.

I don't know how to fix my problem, so any suggestion is welcome.

I'm using QT3/c/c++

I'm sorry about my bad english... Thank you very much...

PS:If need more info about my code i will post, just let me know.

jacek
27th August 2008, 22:19
Try this:
void thread::run()
{

while( _go )
{
...
}
// clean up
}

void thread::stop() { _go = false; }

...

if (myThread->running())
{
myThread->stop();
myThread->wait(5000);
delete myThread;
}
...
This way the thread will be able to finish gently and clean up after itself.

wysota
27th August 2008, 22:19
Why not stop the thread first and then close the camera?

Apart from that try to avoid using terminate(). Instead raise some flag in the thread (so that your while(1) loop becomes "while(!finish)") and call QThread::wait() afterwards (in the main thread) to pause until the worker thread exits. You shouldn't be experiencing those weird effects then.

JoseTlaseca
27th August 2008, 22:52
I've tried as you suggested but i get an error:


Class "thread" has no member named "stop"

I suppose the cause is i am using QT3, and there is no a member function named "stop" in the QThread class reference (http://doc.trolltech.com/3.3/qthread.html).

I change this line to terminate(); and i get less error than before (I forgot to mention i got 4 errors, all the same, one for each buffer i use to queue frames), but still getting 1 error because cam does not exist and thread still reading frames.

this is the way i do:


void thread::run()
{

while(padre->capturing)
{
webcam_read_frame(parent->cam_fd, parent->pixelImagen);
if(padre->need_update)
{
QCustomEvent *evento = new QCustomEvent(QEvent::User);
padre->need_update = false;
QApplication::postEvent(parent, evento);
}
}
}

and stop button:


void gui_tracksys::slot_pushButtonStop_clicked()
{
captururing = false;

webcam_close(cam_fd);

if (miHilo->running())
{
miHilo->terminate();
miHilo->wait(5000);
delete miHilo;
}
}

What can i do?

jacek
27th August 2008, 22:56
I suppose the cause is i am using QT3, and there is no a member function named "stop" in the QThread class reference
You were supposed to add it to your class definition.


I change this line to terminate();
Forget about this method.


webcam_close(cam_fd);
This should be in run(). If the thread uses the webcam, it should open it and it should clean it up. Otherwise you will have webcam code smeared all over your sources.

JoseTlaseca
27th August 2008, 22:57
Wysota says:

Why not stop the thread first and then close the camera?

If I stop thread first and the close cam i get a segmentation fault and program crash.
So i close cam first and then stop thread, this way i get error but program finish correctly.

JoseTlaseca
27th August 2008, 23:12
You were supposed to add it to your class definition.

I see... ok, but what code i need to put inside that "myThread->stop();"???

wysota
27th August 2008, 23:31
See line #11 of Jacek's code.

JoseTlaseca
28th August 2008, 04:45
Hello!

Finally i fixed that problem.

I was confused with your advices but now i'm clear and everythings ok.

The final code of my "Stop" button is:



void gui_tracksys::slot_pushButtonStop_clicked()
{
if (myThread->running())
{
myThread->stop();
myThread->wait(5000);
delete myThread;
}

webcam_close(cam_fd);
}

and the thread's code is:


void thread::run()
{
while(parent->capturing)
{
webcam_read_frame(parent->cam_fd, parent->pixelImagen);

if(parent->need_update)
{
QCustomEvent *evento = new QCustomEvent(QEvent::User);
parent->need_update = false;
QApplication::postEvent(parent, evento);
}
}
}

And the thread's "stop" method:


void thread::stop()
{
parent->capturing = false;
}

Finally in class destructor i delete all pointers used.

Thank you very much.

problem SOLVED...