




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
C#實現(xiàn)DirectShow技術開發(fā)準備時間:2009-10-2123:45點擊:73次字體:[大中小]DirectShow組件在“C:WINDOWSsystem32”目錄下的Quartz.dll動態(tài)庫中,要使C#代碼引用COM對象和接口,必須將COM類型庫轉換為.NET框架元數(shù)據(jù),從而有效地創(chuàng)建一個可以從任何托管語言調用的托管包裝。在轉換過程中需要使用FrameWorkSDK自帶的TlbImp命令工具,該命令工具在“D:ProgramFilesMicrosoftVisualStudio8SDKv2.0BinTlbImp.exe”目錄下(取決于VisualStudio2005的安裝路徑)。該命令的使用方法為:TlbImpC:WINDOWSsystem32quartz.dllout:C:WINDOWSsystem32quartzDriectShow.dll在DOS命令下執(zhí)行轉換成功。轉換完成后需在應用程序引用quartzDriectShow,引用quartzDriectShow.dll組件步驟如下:(1)在VisualStudio2005開發(fā)環(huán)境中,選擇菜單“項目”/“添加引用”命令,彈出“添加引用”對話框。(2)選擇“瀏覽”選項卡,通過瀏覽找到引用quartzDriectShow.dll所在的位置,并引用到程序中來。(3)最后引入usingquartzDriectShow,在程序中可以開發(fā)相關多媒體程序了。開發(fā)人員還可以通過編寫自己的過濾器擴展DirectShow多媒體支持。下面是DirectShow組件的接口。lIFilterGraph:過濾通道接口。lIFilterGraph2:增強的IfilterGraph。lIGraphBuilder:最為重用的COM接口,用于手動或者自動構造過濾通道FilterGraphManager。lIMediaControl:用來控制流媒體(如流的啟動和停止暫停等)播放控制接口。lIMediaEvent:播放事件接口,該接口在FilterGraph發(fā)生一些事件時用來創(chuàng)建事件的標志信息并傳送給應用程序。lIMediaEventEx:擴展播放事件窗口。lIMediaPosition:播放的位置和速度控制接口(控制播放放置只能為設置時間控制方式)。lIMediaSeeking:另一個播放的位置和播放速度控制接口,在位置選擇方面功能較強,設置播放格式。常用的控制播放方式有:TIME_FORMAT_MEDIA_TIME單位100納秒;TIME_FORMAT_FRAME按幀播放。lIBasicAudio:聲音控制接口。lIBasicVideo:圖像控制接口(波特率,寬度,長度等信息)。lIVideoWindow:顯示窗口控制接口(有關播放窗口的一切控制,包括caption顯示,窗口位置控制等)。lISampleGrabber:捕獲圖像接口(可用于抓圖控制)。lIVideoFrameStep:控帛單幀播放的接口。注意:使用DirectShow接口編程有3個步驟:初始化接口→利用接口中的控制函數(shù)使用控制操作→最后釋放接口。原文來自:雨楓技術教程網(wǎng)http://www.fengfly.com原文網(wǎng)址:http://www.fengfly.com/plus/view-140098-1.html一個用C#開發(fā)的DirectShow媒體播放器(作者:DanielStrigl)關鍵字:一個用C#開發(fā)的DirectShow媒體播放器(作者:DanielStrigl)按"Browse..."選擇DirectShowCOMDLL。usingQuartzTypeLib;關于代碼:怎樣建立DirectShow并選擇媒體文件?在選擇了主菜單下的"File->Open..."后,顯示"OpenFile"對話框然后用戶可以選擇一個媒體文件。在C#中通過建立一個OpenFileDialog類對象并使用ShowDialog()方法來實現(xiàn)。OpenFileDialogopenFileDialog=newOpenFileDialog();openFileDialog.Filter="MediaFiles|*.mpg;*.avi;*.wma;*.mov;"+"*.wav;*.mp2;*.mp3|AllFiles|*.*";if(DialogResult.OK==openFileDialog.ShowDialog()){...在以上完成之后,我們開始建立了DirectShow并開始渲染媒體文件。通過以下幾步完成:建立圖象過濾管理(FGM)建立圖象過濾(通過FGM)播放圖象并返回事件以下代碼演示怎樣建立圖象過濾管理和圖象過濾:CollapseCleanUp();m_objFilterGraph=newFilgraphManager();m_objFilterGraph.RenderFile(openFileDialog.FileName);m_objBasicAudio=m_objFilterGraphasIBasicAudio;try{m_objVideoWindow=m_objFilterGraphasIVideoWindow;m_objVideoWindow.Owner=(int)panel1.Handle;m_objVideoWindow.windowstyle=WS_CHILD|WS_CLIPCHILDREN;m_objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,panel1.ClientRectangle.Top,panel1.ClientRectangle.Width,panel1.ClientRectangle.Height);}catch(Exceptionex){m_objVideoWindow=Null;}m_objMediaEvent=m_objFilterGraphasIMediaEvent;m_objMediaEventEx=m_objFilterGraphasIMediaEventEx;m_objMediaEventEx.SetNotifyWindow((int)this.Handle,WM_GRAPHNOTIFY,0);m_objMediaPosition=m_objFilterGraphasIMediaPosition;m_objMediaControl=m_objFilterGraphasIMediaControl;通過CleanUp()我們刪除對象,如果對象存在。在我們可以開始渲染一個文件時,我們必須建立FilterGraphManager的幾個新對象用新的方法。RenderFile()方法建立了一個圖象過濾器用來渲染指定文件。IBasicAudio類用來設定聲音的大小和質量。IVideoWindow類用來設定窗口風格,窗口位置。該函數(shù)是附加的,如果你播放聲音文件,你如果調用該方法??墒遣シ怕曇粑募恍枰狪VideoWindow類,所以將m_objVideoWindow設置成Null。IMediaEvent和IMediaEventEx類用來偵聽消息,用來發(fā)送DirectShow信息到父窗口。通過IMediaPosition類,可以設置當前的位置。通過IMediaControl類來控制開始,停止視頻和聲音的播放。想了解更多關于DirectShow的內容請讀一下MSDN的文檔。怎樣播放媒體文件?用IMediaControl類的Run()方法來開始播放一個視頻或聲音文件。m_objMediaControl.Run();怎樣暫停播放?如果你想要暫停播放一個視頻或聲音文件,使用IMediaControl類的Pause()方法。m_objMediaControl.Pause();怎樣停止播放?用IMediaControl類的Stop()方法來停止播放一個視頻或聲音。m_objMediaControl.Stop();怎樣得到文件的播放進度和持續(xù)時間?當媒體文件被播放時,我們在狀態(tài)欄指定當前的播放進度和文件長度。我們讀取全部100MS內IMediaPosition類得到的當前進度并將大小顯示在狀態(tài)欄。為了得到文件長度我們讀取了IMediaPosition類的Duration成員變量。privatevoidtimer1_Tick(objectsender,System.EventArgse){if(m_CurrentStat(yī)us==MediaStatus.Running){UpdateStatusBar();}}時間函數(shù)每隔100MS調用Updat(yī)eStatusBar()方法,用來顯示當前位置和文件進度。CollapseprivatevoidUpdateStatusBar(){switch(m_CurrentStatus){caseMediaStatus.None:statusBarPanel1.Text="Stopped";break;caseMediaStat(yī)us.Paused:statusBarPanel1.Text="Paused";break;caseMediaStatus.Running:statusBarPanel1.Text="Running";break;caseMediaStatus.Stopped:statusBarPanel1.Text="Stopped";break;}if(m_objMediaPosition!=Null){ints=(int)m_objMediaPosition.Duration;inth=s/3600;intm=(s-(h*3600))/60;s=s-(h*3600+m*60);statusBarPanel2.Text=String.Format(yī)("{0:D2}:{1:D2}:{2:D2}",h,m,s);s=(int)m_objMediaPosition.CurrentPosition;h=s/3600;m=(s-(h*3600))/60;s=s-(h*3600+m*60);statusBarPanel3.Text=String.Format("{0:D2}:{1:D2}:{2:D2}",h,m,s);}else{statusBarPanel2.Text="00:00:00";stat(yī)usBarPanel3.Text="00:00:00";}}當文件播放結束時會怎樣?為了判定,文件是在結束狀態(tài),我們重寫了WndProc函數(shù),處理EC_COMPLETE消息,當文件結束播放時,將向窗口發(fā)送DirectShow消息。CollapseprotectedoverridevoidWndProc(refMessagem){if(m.Msg==WM_GRAPHNOTIFY){intlEventCode;intlParam1,lParam2;while(true){try{m_objMediaEventEx.GetEvent(outlEventCode,outlParam1,outlParam2,0);m_objMediaEventEx.FreeEventParams(lEventCode,lParam1,lParam2);if(lEventCode==EC_COMPLETE){m_objMediaControl.Stop();m_objMediaPosition.CurrentPosition=0;m_CurrentStatus=MediaStatus.Stopped;UpdateStat(yī)usBar();UpdateToolBar();}}catch(Exception){break;}}}base.WndProc(refm);}關鍵字:一個用C#開發(fā)的DirectShow媒體播放器(作者:DanielStrigl)按"Browse..."選擇DirectShowCOMDLL。usingQuartzTypeLib;關于代碼:怎樣建立DirectShow并選擇媒體文件?在選擇了主菜單下的"File->Open..."后,顯示"OpenFile"對話框然后用戶可以選擇一個媒體文件。在C#中通過建立一個OpenFileDialog類對象并使用ShowDialog()方法來實現(xiàn)。OpenFileDialogopenFileDialog=newOpenFileDialog();openFileDialog.Filter="MediaFiles|*.mpg;*.avi;*.wma;*.mov;"+"*.wav;*.mp2;*.mp3|AllFiles|*.*";if(DialogResult.OK==openFileDialog.ShowDialog()){...在以上完成之后,我們開始建立了DirectShow并開始渲染媒體文件。通過以下幾步完成:建立圖象過濾管理(FGM)建立圖象過濾(通過FGM)播放圖象并返回事件以下代碼演示怎樣建立圖象過濾管理和圖象過濾:CollapseCleanUp();m_objFilterGraph=newFilgraphManager();m_objFilterGraph.RenderFile(openFileDialog.FileName);m_objBasicAudio=m_objFilterGraphasIBasicAudio;try{m_objVideoWindow=m_objFilterGraphasIVideoWindow;m_objVideoWindow.Owner=(int)panel1.Handle;m_objVideoWindow.windowstyle=WS_CHILD|WS_CLIPCHILDREN;m_objVideoWindow.SetWindowPosition(panel1.ClientRectangle.Left,panel1.ClientRectangle.Top,panel1.ClientRectangle.Width,panel1.ClientRectangle.Height);}catch(Exceptionex){m_objVideoWindow=Null;}m_objMediaEvent=m_objFilterGraphasIMediaEvent;m_objMediaEventEx=m_objFilterGraphasIMediaEventEx;m_objMediaEventEx.SetNotifyWindow((int)this.Handle,WM_GRAPHNOTIFY,0);m_objMediaPosition=m_objFilterGraphasIMediaPosition;m_objMediaControl=m_objFilterGraphasIMediaControl;通過CleanUp()我們刪除對象,如果對象存在。在我們可以開始渲染一個文件時,我們必須建立FilterGraphManager的幾個新對象用新的方法。RenderFile()方法建立了一個圖象過濾器用來渲染指定文件。IBasicAudio類用來設定聲音的大小和質量。IVideoWindow類用來設定窗口風格,窗口位置。該函數(shù)是附加的,如果你播放聲音文件,你如果調用該方法??墒遣シ怕曇粑募恍枰狪VideoWindow類,所以將m_objVideoWindow設置成Null。IMediaEvent和IMediaEventEx類用來偵聽消息,用來發(fā)送DirectShow信息到父窗口。通過IMediaPosition類,可以設置當前的位置。通過IMediaControl類來控制開始,停止視頻和聲音的播放。想了解更多關于DirectShow的內容請讀一下MSDN的文檔。怎樣播放媒體文件?用IMediaControl類的Run()方法來開始播放一個視頻或聲音文件。m_objMediaControl.Run();怎樣暫停播放?如果你想要暫停播放一個視頻或聲音文件,使用IMediaControl類的Pause()方法。m_objMediaControl.Pause();怎樣停止播放?用IMediaControl類的Stop()方法來停止播放一個視頻或聲音。m_objMediaControl.Stop();怎樣得到文件的播放進度和持續(xù)時間?當媒體文件被播放時,我們在狀態(tài)欄指定當前的播放進度和文件長度。我們讀取全部100MS內IMediaPosition類得到的當前進度并將大小顯示在狀態(tài)欄。為了得到文件長度我們讀取了IMediaPosition類的Duration成員變量。privat(yī)evoidtimer1_Tick(objectsender,System.EventArgse){if(m_CurrentStatus==MediaStatus.Running){UpdateStatusBar();}}時間函數(shù)每隔100MS調用UpdateStatusBar()方法,用來顯示當前位置和文件進度。CollapseprivatevoidUpdat(yī)eStat(yī)usBar(){switch(m_CurrentStatus){caseMediaStatus.None:statusBarPanel1.Text="Stopped";break;caseMediaStat(yī)us.Paused:stat(yī)usBarPanel1.Text="Paused";break;caseMediaStatus.Running:statusBarPanel1.Text="Running";break;caseMediaStat(yī)us.Stopped:statusBarPanel1.Text="Stopped";break;}if(m_objMediaPosition!=Null){ints=(int)m_objMediaPosition.Duration;inth=s/3600;intm=(s-(h*3600))/60;s=s-(h*3600+m*60);statusBarPanel2.Text=String.Format("{0:D2}:{1:D2}:{2:D2}",h,m,s);s=(int)m_objMediaPosition.CurrentPosition;h=s/3600;m=(s-(h*3600))/60;s=s-(h*3600+m*60);statusBarPanel3.Text=String.Format("{0:D2}:{1:D2}:{2:D2}",h,m,s);}else{statusBarPanel2.Text="00:00:00";statusBarPanel3.Text="00:00:00";}}當文件播放結束時會怎樣?為了判定,文件是在結束狀態(tài),我們重寫了WndProc函數(shù),處理EC_COMPLETE消息,當文件結束播放時,將向窗口發(fā)送DirectShow消息。CollapseprotectedoverridevoidWndProc(refMessagem){if(m.Msg==WM_GRAPHNOTIFY){intlEventCode;intlParam1,lParam2;while(true){try{m_objMediaEventEx.GetEvent(outlEventCode,outlParam1,outlParam2,0);m_objMediaEventEx.FreeEventParams(lEventCode,lParam1,lParam2);if(lEventCode==EC_COMPLETE){m_objMediaControl.Stop();m_objMediaPosition.CurrentPosition=0;m_CurrentStatus=MediaStatus.Stopped;UpdateStatusBar();UpdateToolBar();}}cat(yī)ch(Exception){break;}}}base.WndProc(refm);}詳細出處參考:HYPERLINK"http://www.itqun.net/content-detail/123829_2.html"http://www.itqun.net/content-detail/123829_2.htmlHYPERLINK"http://blogs.com/freeliver54/archive/2008/10/15/1311356.html"[引]C#WinFormDirectShow視頻采集及圖片抓取實例DxSnapDirectShowSamples-2007-July\Samples\Capture\DxSnapCapture.cs/****************************************************************************While
the
underlying
libraries
are
covered
by
LGPL,
this
sample
is
released
as
public
domain.
It
is
distributed
in
the
hope
that(yī)
it
will
be
useful,
but
WITHOUT
ANY
WARRANTY;
without
even
the
implied
warranty
of
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE.
*****************************************************************************/using
System;using
System.Drawing;using
System.Drawing.Imaging;using
System.Collections;using
System.Runtime.InteropServices;using
System.Threading;using
System.Diagnostics;using
System.Windows.Forms;using
DirectShowLib;namespace
SnapShot{
///
<summary>
Summary
description
for
MainForm.
</summary>
internal
class
Capture
:
ISampleGrabberCB,
IDisposable
{
#region
Member
variables
///
<summary>
graph
builder
interface.
</summary>
private
IFilterGraph2
m_FilterGraph
=
null;
//
Used
to
snap
picture
on
Still
pin
private
IAMVideoControl
m_VidControl
=
null;
privat(yī)e
IPin
m_pinStill
=
null;
///
<summary>
so
we
can
wait
for
the
async
job
to
finish
</summary>
private
ManualResetEvent
m_PictureReady
=
null;
private
bool
m_WantOne
=
false;
///
<summary>
Dimensions
of
the
image,
calculat(yī)ed
once
in
constructor
for
perf.
</summary>
privat(yī)e
int
m_videoWidth;
private
int
m_videoHeight;
private
int
m_stride;
///
<summary>
buffer
for
bitmap
data.
Always
release
by
caller</summary>
privat(yī)e
IntPtr
m_ipBuffer
=
IntPtr.Zero;#if
DEBUG
//
Allow
you
to
"Connect
to
remote
graph"
from
GraphEdit
DsROTEntry
m_rot
=
null;#endif
#endregion
#region
APIs
[DllImport("Kernel32.dll",
EntryPoint="RtlMoveMemory")]
privat(yī)e
static
extern
void
CopyMemory(IntPtr
Destination,
IntPtr
Source,
[MarshalAs(UnmanagedType.U4)]
int
Length);
#endregion
//
Zero
based
device
index
and
device
params
and
output
window
public
Capture(int
iDeviceNum,
int
iWidth,
int
iHeight,
short
iBPP,
Control
hControl)
{
DsDevice
[]
capDevices;
//
Get
the
collection
of
video
devices
capDevices
=
DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if
(iDeviceNum
+
1
>
capDevices.Length)
{
throw
new
Exception("No
video
capture
devices
found
at
that(yī)
index!");
}
try
{
//
Set
up
the
capture
graph
SetupGraph(
capDevices[iDeviceNum],
iWidth,
iHeight,
iBPP,
hControl);
//
tell
the
callback
to
ignore
new
images
m_PictureReady
=
new
ManualResetEvent(false);
}
catch
{
Dispose();
throw;
}
}
///
<summary>
release
everything.
</summary>
public
void
Dispose()
{#if
DEBUG
if
(m_rot
!=
null)
{
m_rot.Dispose();
}#endif
CloseInterfaces();
if
(m_PictureReady
!=
null)
{
m_PictureReady.Close();
}
}
//
Destructor
~Capture()
{
Dispose();
}
///
<summary>
///
Get
the
image
from
the
Still
pin.
The
returned
image
can
turned
into
a
bitmap
with
///
Bitmap
b
=
new
Bitmap(cam.Width,
cam.Height,
cam.Stride,
PixelFormat.Format24bppRgb,
m_ip);
///
If
the
image
is
upside
down,
you
can
fix
it
with
///
b.RotateFlip(RotateFlipType.Rotat(yī)eNoneFlipY);
///
</summary>
///
<returns>Returned
pointer
to
be
freed
by
caller
with
Marshal.FreeCoTaskMem</returns>
public
IntPtr
Click()
{
int
hr;
//
get
ready
to
wait
for
new
image
m_PictureReady.Reset();
m_ipB(yǎng)uffer
=
Marshal.AllocCoTaskMem(Math.Abs(m_stride)
*
m_videoHeight);
try
{
m_WantOne
=
true;
//
If
we
are
using
a
still
pin,
ask
for
a
picture
if
(m_VidControl
!=
null)
{
//
Tell
the
camera
to
send
an
image
hr
=
m_VidControl.SetMode(m_pinStill,
VideoControlFlags.Trigger);
DsError.ThrowExceptionForHR(
hr
);
}
//
Start
waiting
if
(
!
m_PictureReady.WaitOne(9000,
false)
)
{
throw
new
Exception("Timeout
waiting
to
get
picture");
}
}
catch
{
Marshal.FreeCoTaskMem(m_ipBuffer);
m_ipBuffer
=
IntPtr.Zero;
throw;
}
//
Got
one
return
m_ipB(yǎng)uffer;
}
public
int
Width
{
get
{
return
m_videoWidth;
}
}
public
int
Height
{
get
{
return
m_videoHeight;
}
}
public
int
Stride
{
get
{
return
m_stride;
}
}
///
<summary>
build
the
capture
graph
for
grabber.
</summary>
private
void
SetupGraph(DsDevice
dev,
int
iWidth,
int
iHeight,
short
iBPP,
Control
hControl)
{
int
hr;
ISampleGrabber
sampGrabber
=
null;
IBaseFilter
capFilter
=
null;
IPin
pCaptureOut
=
null;
IPin
pSampleIn
=
null;
IPin
pRenderIn
=
null;
//
Get
the
graphbuilder
object
m_FilterGraph
=
new
FilterGraph()
as
IFilterGraph2;
try
{#if
DEBUG
m_rot
=
new
DsROTEntry(m_FilterGraph);#endif
//
add
the
video
input
device
hr
=
m_FilterGraph.AddSourceFilterForMoniker(dev.Mon,
null,
dev.Name,
out
capFilter);
DsError.ThrowExceptionForHR(
hr
);
//
Find
the
still
pin
m_pinStill
=
DsFindPin.ByCategory(capFilter,
PinCategory.Still,
0);
//
Didn't
find
one.
Is
there
a
preview
pin?
if
(m_pinStill
==
null)
{
m_pinStill
=
DsFindPin.ByCategory(capFilter,
PinCategory.Preview,
0);
}
//
Still
haven't
found
one.
Need
to
put
a
splitter
in
so
we
have
//
one
stream
to
capture
the
bitmap
from,
and
one
to
display.
Ok,
we
//
don't
*have*
to
do
it
that
way,
but
we
are
going
to
anyway.
if
(m_pinStill
==
null)
{
IPin
pRaw
=
null;
IPin
pSmart
=
null;
//
There
is
no
still
pin
m_VidControl
=
null;
//
Add
a
splitter
IBaseFilter
iSmartTee
=
(IBaseFilter)new
SmartTee();
try
{
hr
=
m_FilterGraph.AddFilter(iSmartTee,
"SmartTee");
DsError.ThrowExceptionForHR(
hr
);
//
Find
the
find
the
capture
pin
from
the
video
device
and
the
//
input
pin
for
the
splitter,
and
connnect
them
pRaw
=
DsFindPin.ByCategory(capFilter,
PinCategory.Capture,
0);
pSmart
=
DsFindPin.ByDirection(iSmartTee,
PinDirection.Input,
0);
hr
=
m_FilterGraph.Connect(pRaw,
pSmart);
DsError.ThrowExceptionForHR(
hr
);
//
Now
set
the
capture
and
still
pins
(from
the
splitter)
m_pinStill
=
DsFindPin.ByName(iSmartTee,
"Preview");
pCaptureOut
=
DsFindPin.ByName(iSmartTee,
"Capture");
//
If
any
of
the
default
config
items
are
set,
perform
the
config
//
on
the
actual
video
device
(rat(yī)her
than
the
splitter)
if
(iHeight
+
iWidth
+
iBPP
>
0)
{
SetConfigParms(pRaw,
iWidth,
iHeight,
iBPP);
}
}
finally
{
if
(pRaw
!=
null)
{
Marshal.ReleaseComObject(pRaw);
}
if
(pRaw
!=
pSmart)
{
Marshal.ReleaseComObject(pSmart);
}
if
(pRaw
!=
iSmartTee)
{
Marshal.ReleaseComObject(iSmartTee);
}
}
}
else
{
//
Get
a
control
pointer
(used
in
Click())
m_VidControl
=
capFilter
as
IAMVideoControl;
pCaptureOut
=
DsFindPin.ByCategory(capFilter,
PinCategory.Capture,
0);
//
If
any
of
the
default
config
items
are
set
if
(iHeight
+
iWidth
+
iBPP
>
0)
{
SetConfigParms(m_pinStill,
iWidth,
iHeight,
iBPP);
}
}
//
Get
the
SampleGrabber
interface
sampGrabber
=
new
SampleGrabber()
as
ISampleGrabber;
//
Configure
the
sample
grabber
IBaseFilter
baseGrabFlt
=
sampGrabber
as
IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
pSampleIn
=
DsFindPin.ByDirection(baseGrabFlt,
PinDirection.Input,
0);
//
Get
the
default
video
renderer
IBaseFilter
pRenderer
=
new
VideoRendererDefault()
as
IBaseFilter;
hr
=
m_FilterGraph.AddFilter(pRenderer,
"Renderer");
DsError.ThrowExceptionForHR(
hr
);
pRenderIn
=
DsFindPin.ByDirection(pRenderer,
PinDirection.Input,
0);
//
Add
the
sample
grabber
to
the
graph
hr
=
m_FilterGraph.AddFilter(
baseGrabFlt,
"Ds.NET
Grabber"
);
DsError.ThrowExceptionForHR(
hr
);
if
(m_VidControl
==
null)
{
//
Connect
the
Still
pin
to
the
sample
grabber
hr
=
m_FilterGraph.Connect(m_pinStill,
pSampleIn);
DsError.ThrowExceptionForHR(
hr
);
//
Connect
the
capture
pin
to
the
renderer
hr
=
m_FilterGraph.Connect(pCaptureOut,
pRenderIn);
DsError.ThrowExceptionForHR(
hr
);
}
else
{
//
Connect
the
capture
pin
to
the
renderer
hr
=
m_FilterGraph.Connect(pCaptureOut,
pRenderIn);
DsError.ThrowExceptionForHR(
hr
);
//
Connect
the
Still
pin
to
the
sample
grabber
hr
=
m_FilterGraph.Connect(m_pinStill,
pSampleIn);
DsError.ThrowExceptionForHR(
hr
);
}
//
Learn
the
video
properties
SaveSizeInfo(sampGrabber);
ConfigVideoWindow(hControl);
//
Start
the
graph
IMediaControl
mediaCtrl
=
m_FilterGraph
as
IMediaControl;
hr
=
mediaCtrl.Run();
DsError.ThrowExceptionForHR(
hr
);
}
finally
{
if
(sampGrabber
!=
null)
{
Marshal.ReleaseComObject(sampGrabber);
sampGrabber
=
null;
}
if
(pCaptureOut
!=
null)
{
Marshal.ReleaseComObject(pCaptureOut);
pCaptureOut
=
null;
}
if
(pRenderIn
!=
null)
{
Marshal.ReleaseComObject(pRenderIn);
pRenderIn
=
null;
}
if
(pSampleIn
!=
null)
{
Marshal.ReleaseComObject(pSampleIn);
pSampleIn
=
null;
}
}
}
private
void
SaveSizeInfo(ISampleGrabber
sampGrabber)
{
int
hr;
//
Get
the
media
type
from
the
SampleGrabber
AMMediaType
media
=
new
AMMediaType();
hr
=
sampGrabber.GetConnectedMediaType(
media
);
DsError.ThrowExceptionForHR(
hr
);
if(
(media.formatType
!=
Format(yī)Type.VideoInfo)
||
(media.formatPtr
==
IntPtr.Zero)
)
{
throw
new
NotSupportedException(
"Unknown
Grabber
Media
Format"
);
}
//
Grab
the
size
info
VideoInfoHeader
videoInfoHeader
=
(VideoInfoHeader)
Marshal.PtrToStructure(
media.formatPtr,
typeof(VideoInfoHeader)
);
m_videoWidth
=
videoInfoHeader.BmiHeader.Width;
m_videoHeight
=
videoInfoHeader.BmiHeader.Height;
m_stride
=
m_videoWidth
*
(videoInfoHeader.BmiHeader.BitCount
/
8);
DsUtils.FreeAMMediaType(media);
media
=
null;
}
//
Set
the
video
window
within
the
control
specified
by
hControl
private
void
ConfigVideoWindow(Control
hControl)
{
int
hr;
IVideoWindow
ivw
=
m_FilterGraph
as
IVideoWindow;
//
Set
the
parent
hr
=
ivw.put_Owner(hControl.Handle);
DsError.ThrowExceptionForHR(
hr
);
//
Turn
off
captions,
etc
hr
=
ivw.put_WindowStyle(WindowStyle.Child
|
WindowStyle.ClipChildren
|
WindowStyle.ClipSiblings);
DsError.ThrowExceptionForHR(
hr
);
//
Yes,
make
it
visible
hr
=
ivw.put_Visible(
OABool.True
);
DsError.ThrowExceptionForHR(
hr
);
//
Move
to
upper
left
corner
Rectangle
rc
=
hControl.ClientRectangle;
hr
=
ivw.SetWindowPosition(
0,
0,
rc.Right,
rc.Bottom
);
DsError.ThrowExceptionForHR(
hr
);
}
private
void
ConfigureSampleGrabber(ISampleGrabber
sampGrabber)
{
int
hr;
AMMediaType
media
=
new
AMMediaType();
//
Set
the
media
type
to
Video/RBG24
media.majorType
=
MediaType.Video;
media.subType
=
MediaSubType.RGB24;
media.format(yī)Type
=
FormatType.VideoInfo;
hr
=
sampGrabber.SetMediaType(
media
);
DsError.ThrowExceptionForHR(
hr
);
DsUtils.FreeAMMediaType(media);
media
=
null;
//
Configure
the
samplegrabber
hr
=
sampGrabber.SetCallback(
this,
1
);
DsError.ThrowExceptionForHR(
hr
);
}
//
Set
the
Framerate,
and
video
size
private
void
SetConfigParms(IPin
pStill,
int
iWidth,
int
iHeight,
short
iBPP)
{
int
hr;
AMMediaType
media;
VideoInfoHeader
v;
IAMStreamConfig
videoStreamConfig
=
pStill
as
IAMStreamConfig;
//
Get
the
existing
format(yī)
block
hr
=
videoStreamConfig.GetFormat(out
media);
DsError.ThrowExceptionForHR(hr);
try
{
//
copy
out
the
videoinfoheader
v
=
new
VideoInfoHeader();
Marshal.PtrToStructure(
media.formatPtr,
v
);
//
if
overriding
the
width,
set
the
width
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湖北省云學聯(lián)盟2024-2025學年高一下學期3月月考物理試題(原卷版+解析版)
- 不完全市場下發(fā)展中國家的農(nóng)村市場講義
- 2025年黨章黨史國史國情知識競賽題庫及答案(共200題)
- 《國際市場營銷》課件-第9章 國際市場促銷策略
- 《電子商務基礎》課件-話題3 電子商務運用
- 橄欖球俱樂部簡裝合同樣本
- 保險業(yè)務代理居間協(xié)議
- 電子商務平臺訂單管理表
- 高質量產(chǎn)業(yè)人才培育與發(fā)展計劃實施方案研究報告
- 如何寫可行性分析報告
- (一診)2025年蘭州市高三診斷考試政治試卷(含答案)
- 2025國家電力投資集團有限公司應屆畢業(yè)生招聘筆試參考題庫附帶答案詳解
- 2025年個人所得稅贍養(yǎng)老人費用分攤協(xié)議模板
- 2025年內蒙古興安盟單招職業(yè)適應性測試題庫附答案
- 醫(yī)療器械使用安全和風險管理培訓課件
- 2025年新疆生產(chǎn)建設兵團興新職業(yè)技術學院單招職業(yè)傾向性測試題庫帶答案
- 2025年江西工業(yè)貿易職業(yè)技術學院單招職業(yè)技能測試題庫帶答案
- (正式版)JBT 14449-2024 起重機械焊接工藝評定
- DB32∕T 4117-2021 保溫裝飾板外墻外保溫系統(tǒng)技術規(guī)程
- 變壓器的用途、分類與結構ppt課件
- CT新技術學習課程
評論
0/150
提交評論