no crap only codes
1
class
CCaptureVideo :
public
CWnd
2
{
3
friend
class
CSampleGrabberCB;
4
public
:
5
void
GrabOneFrame(BOOL bGrab,
const
CString
&
szFileName);
6
HRESULT Init(
int
iDeviceID,HWND hWnd);
7
int
EnumDevices(HWND hList);
8
CCaptureVideo();
9
virtual
~
CCaptureVideo();
10
private
:
11
HWND m_hWnd;
12
IGraphBuilder
*
m_pGB;
13
ICaptureGraphBuilder2
*
m_pCapture;
14
IBaseFilter
*
m_pBF;
15
IMediaControl
*
m_pMC;
16
IMediaEventEx
*
m_pME;
17
IVideoWindow
*
m_pVW;
18
CComPtr
<
ISampleGrabber
>
m_pGrabber;
19
protected
:
20
void
FreeMediaType(AM_MEDIA_TYPE
&
mt);
21
bool
BindFilter(
int
deviceId, IBaseFilter
**
pFilter);
22
void
ResizeVideoWindow();
23
HRESULT SetupVideoWindow();
24
HRESULT InitCaptureGraphBuilder();
25
}
;
1
2
class
CSampleGrabberCB :
public
ISampleGrabberCB
3
{
4
public
:
5
long
lWidth;
6
long
lHeight;
7
static
CString m_szFileName;
//
位图文件名称
8
CSampleGrabberCB( )
9
{
10
}
11
12
STDMETHODIMP_(ULONG) AddRef()
13
{
return
2
; }
14
15
STDMETHODIMP_(ULONG) Release()
16
{
return
1
; }
17
18
STDMETHODIMP QueryInterface(REFIID riid,
void
**
ppv)
19
{
20
if
( riid
==
IID_ISampleGrabberCB
||
riid
==
IID_IUnknown )
21
{
22
*
ppv
=
(
void
*
) static_cast
<
ISampleGrabberCB
*>
(
this
);
23
return
NOERROR;
24
}
25
return
E_NOINTERFACE;
26
}
27
28
STDMETHODIMP SampleCB(
double
SampleTime, IMediaSample
*
pSample )
29
{
30
return
0
;
31
}
32
33
STDMETHODIMP BufferCB(
double
dblSampleTime, BYTE
*
pBuffer,
long
lBufferSize )
34
{
35
if
(
!
bOneShot )
return
0
;
36
37
if
(
!
pBuffer)
38
return
E_POINTER;
39
40
if
(SaveBitmap(pBuffer, lBufferSize))
41
{
42
//
notify has create a bitmap file;
43
CGlobalData::m_pMainView
->
HasSavedPhoto(m_szFileName);
44
}
45
46
bOneShot
=
FALSE;
47
48
49
return
0
;
50
}
51
//
创建位图文件
52
BOOL SaveBitmap(BYTE
*
pBuffer,
long
lBufferSize )
53
{
54
HANDLE hf
=
CreateFile(
55
m_szFileName,
56
GENERIC_WRITE, FILE_SHARE_READ, NULL,
57
CREATE_ALWAYS,
58
NULL,
59
NULL );
60
61
if
( hf
==
INVALID_HANDLE_VALUE )
62
return
FALSE;
63
64
//
写文件头
65
BITMAPFILEHEADER bfh;
66
memset(
&
bfh,
0
,
sizeof
( bfh ) );
67
bfh.bfType
=
'
MB
'
;
68
bfh.bfSize
=
sizeof
( bfh )
+
lBufferSize
+
sizeof
( BITMAPINFOHEADER );
69
bfh.bfOffBits
=
sizeof
( BITMAPINFOHEADER )
+
sizeof
( BITMAPFILEHEADER );
70
DWORD dwWritten
=
0
;
71
WriteFile( hf,
&
bfh,
sizeof
( bfh ),
&
dwWritten, NULL );
72
73
//
写位图格式
74
BITMAPINFOHEADER bih;
75
memset(
&
bih,
0
,
sizeof
( bih ) );
76
bih.biSize
=
sizeof
( bih );
77
bih.biWidth
=
lWidth;
78
bih.biHeight
=
lHeight;
79
bih.biPlanes
=
1
;
80
bih.biBitCount
=
24
;
81
WriteFile( hf,
&
bih,
sizeof
( bih ),
&
dwWritten, NULL );
82
83
//
写位图数据
84
WriteFile( hf, pBuffer, lBufferSize,
&
dwWritten, NULL );
85
86
CloseHandle( hf );
87
88
return
TRUE;
89
}
90
}
;
/**/
/////////////////////////////////////////////////////////////////////
/
//
Construction/Destruction
/**/
/////////////////////////////////////////////////////////////////////
/
CCaptureVideo::CCaptureVideo()

{
m_pBF
=
0
;
m_hWnd
=
NULL;
m_pVW
=
NULL;
m_pMC
=
NULL;
m_pME
=
NULL;
m_pGB
=
NULL;
m_pCapture
=
NULL;
}
CCaptureVideo::
~
CCaptureVideo()

{
//
Stop media playback
if
(m_pMC)
m_pMC
->
StopWhenReady();
//
Stop receiving events
if
(m_pME)
m_pME
->
SetNotifyWindow(NULL, WM_GRAPHNOTIFY,
0
);


if
(m_pVW)
{
m_pVW
->
put_Visible(OAFALSE);
m_pVW
->
put_Owner(NULL);
}
SAFE_RELEASE(m_pMC);
SAFE_RELEASE(m_pME);
SAFE_RELEASE(m_pVW);
SAFE_RELEASE(m_pGB);
SAFE_RELEASE(m_pBF);
SAFE_RELEASE(m_pCapture);
//
CoUninitialize( );
}
int
CCaptureVideo::EnumDevices(HWND hList)

{
if
(
!
hList)
return
-
1
;
int
id
=
0
;
//
枚举视频扑捉设备
ICreateDevEnum
*
pCreateDevEnum;
HRESULT hr
=
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (
void
**
)
&
pCreateDevEnum);
if
(hr
!=
NOERROR)
return
-
1
;
CComPtr
<
IEnumMoniker
>
pEm;
hr
=
pCreateDevEnum
->
CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&
pEm,
0
);
if
(hr
!=
NOERROR)
return
-
1
;
pEm
->
Reset();
ULONG cFetched;
IMoniker
*
pM;
while
(hr
=
pEm
->
Next(
1
,
&
pM,
&
cFetched), hr
==
S_OK)

{
IPropertyBag
*
pBag;
hr
=
pM
->
BindToStorage(
0
,
0
, IID_IPropertyBag, (
void
**
)
&
pBag);
if
(SUCCEEDED(hr))

{
VARIANT var;
var.vt
=
VT_BSTR;
hr
=
pBag
->
Read(L
"
FriendlyName
"
,
&
var, NULL);
if
(hr
==
NOERROR)

{
TCHAR str[
2048
];
id
++
;
WideCharToMultiByte(CP_ACP,
0
,var.bstrVal,
-
1
, str,
2048
, NULL, NULL);
::SendMessage(hList, CB_ADDSTRING,
0
,(LPARAM)str);
SysFreeString(var.bstrVal);
}
pBag
->
Release();
}
pM
->
Release();
}
return
id;
}
HRESULT CCaptureVideo::Init(
int
iDeviceID, HWND hWnd)

{
HRESULT hr;
hr
=
InitCaptureGraphBuilder();

if
(FAILED(hr))
{
AfxMessageBox(
"
Failed to get video interfaces!
"
);
return
hr;
}
//
Bind Device Filter. We know the device because the id was passed in
if
(
!
BindFilter(iDeviceID,
&
m_pBF))
return
S_FALSE;
hr
=
m_pGB
->
AddFilter(m_pBF, L
"
Video Capture
"
);
if
(FAILED(hr))

{
m_pBF
->
Release();
return
hr;
}
//
create a sample grabber
hr
=
m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );

if
(
!
m_pGrabber )
{
AfxMessageBox(
"
Fail to create SampleGrabber, maybe qedit.dll is not registered?
"
);
return
hr;
}
CComQIPtr
<
IBaseFilter,
&
IID_IBaseFilter
>
pGrabBase( m_pGrabber );
//
设置视频格式
AM_MEDIA_TYPE mt;
ZeroMemory(
&
mt,
sizeof
(AM_MEDIA_TYPE));
mt.majortype
=
MEDIATYPE_Video;
mt.subtype
=
MEDIASUBTYPE_RGB24;
hr
=
m_pGrabber
->
SetMediaType(
&
mt);

if
( FAILED( hr ) )
{
AfxMessageBox(
"
Fail to set media type!
"
);
return
hr;
}
hr
=
m_pGB
->
AddFilter( pGrabBase, L
"
Grabber
"
);

if
( FAILED( hr ) )
{
AfxMessageBox(
"
Fail to put sample grabber in graph
"
);
return
hr;
}
//
try to render preview/capture pin
hr
=
m_pCapture
->
RenderStream(
&
PIN_CATEGORY_PREVIEW,
&
MEDIATYPE_Video,m_pBF,pGrabBase,NULL);
if
( FAILED( hr ) )
hr
=
m_pCapture
->
RenderStream(
&
PIN_CATEGORY_CAPTURE,
&
MEDIATYPE_Video,m_pBF,pGrabBase,NULL);

if
( FAILED( hr ) )
{
AfxMessageBox(
"
Can’t build the graph
"
);
return
hr;
}
hr
=
m_pGrabber
->
GetConnectedMediaType(
&
mt );

