Clear the message queue

  • Follow


Hi,
I create a dialog-based application. I capture video frame from webcam with 
VFW and create a UI thread, CEncThread, to encode the frame. The 
OnCaptureVideo is invoked when the video frame is captured by the driver, 
copy the frame data into global frame memory, and send a message to tell the 
CEncThread to encode:
========================================
if (g_bFrameCopied == false) {
      memcpy(g_szFrame, captureframe, size);
      g_nFrameLength = size;
      g_bFrameCopied = true;

      ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
========================================
The CEncThread will copy the video frame from global memory into local 
memory and encode it with jpeg2000 codec:
========================================
   if (g_bFrameCopied == true) {
      memcpy(s_szFrame, g_szFrame, g_nFrameLength);
      g_bFrameCopied = false;
   }
  m_Encode.CreateFromArray((unsigned char *)g_szFrame, FRAME_WIDTH, 
FRAME_HEIGHT, 8, FRAME_WIDTH, false);
   m_Encode.SetJpegQuality(10);
   m_Encode.Encode(buffer,len,CXIMAGE_FORMAT_JP2);  
========================================
After closing the program, I get an error at this statement:
========================================
::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
========================================
I think that there maybe a few messages that invoke video callback function 
in message queue after stopping the capturing process and disable the 
callback function. So, It still calls PostThreadMessage to tell CEncThread to 
work after CEncThread is closed. I want to know how to clear the message 
queue???
0
Reply mmlabjs (29) 3/19/2007 2:10:38 PM

My solution is:
When I close the CEncThread thread, I set a flag:
================================================
   g_bExit = true;
 
   if (m_pVidCap != NULL) {
      m_pVidCap->StopCapture();	 // Stop the processing
      m_pVidCap->Destroy();         // Disable the callback function and 
disconnect the driver
      delete m_pVidCap;
   }

   if (m_pEncThread)
   {
      if (::PostThreadMessage(m_pEncThread->m_nThreadID, WM_TERM_THREAD, 0, 
0) == 0)
         TRACE(_TEXT("Thread 0x%02x possibly already terminated\n"), 
m_pEncThread->m_nThreadID);
      m_pEncThread = 0;
   }
================================================
I insert the following code into callback function:
================================================
if (g_bExit)
      return;
if (g_bFrameCopied == false) {
      memcpy(g_szFrame, captureframe, size);
      g_nFrameLength = size;
      g_bFrameCopied = true;

      ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
================================================

"mmlab_js" wrote:

> Hi,
> I create a dialog-based application. I capture video frame from webcam with 
> VFW and create a UI thread, CEncThread, to encode the frame. The 
> OnCaptureVideo is invoked when the video frame is captured by the driver, 
> copy the frame data into global frame memory, and send a message to tell the 
> CEncThread to encode:
> ========================================
> if (g_bFrameCopied == false) {
>       memcpy(g_szFrame, captureframe, size);
>       g_nFrameLength = size;
>       g_bFrameCopied = true;
> 
>       ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
> ========================================
> The CEncThread will copy the video frame from global memory into local 
> memory and encode it with jpeg2000 codec:
> ========================================
>    if (g_bFrameCopied == true) {
>       memcpy(s_szFrame, g_szFrame, g_nFrameLength);
>       g_bFrameCopied = false;
>    }
>   m_Encode.CreateFromArray((unsigned char *)g_szFrame, FRAME_WIDTH, 
> FRAME_HEIGHT, 8, FRAME_WIDTH, false);
>    m_Encode.SetJpegQuality(10);
>    m_Encode.Encode(buffer,len,CXIMAGE_FORMAT_JP2);  
> ========================================
> After closing the program, I get an error at this statement:
> ========================================
> ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
> ========================================
> I think that there maybe a few messages that invoke video callback function 
> in message queue after stopping the capturing process and disable the 
> callback function. So, It still calls PostThreadMessage to tell CEncThread to 
> work after CEncThread is closed. I want to know how to clear the message 
> queue???
0
Reply mmlabjs (29) 3/19/2007 2:18:05 PM

By the way ... if your application is exiting ... you should end the 
secondary thread gracefully ...... let it process the messages in message 
queue ... post your own custom exit message in the queue ....

"mmlab_js" <mmlabjs@discussions.microsoft.com> wrote in message 
news:0417D63A-E651-4B40-9CCB-91105B8B4FF4@microsoft.com...
> Hi,
> I create a dialog-based application. I capture video frame from webcam 
> with
> VFW and create a UI thread, CEncThread, to encode the frame. The
> OnCaptureVideo is invoked when the video frame is captured by the driver,
> copy the frame data into global frame memory, and send a message to tell 
> the
> CEncThread to encode:
> ========================================
> if (g_bFrameCopied == false) {
>      memcpy(g_szFrame, captureframe, size);
>      g_nFrameLength = size;
>      g_bFrameCopied = true;
>
>      ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 
> 0);
> ========================================
> The CEncThread will copy the video frame from global memory into local
> memory and encode it with jpeg2000 codec:
> ========================================
>   if (g_bFrameCopied == true) {
>      memcpy(s_szFrame, g_szFrame, g_nFrameLength);
>      g_bFrameCopied = false;
>   }
>  m_Encode.CreateFromArray((unsigned char *)g_szFrame, FRAME_WIDTH,
> FRAME_HEIGHT, 8, FRAME_WIDTH, false);
>   m_Encode.SetJpegQuality(10);
>   m_Encode.Encode(buffer,len,CXIMAGE_FORMAT_JP2);
> ========================================
> After closing the program, I get an error at this statement:
> ========================================
> ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
> ========================================
> I think that there maybe a few messages that invoke video callback 
> function
> in message queue after stopping the capturing process and disable the
> callback function. So, It still calls PostThreadMessage to tell CEncThread 
> to
> work after CEncThread is closed. I want to know how to clear the message
> queue??? 


0
Reply mubi (160) 3/19/2007 2:30:16 PM

See below
On Mon, 19 Mar 2007 07:10:38 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:

>Hi,
>I create a dialog-based application. I capture video frame from webcam with 
>VFW and create a UI thread, CEncThread, to encode the frame. The 
>OnCaptureVideo is invoked when the video frame is captured by the driver, 
>copy the frame data into global frame memory, and send a message to tell the 
>CEncThread to encode:
>========================================
>if (g_bFrameCopied == false) {
>      memcpy(g_szFrame, captureframe, size);
>      g_nFrameLength = size;
>      g_bFrameCopied = true;
****
THis suggests you are using global variables to communicate with the thread.  This should
be considered a Really Bad Idea.  Since you have to copy anyway, why not copy to heap
memory, pass a pointer to this in via the WPARAM or LPARAM, and avoid the copy at the
target?
****
>
>      ::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
>========================================
>The CEncThread will copy the video frame from global memory into local 
>memory and encode it with jpeg2000 codec:
>========================================
>   if (g_bFrameCopied == true) {
>      memcpy(s_szFrame, g_szFrame, g_nFrameLength);
>      g_bFrameCopied = false;
>   }
>  m_Encode.CreateFromArray((unsigned char *)g_szFrame, FRAME_WIDTH, 
>FRAME_HEIGHT, 8, FRAME_WIDTH, false);
>   m_Encode.SetJpegQuality(10);
>   m_Encode.Encode(buffer,len,CXIMAGE_FORMAT_JP2);  
>========================================
>After closing the program, I get an error at this statement:
>========================================
>::PostThreadMessage(m_pEncThread->m_nThreadID, WM_ENCODE_FRAME, 0, 0);
*****
THis seems a clumsy way to implement
	m_pEncThread->PostThreadMessage(WM_ENCODE);
why are you going for the raw API?
*****
>========================================
>I think that there maybe a few messages that invoke video callback function 
>in message queue after stopping the capturing process and disable the 
>callback function. So, It still calls PostThreadMessage to tell CEncThread to 
>work after CEncThread is closed. I want to know how to clear the message 
>queue???
****
You did not get "an error".  You got a VERY SPECIFIC ERROR, such as an access fault,
assertion failure, etc.  In addition, you were told the line on which this occurred, and
you could use the debugger to determine the values of the variables involved.  Lacking all
this critical information, all we can say is that you have done something wrong and should
fix it.

Note that it is your responsibility to terminate the thread cleanly, and your
responsibility to see that the thread does not attempt to send messages to nonexist
windows and that you do not attempt to post messages to nonexistent threads.  This is just
a guess based on typical examples of such problems.
*****
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
Reply newcomer (15982) 3/19/2007 5:16:16 PM

"Joseph M. Newcomer" wrote:

> See below
> On Mon, 19 Mar 2007 07:10:38 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:
> 
> ****
> THis suggests you are using global variables to communicate with the thread.  This should
> be considered a Really Bad Idea.  Since you have to copy anyway, why not copy to heap
> memory, pass a pointer to this in via the WPARAM or LPARAM, and avoid the copy at the
> target?
> ****
That 's a good idea. Thank you.
So, I dynamically allocate a heap memory, copy the frame to heap, and pass 
the pointer to encoding thread wia the WPARAM or LPARAM. 
Encoding thread gets the pointer, encodes the frame pointered by pointer, 
and finally release the heap memory. Right???
> *****
> THis seems a clumsy way to implement
> 	m_pEncThread->PostThreadMessage(WM_ENCODE);
> why are you going for the raw API?
> *****
Sorry, I don't know what's meaning of "the raw API". 
Could you explain more?
> ****
> You did not get "an error".  You got a VERY SPECIFIC ERROR, such as an access fault,
> assertion failure, etc.  In addition, you were told the line on which this occurred, and
> you could use the debugger to determine the values of the variables involved.  Lacking all
> this critical information, all we can say is that you have done something wrong and should
> fix it.

0
Reply mmlabjs (29) 3/20/2007 2:35:13 AM


"Joseph M. Newcomer" wrote:

> See below
> On Mon, 19 Mar 2007 07:10:38 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:
> 
> >Hi,
> >I create a dialog-based application. I capture video frame from webcam with 
> >VFW and create a UI thread, CEncThread, to encode the frame. The 
> >OnCaptureVideo is invoked when the video frame is captured by the driver, 
> >copy the frame data into global frame memory, and send a message to tell the 
> >CEncThread to encode:
> >========================================
> >if (g_bFrameCopied == false) {
> >      memcpy(g_szFrame, captureframe, size);
> >      g_nFrameLength = size;
> >      g_bFrameCopied = true;
> ****
> THis suggests you are using global variables to communicate with the thread.  This should
> be considered a Really Bad Idea.  Since you have to copy anyway, why not copy to heap
> memory, pass a pointer to this in via the WPARAM or LPARAM, and avoid the copy at the
> target?
> ****
I capture frame from webcam and encode it with JPEG2000, repeatedly. 
Callback function copies the frame into global memory and notifies the 
CEncThread to process it. In order to reduce the time that CEncThread lock 
the global memory, I copy the global memory into its local memory, and unlock 
the global memory. CEncThread can process it, at the same time, callback 
function can also copies the frame into global memory and again post the 
thread message in CEncThread's message queue. Because the speed of encoding a 
frame is slow than the callback function notifies the CEncThread, I think 
there maybe a few WM_ENCODE_FRAME messages in CEncThread's message queue.
0
Reply mmlabjs (29) 3/20/2007 3:36:05 AM

See below...
On Mon, 19 Mar 2007 19:35:13 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:

>"Joseph M. Newcomer" wrote:
>
>> See below
>> On Mon, 19 Mar 2007 07:10:38 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:
>> 
>> ****
>> THis suggests you are using global variables to communicate with the thread.  This should
>> be considered a Really Bad Idea.  Since you have to copy anyway, why not copy to heap
>> memory, pass a pointer to this in via the WPARAM or LPARAM, and avoid the copy at the
>> target?
>> ****
>That 's a good idea. Thank you.
>So, I dynamically allocate a heap memory, copy the frame to heap, and pass 
>the pointer to encoding thread wia the WPARAM or LPARAM. 
>Encoding thread gets the pointer, encodes the frame pointered by pointer, 
>and finally release the heap memory. Right???
****
Right.  See my essay on worker threads on my MVP Tips site.
****
>> *****
>> THis seems a clumsy way to implement
>> 	m_pEncThread->PostThreadMessage(WM_ENCODE);
>> why are you going for the raw API?
>> *****
>Sorry, I don't know what's meaning of "the raw API". 
>Could you explain more?
****
You can use MFC methods for many window operations.  MFC is a library built on top of the
WIndows API.  For those things which MFC defines, there is very little reason to use the
Windows API methods;  So there is a PostThreadMessage of the CWinThread class which
already does what you want, but instead of using the method, you call the raw API
function, and consequently have to provide all the parameters which the method call
automatically provides for you.
*****
>> ****
>> You did not get "an error".  You got a VERY SPECIFIC ERROR, such as an access fault,
>> assertion failure, etc.  In addition, you were told the line on which this occurred, and
>> you could use the debugger to determine the values of the variables involved.  Lacking all
>> this critical information, all we can say is that you have done something wrong and should
>> fix it.
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
Reply newcomer (15982) 3/21/2007 1:35:58 AM

See below...
On Mon, 19 Mar 2007 20:36:05 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:

>
>
>"Joseph M. Newcomer" wrote:
>
>> See below
>> On Mon, 19 Mar 2007 07:10:38 -0700, mmlab_js <mmlabjs@discussions.microsoft.com> wrote:
>> 
>> >Hi,
>> >I create a dialog-based application. I capture video frame from webcam with 
>> >VFW and create a UI thread, CEncThread, to encode the frame. The 
>> >OnCaptureVideo is invoked when the video frame is captured by the driver, 
>> >copy the frame data into global frame memory, and send a message to tell the 
>> >CEncThread to encode:
>> >========================================
>> >if (g_bFrameCopied == false) {
>> >      memcpy(g_szFrame, captureframe, size);
>> >      g_nFrameLength = size;
>> >      g_bFrameCopied = true;
>> ****
>> THis suggests you are using global variables to communicate with the thread.  This should
>> be considered a Really Bad Idea.  Since you have to copy anyway, why not copy to heap
>> memory, pass a pointer to this in via the WPARAM or LPARAM, and avoid the copy at the
>> target?
>> ****
>I capture frame from webcam and encode it with JPEG2000, repeatedly. 
>Callback function copies the frame into global memory and notifies the 
>CEncThread to process it. In order to reduce the time that CEncThread lock 
>the global memory, I copy the global memory into its local memory, and unlock 
>the global memory. CEncThread can process it, at the same time, callback 
>function can also copies the frame into global memory and again post the 
>thread message in CEncThread's message queue. Because the speed of encoding a 
>frame is slow than the callback function notifies the CEncThread, I think 
>there maybe a few WM_ENCODE_FRAME messages in CEncThread's message queue.
****
Which is why it doesn't make any sense to use global memory or locks at all.  If you
allocate a block, you fill it, hand it off to the thread, allocate a new block and fill
it, and no locks at all are necessary!  Lock-free algorithms tend to be better mechanism
than using locks (yes, there's an implicit lock on the allocator, but it is a very quick
lock)
					joe

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
Reply newcomer (15982) 3/21/2007 1:40:04 AM

7 Replies
213 Views

(page loaded in 0.08 seconds)


Reply: