directshow播放器 directshow消息

时间:2022-12-14 17:47:59

directshow中有很多消息时间,DirectShow中,也有时间通知的消息机制;

但是在一般情况中,会直接用IMediaEvent接口获取事件,我们可以再线程中获取;

在帮助文档中可以参考Learning When an Event Occurs;


示例:


DWORD WINAPI ThreadFuncVideo ( LPVOID lpParam ) 

IMediaEvent * pEvent = (IMediaEvent*)lpParam;


HANDLE  hEvent; 
long    evCode, param1, param2;
BOOLEAN bDone = FALSE;
HRESULT hr = S_OK;
hr = pEvent->GetEventHandle((OAEVENT*)&hEvent);


while(!bDone) 
{
if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 100))

while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr)) 
{
pEvent->FreeEventParams(evCode, param1, param2);

                                if (EC_DEVICE_LOST == evCode) //获取消息;
{
AfxMessageBox(CString("EC_DEVICE_LOST"));

return 0;

}
 
}
}



return 0; 
}








上面简单讲解了消息,下面写一个directshow的播放器:

class CVideoPlay
{
public:
CVideoPlay( CWnd * wnd )
{


pGraph = NULL;


pControl = NULL;  
pEvent = NULL; 
pVidWin = NULL;


hr=0;


pWnd = wnd;




}


~CVideoPlay()
{
stop();
}




public:
IGraphBuilder *pGraph ;


IMediaControl *pControl  ;  
IMediaEvent   *pEvent ;


IVideoWindow *pVidWin ;


CWnd         * pWnd;



HRESULT hr;


public:
int Play( CString strfile  )
{
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
IID_IGraphBuilder, (void **)&pGraph);    if (FAILED(hr))


{       
printf("ERROR - Could not create the Filter Graph Manager.");


return 0;   
}


hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
hr = pGraph->RenderFile(strfile, NULL);  
hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);




pVidWin->put_Owner((OAHWND)(pWnd->GetSafeHwnd()));
pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
CRect grc;
pWnd->GetClientRect(&grc);
pVidWin->SetWindowPosition(0, 0, /*grc.right*/100, /*grc.bottom*/100);




if (SUCCEEDED(hr))
{  
hr = pControl->Run();
if (!SUCCEEDED(hr))     

stop();


return 0;
}





//AfxBeginThread( threadEV, this );
{
DWORD dwThreadId, dwThrdParam = 1; 
HANDLE hThread; 
char szMsg[80];


hThread = CreateThread( 
NULL,                        // no security attributes 
0,                           // use default stack size  
threadEV,                  // thread function 
this,                      // argument to thread function 
0,                           // use default creation flags 
&dwThreadId);                // returns the thread identifier 


CloseHandle( hThread );




}


return 1;


}




void stop()
{
if (pControl)
{
pControl->Pause();
pControl->Stop();


if (pVidWin)
{
pVidWin->put_Visible(OAFALSE);
pVidWin->put_Owner(NULL);  
}
}


if (pGraph)
{
pControl->Release();


pEvent->Release();
pGraph->Release(); 
pVidWin->Release();


pControl = NULL;
pEvent = NULL;
pGraph = NULL;
pVidWin = NULL;


while(m_threadok == 0)
{
Sleep(10);
}


}


}








public:

int m_threadok;


private:
UINT EV()
{
m_threadok = 0;




HANDLE  hEvent; 
long    evCode, param1, param2;
BOOLEAN bDone = FALSE;
HRESULT hr = S_OK;
hr = pEvent->GetEventHandle((OAEVENT*)&hEvent);
if (FAILED(hr) )
{
/* Insert failure-handling code here. */
}
while( !bDone && pEvent && pControl) 
{
if (WAIT_OBJECT_0 == WaitForSingleObject(hEvent, 10) )

if (pEvent == NULL)
{
break;
}


while ( hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr) ) 
{
if (pEvent==NULL)
{
break;
}


OutputDebugStringA("pEvent && ");
printf("Event code: %#04x\n Params: %d, %d\n", evCode, param1, param2);
pEvent->FreeEventParams(evCode, param1, param2);
bDone = (EC_COMPLETE == evCode);
}
}





if (pControl==NULL)
{
AfxMessageBox( CString("播放退出") );


//播放退出;
}
else
{
//播放完成;
AfxMessageBox( CString("播放完成") );
}


 


m_threadok = 1;


return 0;


}


public:
static DWORD WINAPI  threadEV( PVOID pParam )
{
CVideoPlay * play = (CVideoPlay*)pParam;


play->EV();


return 0;
}




};