if
( FAILED( hr) )
{
AfxMessageBox(
"
Failt to read the connected media type
"
);
return
hr;
}
VIDEOINFOHEADER
*
vih
=
(VIDEOINFOHEADER
*
) mt.pbFormat;
mCB.lWidth
=
vih
->
bmiHeader.biWidth;
mCB.lHeight
=
vih
->
bmiHeader.biHeight;
FreeMediaType(mt);
hr
=
m_pGrabber
->
SetBufferSamples( FALSE );
hr
=
m_pGrabber
->
SetOneShot( FALSE );
hr
=
m_pGrabber
->
SetCallback(
&
mCB,
1
);
//
设置视频捕捉窗口
m_hWnd
=
hWnd ;
SetupVideoWindow();

hr
=
m_pMC
->
Run();
//
开始视频捕捉
if
(FAILED(hr))

{
AfxMessageBox(
"
Couldn’t run the graph!
"
);
return
hr;
}
return
S_OK;
}
bool
CCaptureVideo::BindFilter(
int
deviceId, IBaseFilter
**
pFilter)

{
if
(deviceId
<
0
)
return
false
;
IBaseFilter
*
pSrc
=
NULL;
//
enumerate all video capture devices
CComPtr
<
ICreateDevEnum
>
pCreateDevEnum
=
NULL;
HRESULT hr
=
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (
void
**
)
&
pCreateDevEnum);
if
(FAILED(hr))

{
return
false
;
}
CComPtr
<
IEnumMoniker
>
pEm
=
NULL;
hr
=
pCreateDevEnum
->
CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&
pEm,
0
);
if
(FAILED(hr))

{
return
false
;
}
//
pEm->Reset();
ULONG cFetched;
IMoniker
*
pM;
int
index
=
0
;
while
(S_OK
==
(pEm
->
Next(
1
,
&
pM,
&
cFetched))
&&
index
<=
deviceId)

{
IPropertyBag
*
pBag;
hr
=
pM
->
BindToStorage(
0
,
0
, IID_IPropertyBag, (
void
**
)
&
pBag);
if
(SUCCEEDED(hr))

{
VARIANT var;
var.vt
=
VT_BSTR;
hr
=
pBag
->
Read(L
"
FriendlyName
"
,
&
var, NULL);
if
(hr
==
NOERROR)

{
if
(index
==
deviceId)

{
pM
->
BindToObject(
0
,
0
, IID_IBaseFilter, (
void
**
)
&
pSrc);
}
SysFreeString(var.bstrVal);
}
pBag
->
Release();
}
pM
->
Release();
index
++
;
}
*
pFilter
=
pSrc;
return
true
;
}
HRESULT CCaptureVideo::InitCaptureGraphBuilder()

{
HRESULT hr;
//
创建IGraphBuilder接口
hr
=
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (
void
**
)
&
m_pGB);
if
(FAILED(hr))
return
hr;

//
创建ICaptureGraphBuilder2接口
hr
=
CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (
void
**
)
&
m_pCapture);
if
(FAILED(hr))
return
hr;

m_pCapture
->
SetFiltergraph(m_pGB);
hr
=
m_pGB
->
QueryInterface(IID_IMediaControl, (
void
**
)
&
m_pMC);
if
(FAILED(hr))
return
hr;

hr
=
m_pGB
->
QueryInterface(IID_IVideoWindow, (LPVOID
*
)
&
m_pVW);
if
(FAILED(hr))
return
hr;

hr
=
m_pGB
->
QueryInterface(IID_IMediaEvent, (LPVOID
*
)
&
m_pME);
if
(FAILED(hr))
return
hr;

//
Set the window handle used to process graph events
hr
=
m_pME
->
SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY,
0
);

return
hr;
}
HRESULT CCaptureVideo::SetupVideoWindow()

{
HRESULT hr;
hr
=
m_pVW
->
put_Owner((OAHWND)m_hWnd);
if
(FAILED(hr))
return
hr;

hr
=
m_pVW
->
put_WindowStyle(WS_CHILD
|
WS_CLIPCHILDREN);
if
(FAILED(hr))
return
hr;

ResizeVideoWindow();
hr
=
m_pVW
->
put_Visible(OATRUE);

return
hr;
}
void
CCaptureVideo::ResizeVideoWindow()

{

if
(m_pVW)
{
//
让图像充满整个窗口
CRect rc;
::GetClientRect(m_hWnd,
&
rc);
m_pVW
->
SetWindowPosition(
0
,
0
, rc.right, rc.bottom);
}
}
void
CCaptureVideo::GrabOneFrame(BOOL bGrab,
const
CString
&
szFileName)

{
bOneShot
=
bGrab;
CSampleGrabberCB::m_szFileName
=
szFileName;
}
void
CCaptureVideo::FreeMediaType(AM_MEDIA_TYPE
&
mt)

{

if
(mt.cbFormat
!=
0
)
{
CoTaskMemFree((PVOID)mt.pbFormat);
//
Strictly unnecessary but tidier
mt.cbFormat
=
0
;
mt.pbFormat
=
NULL;
}
if
(mt.pUnk
!=
NULL)
{
mt.pUnk
->
Release();
mt.pUnk
=
NULL;
}
}
posted on 2006-11-12 14:10
力为 阅读(895)
评论(0) 编辑 收藏 引用 所属分类:
C++ Practice