My goal is to use DirectShow to play media files (AVI, MPEG etc) and get the
video samples/frames one by one.
Question 1: How to associate DirectShow with DirectDraw?
Unfortunately CE doesn't support the powerful IAMMultiMediaStream interface,
things got complicated than I expected. DirectDraw let us have hands on the
video data, so I was thinking to play video file with DirectShow and get the
video
data in DirectDraw surface. However, how can I associate DirectShow with
DirectDraw? The only way I saw is in the example
c:\wince420\public\directx\sdk\samples\dshow\players\ddxclmv:
IDDrawExclModeVideo *pDDXM ;
hr = pOvM->QueryInterface(IID_IDDrawExclModeVideo, (LPVOID *)&pDDXM) ;
...
hr = pDDXM->SetDDrawObject(pDDObj) ;
but i don't think that it works for me since:
. The program doesn't work on my embedded board
. I don't need Direct Draw Exclusive Mode Video
. None of the official documents states that CE supports Direct Draw
Exclusive Mode Video
Does any one know how to associate DirectShow with DirectDraw easily?
Question 2: How to get frames one by one?
It seems I can only use IMediaControl to render a media file, but after i
triggered media playing with IMediaControl::Run, I lost control of get
samples/frames one by one because IMediaControl doesn't have an Update()
method. My solution is to get the samples under the control of a timer. Does
anyone has a better solution?
Question 3: Is customized filter a solution?
Actually, I don't need DirectShow to render media file to video buffer. I
will use sample data in somewhere else. So another idea is to replace the
"video render" by my own customized filter. In this way, I may not need
DirectDraw anymore. Do you think it is feasible? Is it difficult to
implement the filter and connect it to the filter graph?
Thanks in advance,
Steven Duan
HRESULT CDsPlayerCtrl::GetInterfaces(void)
{
HRESULT hr;
// USES_CONVERSION;
// WCHAR wFilterName[MAX_PATH];
// CString csFilterName;
// IIPEffect *pEzeff
CoInitialize(NULL);;
m_psCurrent = Initializing;
FireStatusChange();
// Create the filter graph
JIF(CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **) &pGB));
m_filterGraph = pGB;
// Convert filename to wide character string
// csFilterName = "Image Effects (EZRGB24)";
// wcsncpy(wFilterName, T2W(csFilterName), NUMELMS(wFilterName)-1);
// wFilterName[MAX_PATH-1] = 0;
hr = CoCreateInstance(CLSID_EZrgb24, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)&pEZ);
hr = CoCreateInstance(CLSID_ColorSpace, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **)&pCSC);
if (m_effectsEnabled)
{
hr = pGB->AddFilter(pEZ, L"Image Effects (EZRGB24)");
hr = pGB->AddFilter(pCSC, L"Color Space Convereter 0002");
}
// QueryInterface for DirectShow interfaces
// Query for video interfaces, which may not be relevant for audio files
JIF(pGB->QueryInterface(IID_IVideoWindow, (void **)&pVW));
JIF(pGB->QueryInterface(IID_IBasicVideo, (void **)&pBV));
// Query for audio interfaces, which may not be relevant for video-only
files
JIF(pGB->QueryInterface(IID_IBasicAudio, (void **)&pBA));
// Query for Media Control Interfaces
JIF(pGB->QueryInterface(IID_IMediaControl, (void **)&pMC));
JIF(pGB->QueryInterface(IID_IMediaEventEx, (void **)&pME));
JIF(pGB->QueryInterface(IID_IMediaSeeking, (void **)&pMS));
JIF(pGB->QueryInterface(IID_IMediaPosition, (void **)&pMP));
// Set the window handle used to process graph events
JIF(pME->SetNotifyWindow((OAHWND)this->m_hWnd, WM_GRAPHNOTIFY, 0));
#ifdef REGISTER_FILTERGRAPH
hr = AddGraphToRot(pGB, &m_dwGraphRegister);
if (FAILED(hr))
{
m_LastError.Format(TEXT("Failed to register filter graph with
ROT! hr=0x%x"), hr);
m_dwGraphRegister = 0;
}
#endif
CoUninitialize();
m_psCurrent = Ready;
FireStatusChange();
return hr;
}
void CDsPlayerCtrl::CloseInterfaces(void)
{
#ifdef REGISTER_FILTERGRAPH
if (m_dwGraphRegister)
{
RemoveGraphFromRot(m_dwGraphRegister);
m_dwGraphRegister = 0;
}
#endif
ReleaseVideoWindow();
if (pEZ) pGB->RemoveFilter(pEZ);
if (pCSC) pGB->RemoveFilter(pCSC);
SAFE_RELEASE(pEZ);
SAFE_RELEASE(pCSC);
// Release and zero DirectShow interfaces
SAFE_RELEASE(pME);
SAFE_RELEASE(pMS);
SAFE_RELEASE(pMP);
SAFE_RELEASE(pMC);
SAFE_RELEASE(pBA);
SAFE_RELEASE(pBV);
SAFE_RELEASE(pVW);
// SAFE_RELEASE(pFS);
SAFE_RELEASE(pGB);
m_filterGraph = pGB;
m_psCurrent = Uninitialized;
FireStatusChange();
}
void CDsPlayerCtrl::ReleaseVideoWindow(void)
{
HRESULT hr;
// Relinquish ownership (IMPORTANT!) after hiding video window
if(pVW)
{
pVW->put_Visible(OAFALSE);
pVW->put_Owner(NULL);
}
// Disable event callbacks
if (pME)
hr = pME->SetNotifyWindow((OAHWND)NULL, 0, 0);
}
HRESULT CDsPlayerCtrl::SetupVideoWindow(void)
{
HRESULT hr;
if ( pVW == NULL ) return -1;
// Set the video window to be a child of the main window
hr = pVW->put_Owner((OAHWND)this->m_hWnd);
if (FAILED(hr))
return hr;
// Set video window style
hr = pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if (FAILED(hr))
return hr;
// Use helper function to position video window in client rect
// of main application window
ResizeVideoWindow();
// Make the video window visible, now that it is properly positioned
hr = pVW->put_Visible(OATRUE);
if (FAILED(hr))
return hr;
// Set the window handle used to process graph events
JIF(pME->SetNotifyWindow((OAHWND)this->m_hWnd, WM_GRAPHNOTIFY, 0));
m_NeedResize = false;
return hr;
}
void CDsPlayerCtrl::ResizeVideoWindow(void)
{
// Resize the video preview window to match owner window size
if (pVW)
{
RECT rc, rc2;
// Make the preview video fill our window
GetClientRect(&rc);
pVW->GetWindowPosition(&rc2.left, &rc2.top, &rc2.right, &rc2.bottom);
if (memcmp(&rc, &rc2, sizeof(rc))!=0)
pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
}
BOOL CDsPlayerCtrl::OpenClip()
{
USES_CONVERSION;
WCHAR wFile[MAX_PATH];
CloseInterfaces();
GetInterfaces();
// Convert filename to wide character string
wcsncpy(wFile, T2W(m_FileName), NUMELMS(wFile)-1);
wFile[MAX_PATH-1] = 0;
// Have the graph builder construct its the appropriate graph automatically
if (FAILED(pGB->RenderFile(wFile, NULL)))
{
m_LastError = "File format unsupported!";
return FALSE;
}
SetupVideoWindow();
m_psCurrent = Stopped;
m_LastError = "OK";
FireStatusChange();
return TRUE;
}
BOOL CDsPlayerCtrl::Play()
{
HRESULT hr;
if (!pMC)
{
m_LastError = "Uninitialized!";
return FALSE;
}
if (FAILED((hr=pMC->Run())))
{
m_LastError.Format(TEXT("Failed(0x%08lx) to play media clip!\r\n"), hr);
return FALSE;
}
m_psCurrent = Running;
m_LastError = "OK";
FireStatusChange();
return TRUE;
}
BOOL CDsPlayerCtrl::CloseClip()
{
HRESULT hr;
// Stop media playback
if(pMC)
{
hr = pMC->Stop();
m_psCurrent = Stopped;
FireStatusChange();
}
// Free DirectShow interfaces
CloseInterfaces();
return TRUE;
}
"Steven Duan" <ste...@whiteway.com> wrote in message
news:unjyFenx...@TK2MSFTNGP09.phx.gbl...