實現(xiàn)DirectShow技術開發(fā)準備_第1頁
實現(xiàn)DirectShow技術開發(fā)準備_第2頁
實現(xiàn)DirectShow技術開發(fā)準備_第3頁
實現(xiàn)DirectShow技術開發(fā)準備_第4頁
實現(xiàn)DirectShow技術開發(fā)準備_第5頁
已閱讀5頁,還剩30頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

bitmap

with

///

Bitmap

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

still

pin,

ask

for

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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論