力为的技术博客
联系
聚合
管理
154 Posts :: 1 Stories :: 561 Comments :: 0 Trackbacks
公告
@上海浦东
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(58)
给我留言
查看公开留言
查看私人留言
随笔分类
(154)
2. Graphics(10)
3. VC&MFC&Qt(35)
4. C++ FAQ(35)
5. GP&STL&BOOST(10)
6. COM&ATL&WTL(5)
7. OGRE Analysis(14)
8. ACIS/HOOPS(4)
9.OpenCASCADE(13)
Mac&iOS(5)
Mac&iOS(1)
Tools(22)
积分与排名
积分 - 702991
排名 - 22
最新评论
1. re: 2015武汉校园招聘归来
@eryar
时间安排的太紧,就没有惊扰你啦。
--力为
2. re: 2015武汉校园招聘归来
评论内容较长,点击标题查看
--sunyuanbo
3. re: 2015武汉校园招聘归来
谢谢 您的笔记让我受益匪浅
--仝锡林
4. re: 2015武汉校园招聘归来
不知道来武汉了啊!
--eryar
5. re: 2015武汉校园招聘归来
@力为
谢谢提醒,还在学习中。。。
--编程小学徒
6. re: 2015武汉校园招聘归来
评论内容较长,点击标题查看
--编程小学徒
7. re: 2015武汉校园招聘归来[未登录]
评论内容较长,点击标题查看
--chipset
8. re: 2015武汉校园招聘归来
@编程小学徒
考研也不仅仅靠有编程兴趣就够了,还有其他的课程。好好准备吧,祝考试顺利。
--力为
9. re: 2015武汉校园招聘归来
评论内容较长,点击标题查看
--编程小学徒
10. re: 2015武汉校园招聘归来[未登录]
为了混口饭吃,大家都不容易啊,原谅刷题的同学吧。话说学校里能教啥呀,都靠自己用心,有上进心才是最重要的,否则笔试面试再好也是白扯。从面试官的角度看考试没有错,换成我会找有潜力的或者上进心强的。
--chipset
11. re: 【代码】使用Teigha读取DWG
要用vs2010编译么?
--jj
12. re: 临时对象引用[未登录]
最后一个例子也是零时变量?
--zhonghuajia
13. re: 为什么需要给函数返回类型加const
评论内容较长,点击标题查看
--冬瓜
14. re: 【代码】使用Teigha读取DWG
欢迎加入QQ群122751318,讨论Teigha
--Teigha开发
15. re: CMake + Qt5.1.0
@MIKE
还是不行。
不管是prefix还是library还是include,都尝试过了,不行,网上的方法都不行……
--Delbert
评论排行榜
1. Pro OGRE 3D Programming 电子版(54)
2. 手机号码黑名单(53)
3. 屏幕截图工具V1[附源码](22)
4. 波形显示不是很难(15)
5. 五个小矮人分桃子-一道小学生的作业题目(15)
6. 用CImage加载内存里的Image(14)
7. 用istringstream 解决问题一则(14)
8. OGRE动画练习(13)
9. VC+ADO操作数据库注意事项(1)(13)
10. fstream 和 中文路径(13)
11. OGRE粒子系统之在烈火中永生(11)
12. 如何通过FILE*操作内存文件?(11)
13. VC2008 Feature Pack的问题(11)
14. 升级到 VS2008 SP1 注意问题(11)
15. 失足于shared_ptr(11)
A Class Capturing Video by DShow
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
力为
阅读(1480)
评论(0)
编辑
收藏
引用
所属分类:
Tools
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
Perforce的shelved 命令
我的原创技术随笔大全(2000~2009)
Vista 远程连接设置
Boost.Python与C++互操作的问题(更新)
STL容器误用一则
运算符 && 和 ||
[Debug] 解决图形没有显示的问题
屏幕截图工具V2
VC2008 竟然不带 glaux.lib!
用wxWidgets做界面
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © 力为