// SzpVideo.cpp: implementation of the CSzpVideo class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
// for direct show
#include <streams.h>
#include <mtype.h>
#include "SzpVideo.h"
#include "../imagereadandwrite/visimage.h"
#include "../imagereadandwrite/featureextraction.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// CSzpVideo: The class handle the DirectShow graph building
//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Constructor : Init member variable and search for available devices
///////////////////////////////////////////////////////////////////////
CSzpVideo::CSzpVideo()
{
CoInitialize(NULL); // Init COM
m_pCaptureGraphBuilder2 = NULL;
m_pGraphBuilder = NULL;
m_pFilterGraph = NULL;
m_pMediaControl = NULL;
m_pVideoWindow = NULL;
m_pMediaSeeking = NULL;
m_pSrcFilter = NULL;
m_pRenderFilter = NULL;
//m_pBasicVideo = NULL; //shizp 2004.6.4
//m_pVideoFrameStep = NULL; //shizp 2004.6.4
m_TimeFormat = TIME_FORMAT_MEDIA_TIME;
m_hRenderWnd = NULL;
m_pCaptureSetting = NULL;
m_fIsScaling = false; // no scaling
m_fRegisterFilterGraph = true; // register for GraphEdt to view
m_dwGraphRegister = 0; // the register no. of the graph
m_wcMediaName[0] = '\0';
m_wcOutputFile[0] = '\0';
// enumerate all available video capture devices
m_nNumOfCapDev = 0;
HRESULT hr;
CComPtr<ICreateDevEnum> pCreateDevEnum;
CComPtr<IEnumMoniker> pEnumMoniker = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
if (FAILED(hr)) return; // no capture device enumerator
hr = pCreateDevEnum->
CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEnumMoniker, 0);
if (FAILED(hr) || !pEnumMoniker) return; // no capture device
// Search all available devices and save in m_pCapMonikers[]
ULONG cFetched;
// Note that if the Next() call succeeds but there are no monikers,
// it will return S_FALSE (which is not a failure). Therefore, we
// check that the return code is S_OK instead of using SUCCEEDED()
while (S_OK == pEnumMoniker->Next(1, m_pCapMonikers+m_nNumOfCapDev,
&cFetched))
m_nNumOfCapDev ++;
}
///////////////////////////////////////////////////////////////////////
// Deconstructor : Release all resources
///////////////////////////////////////////////////////////////////////
CSzpVideo::~CSzpVideo()
{
// Release the stored available capture device
for (int i = 0; i < m_nNumOfCapDev; i++)
SafeRelease(m_pCapMonikers[i]);
ReleaseFilterGraph(); // destroy the filter graph
CoUninitialize(); // release COM
}
///////////////////////////////////////////////////////////////////////
// SetRenderWindow: Set the window to display the video
// Auguments:
// hWnd: the display window handler
// pImgRect: display the video in the rectangle in window
// if NULL, display video in up-left conner (0, 0) at
// original video size
// return value: error code of set video window
///////////////////////////////////////////////////////////////////////
// Filter graph notification to the specified window
#define WM_GRAPHNOTIFY (WM_USER+20)
HRESULT CSzpVideo::SetRenderWindow(HWND hWnd, RECT * pImgRect)
{
m_hRenderWnd = hWnd; // set the render window
if (pImgRect == NULL)
// displaye video in original size at up-left corner.
m_fIsScaling = false, m_oVideoRect.left = m_oVideoRect.top = 0;
else
// Set the rect to display the video and mark the flag
m_oVideoRect = *pImgRect, m_fIsScaling = true;
//set video window shizp 2004.3.3
HRESULT hr = NULL;
if (m_hRenderWnd&&m_pVideoWindow) {
//shizp edit for maybe an audio only, if is audio only,
hr = (m_pVideoWindow->put_MessageDrain((OAHWND)m_hRenderWnd));
if(SUCCEEDED(hr)){
JIF(m_pVideoWindow->put_Owner((OAHWND)m_hRenderWnd));
JIF(m_pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS));//
// Set the display position
JIF(setVideoWindowSize());
m_pVideoWindow->put_Visible(OATRUE);
//hr = m_pVideoWindow->SetWindowForeground(-1);
}
}
// update the video window size
return S_OK;// setVideoWindowSize();
}
///////////////////////////////////////////////////////////////////////
// SetRenderWindow: Set the window to display the video
// Auguments:
// hWnd: the display window handler
// x, y: display in original size and up-left coner at (x, y)
// return value: error code of set video window
///////////////////////////////////////////////////////////////////////
HRESULT CSzpVideo::SetRenderWindow(HWND hWnd, int x, int y)
{
m_hRenderWnd = hWnd; // set the render window
m_fIsScaling = false; // no scaling
m_oVideoRect.left = x, m_oVideoRect.top = y;
//set video window shizp 2004.7.2
if (m_hRenderWnd&&m_pVideoWindow) {
//shizp edit for maybe an audio only, if is audio only,
HRESULT hr = (m_pVideoWindow->put_MessageDrain((OAHWND)m_hRenderWnd));
if(SUCCEEDED(hr)){
JIF(m_pVideoWindow->put_Owner((OAHWND)m_hRenderWnd));
JIF(m_pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN));//
// Set the display position
JIF(setVideoWindowSize());
m_pVideoWindow->put_Visible(OATRUE);
//hr = m_pVideoWindow->SetWindowForeground(-1);
}
}
// update the video window size
return S_OK;// setVideoWindowSize();
}
///////////////////////////////////////////////////////////////////////
// ReleaseFilterGraph : Release the whole graph
///////////////////////////////////////////////////////////////////////
void CSzpVideo::ReleaseFilterGraph()
{
// Destroy the whole filter graph
stopGraph();
SafeRelease( m_pMediaControl );
SafeRelease( m_pMediaSeeking );
SafeRelease( m_pSrcFilter );
SafeRelease( m_pRenderFilter );
SafeRelease( m_pVideoWindow );
SafeRelease( m_pFilterGraph );
SafeRelease( m_pGraphBuilder );
SafeRelease( m_pCaptureGraphBuilder2 );
}
///////////////////////////////////////////////////////////////////////
// RenderFile: Playback the given media file
// Auguments:
// vname: the name of the media file
// Return value: Error code of building playback graph
///////////////////////////////////////////////////////////////////////
HRESULT CSzpVideo::RenderFile(const TCHAR * vname)
{
// set the VideoSource to indicate we are play video file
m_nVideoSource = VideoFilePlayback;
// change the given file name to wide character in m_wcMediaName
USES_CONVERSION;
TCHAR tempVName[MAX_PATH];
_tcscpy(tempVName, vname);
wcscpy(m_wcMediaName, T2W(tempVName));
HRESULT hr;
// Create the essensial element of a video graph
JIF(createFilterGraph());
// Create seeking control to navigate through the video file
// May fail for live camera. (but no need to return even we fail)
hr = m_pGraphBuilder->QueryInterface(IID_IMediaSeeking,
(void**)&m_pMediaSeeking);
if (SUCCEEDED(hr)) {
/* hr = m_pMediaSeeking->SetTimeFormat(&TIME_FORMAT_FRAME);
if (SUCCEEDED(hr))
m_TimeFormat = TIME_FORMAT_FRAME;
*/ }
else