一个directshow示例程序编译时link行政许可 错误示例,求教,0

编译directshow的示例程序baseclasses - CSDN博客
编译directshow的示例程序baseclasses
编译baseclasses
由于此工程的头文件中包含文件时都用了&&符号,所以在进行以下所说的任何操作之前,必需首先设置好VS的包含路径,即把baseclasses的工程目录加到VS的包含路径中。这个工程需要这样的设置,不太好,它必竟是做为一个&demo&出现的,而且,对于不同的开发都来说,可能会放这个工程到不同的目录,所以这样设置就不好。所以我没有设置这个路径,而是修改工程的包含文件来解决这个问题,因为我的工程没有直接在它安装的默认目录中编译,而是被我拷贝到另外一个地方进行的编译。
注:我编译使用的是vs2008,os&是vista,baseclasses工程是从windows&sdk的安装包中获取的(早期的directshow示例都是在directx的单独安装包中,现在新的都改成了从windows&sdk的安装包中发布),我的工程中有combase.h文件,有的版本没有这个文件,我就不知道其编译是否可以非常顺利。
下载地址:
web:/downloads/details.aspx?FamilyId=F26B1AA4-741A-433A-9BE5-FA919850BDBF&displaylang=en
名称:name:Windows&SDK&for&Windows&Server&2008&and&.NET&Framework&3.5
文件名:6.0..367-KRMSDK_EN.iso
大小:1.29G
安装的默认路径为:c:/Program&Files/Microsoft&SDKs/Windows/v6.1
在默认情况下,是编译成为静态链接库的,这很简单,只要设置好包含的路径就可以直接编译,但是我要使用动态库,所以我直接修改编译选项为动态链接,然后把streams.h中包含本地文件的符号全部由&&改成了双引号"",然后编译时编译不过,说是_无法链接(实际代码中是,没有带前导下划线)
我发现是在uuids.h中有声明,所以就在相关的文件中包含了文件,再编译,还是不过,又说是没有声明,晕!
上网上找,发现很多都是说的很简单,而且都是抄来抄出说得一样,好不容易才找到一个比较好的:.cn/s/blog_4c0aa7ef0100cyqr.html,按照上面说的,把strmiids.lib&和&quartz.lib加入到编译选项中(上面说的包含uuids.h文件的修改全部撤消),如图:
注意,有的baseclasses工程好像没有linker这个选项卡,我没有找它可以在哪里增加这两个lib,我想应该是有地方可以加的。再次编译,还是不过,又说&&没有声明,无法链接通过。
从代码查找,发现它是被一个宏定义包含,于是在链接选项中又加入了,如图:
再编译,还是不过,这次只出现如下的两个错误:
第一个错误,查看的类声明发现,前两个成员是:
这和在声明时的附值是不一样的,所以就调换了这两个成员的声明顺序:
第二个错误,直接简单地在声明时候的附值时使用强制转换。
这两个错误的解决过程,没有试验是否会造成不正确的后果。然后编译,还是不过,说是无法链接,查msdn,直接在图1所示位置添加winmm.lib,然后再编译,终于通过!
本文已收录于以下专栏:
相关文章推荐
编译directshow的示例程序baseclasses
09:32 860人阅读
评论(2) 收藏
编译baseclasses
首先,就是编译baseclasses,什么是baseclasses?打开你的dx的sdk安装目录,例如:
D:/DX90SDK/Samples/C++/DirectShow/
这里就有一个叫bas...
errorC4430: missing type specifier - int assumed. Note: C++ does not supportdefault-int        c:\Pr...
Integer属于包装类,int属于基本数据类型,初始化时,int赋值默认为0,Integer默认指向null。
创建对象时,可以写成
1. Integer a = 128;
在AWS EC2上编译Caffe,并测试示例程序
Caffe 1.0.0
1. 启动Ubuntu 14.04 EC2.
选择镜像版本
2. 进入虚拟机后,安装编译 Caffe
首先自己去下载omniorb,解压后准备安装。我解压到了/root/omniorb4.1.5文件夹中。
请一定要阅读README.unix,按照其指示的步骤,在终端中如下:
1) cd /root...
首先确保Hadoop已正确安装及运行。
将WordCount.java拷贝出来
$ cp ./src/examples/org/apache/hadoop/examples/WordCount...
此前做了一系列有关FFmpeg的示例程序,组成了《最简单的FFmpeg示例程序合集》,其中包含了如下项目:simplest ffmpeg player:                  最简单的基于...
1.建立一个android 的项目, NDK 不支持 1.5 以下的版本
项目中包含 两个文件:JNI.java, JniTest.java
2.编译工程 。这步非常重要,先编译工程才能执...
从网上下载了OpenGL超级宝典第五版的示例代码,代码中只提供了VS和Linux下的编译文件,但直接使用Linux下的Makefile进行编译,发现会报错。为了解决编译的问题,也颇费了写周折。因此写了...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)浅析DirectShow音视频同步解决方案
ZDNet软件频道 时间: 作者:陆其明 | 论坛 
本文关键词:
多媒体处理,不可避免地要解决音视频的同步问题。DirectShow是怎么来实现的呢?
多媒体处理,不可避免地要解决音视频的同步问题。是怎么来实现的呢?我们一起来学习一下。   大家知道,结构最核心的部分是Filter Graph Manager:向下控制Graph中的所有Filter,向上对应用程序提供编程接口。其中,Filter Graph Manager实现的很重要一个功能,就是同步音视频的处理。简单地说,就是选一个公共的参考时钟,并且要求给每个Sample都打上时间戳,Video Renderer或Audio Renderer根据Sample的时间戳来控制播放。如果到达Renderer的Sample晚了,则加快Sample的播放;如果早了,则Renderer等待,一直到Sample时间戳的开始时间再开始播放。这个控制过程还引入一个叫Quality Control的反馈机制。  下面,我们来看一下参考时钟(Reference Clock)。所有Filter都参照于同一个时钟,才能统一步调。引入了两种时钟时间:Reference time和Stream time。前者是从参考时钟返回的绝对时间(IReferenceClock::GetTime),数值本身的意义取决于参考时钟的内部实现,利用价值不大;后者是两次从参考时钟读取的数值的差值,实际应用于Filter Graph内部的同步。Stream time在Filter Graph不同状态的取值为:  1. Filter Graph运行时,取值为当前参考时钟时间减去Filter Graph启动时的时间(启动时间是通过调用Filter上的IMediaFilter::Run来设置的);  2. Filter Graph暂停时,保持为暂停那一刻的S  3. 执行完一次Seek操作后,复位至零;  4. Filter Graph停止时,取值不确定。  那么,参考时钟究竟是什么东西呢?其实,它只是一个实现了IReferenceClock接口的对象。也就是说,任何一个实现了IReferenceClock接口的对象都可以成为参考时钟。在Filter Graph中,这个对象一般就是一个Filter。(在GraphEdit中,实现了参考时钟的Filter上会显示一个时钟的图标;如果同一个Graph中有多个Fiter实现了参考时钟,当前被Filter Graph Manager使用的那个会高亮度显示。)而且大多数情况下,参考时钟是由Audio Renderer这个Filter提供的,因为声卡上本身带有了硬件定时器资源。接下来的问题是,如果Filter Graph中有多个对象实现了IReferenceClock接口,Filter Graph Manager是如何做出选择的呢?默认的算法如下:  1. 如果应用程序设置了一个参考时钟,则直接使用这个参考时钟。(应用程序通过IMediaFilter:: SetSyncSource设置参考时钟,参数即为参考时钟;如果参数值为NULL,表示Filter Graph不使用参考时钟,以最快的速度处理Sample;可以调用IFilterGraph:: SetDefaultSyncSource来恢复Filter Graph Manager默认的参考时钟。值得注意的是,这时候的IMediaFilter接口应该从Filter Graph Manager上获得,而不是枚举Graph中所有的Filter并分别调用Filter上的这个接口方法。)  2. 如果Graph中有支持IReferenceClock接口的Live Source,则选择这个Live Source。  3. 如果Graph中没有Live Source,则从Renderer依次往上选择一个实现IReferenceClock接口的Filter。如果连接着的Filter都不能提供参考时钟,则再从没有连接的Filter中选择。这一步算法中还有一个优先情况,就是如果Filter Graph中含有一个Audio Render的链路,则直接选择Audio Renderer这个Filter(原因上面已经提及)。  4. 如果以上方法都找不到一个适合的Filter,则选取系统参考时钟。(System Reference Clock,通过CoCreateInstance创建,CLSID为CLSID_SystemClock。)  我们再来看一下Sample的时间戳(Time Stamp)。需要注意的是,每个Sample上可以设置两种时间戳:IMediaSample::SetTime和IMediaSample::SetMediaTime。我们通常讲到时间戳,一般是指前者,它又叫Presentation time,Renderer正是根据这个时间戳来控制播放;而后者对于Filter来说不是必须的,Media time有没有用取决于你的实现,比如你给每个发出去的Sample依次打上递增的序号,在后面的Filter接收时就可以判断传输的过程中是否有Sample丢失。我们再看一下IMediaSample::SetTime的参数,两个参数类型都是REFERENCE_TIME,千万不要误解这里的时间是Reference time,其实它们用的是Stream time。还有一点,就是并不是所有的Sample都要求打上时间戳。对于一些压缩数据,时间戳是很难打的,而且意义也不是很大(不过压缩数据经过Decoder出来之后到达Renderer之前,一般都会打好时间戳了)。时间戳包括两个时间,开始时间和结束时间。当Renderer接收到一个Sample时,一般会将Sample的开始时间和当前的Stream time作比较,如果Sample来晚了或者没有时间戳,则马上播放这个Sample;如果Sample来得早了,则通过调用参考时钟的IReferenceClock::AdviseTime等待Sample的开始时间到达后再将这个Sample播放。Sample上的时间戳一般由Source Filter或Parser Filter来设置,设置的方法有如下几种情况:  1. 文件回放(File playback):第一个Sample的时间戳从0开始打起,后面Sample的时间戳根据Sample有效数据的长度和回放速率来定。  2. 音视频捕捉(Video and audio capture):原则上,采集到的每一个Sample的开始时间都打上采集时刻的Stream time。对于视频帧,Preview pin出来的Sample是个例外,因为如果按上述方法打时间戳的话,每个Sample通过Filter链路传输,最后到达Video Renderer的时候都将是迟到的;Video Renderer通过Quality Control反馈给Source Filter,会导致Source Filter丢帧。所以,Preview pin出来的Sample都不打时间戳。对于音频采集,需要注意的是,Audio Capture Filter与声卡驱动程序两者各自使用了不同的缓存,采集的数据是定时从驱动程序缓存拷贝到Filter的缓存的,这里面有一定时间的消耗。  3. 合成(Mux Filters):取决于Mux后输出的数据类型,可以打时间戳,也可以不打时间戳。  大家可以看到,Sample的时间戳对于保证是很重要的。Video Renderer和Audio Renderer作为的最终执行者,需要做很多工作。我们或许要开发其它各种类型的Filter,但一般这两个Filter是不用再开发的。一是因为Renderer Filter本身的复杂性,二是因为微软会对这两个Filter不断升级,集成DirectX中其它模块的最新技术(如DirectSound、DirectDraw、Direct3D等)。  最后,我们再来仔细看一下Live Source的情况。Live Source又叫Push source,包括Video /Audio Capture Filter、网络广播接收器等。Filter Graph Manager是如何知道一个Filter是Live Source的呢?通过如下任何一个条件判断:  1. 调用Filter上的IAMFilterMiscFlags::GetMiscFlags返回有AM_FILTER_MISC_FLAGS_IS_SOURCE标记,并且至少有一个Output pin实现了IAMPushSource接口。  2. Filter实现了IKsPropertySet接口,并且有一个Capture output pin(Pin的类型为PIN_CATEGORY_CAPTURE)。  Live Source对于的影响主要是以下两个方面:Latency和Rate Matching。Latency是指Filter处理一个Sample花费的时间,对于Live Source来说,主要取决于使用缓存的大小,比如采集30fps的视频一般采集完一帧后才将数据以一个Sample发送出去,则这个Filter的Latency为33ms,而Audio一般缓存500ms后才发送一个Sample,则它的Latency就为500ms。这样的话,Audio与Video到达Renderer就会偏差470ms,造成音视频的不同步。默认情况下,Filter Graph Manager是不会对这种情况进行调整的。当然,应用程序可以通过IAMPushSource接口来进行Latency的补偿,方法是调用IAMGraphStreams::SyncUsingStreamOffset函数。Filter Graph Manager的实现如下:对所有实现IAMPushSource接口的Filter调用IAMLatency::GetLatency得到各个Source的Latency值,记下所有Latency值中的最大值,然后调用IAMPushSource::SetStreamOffset对各个Source设置偏移值。  这样,在Source Filter产生Sample时,打的时间戳就会加上这个偏移量。Rate Matching问题的引入,主要是由于Renderer Filter和Source Filter使用的是不同的参考时钟。这种情况下,Renderer对数据的播放要么太快,要么太慢。另外,一般Live Source不能控制输出数据的速率,所以必须在Renderer上进行播放速率的匹配。因为人的听觉敏感度要大于视觉敏感度,所以微软目前只在Audio Renderer上实现了Rate Matching。实现Rate Matching的算法是比较复杂的,这里就不再赘述。  看到这里,大家应该对是如何解决问题的方案有一点眉目了吧。深层次的研究,还需要更多的测试、Base class源码阅读,以及相关控制机制的理解,比如Quality Control Management等。
上一篇:下一篇:
DirectShow音视频同步解决方案
? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ?
最受关注的文章:
关键字: &&&&&&&&&& 关键字: &&&&&& 关键字: &&&& 关键字: && 关键字: &&&&&&
最新更新文章:
??????????
本篇文章共有
- 发表评论 -
??????????
Copyright& 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备号-159京公网安备:本帖子已过去太久远了,不再提供回复功能。2006年4月 总版技术专家分月排行榜第一
2006年3月 总版技术专家分月排行榜第三
2006年4月 总版技术专家分月排行榜第一
2006年3月 总版技术专家分月排行榜第三
2006年10月 总版技术专家分月排行榜第二2006年9月 总版技术专家分月排行榜第二
2006年5月 总版技术专家分月排行榜第三
2006年4月 总版技术专家分月排行榜第一
2006年3月 总版技术专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。=====================================================最简单的基于DirectShow的示例文章列表:=====================================================本文记录一个简单的基于DirectShow的自定义的视频播放器。这里所说的“自定义播放器”,实际上指的是自己在Filter Graph中手动逐个添加Filter,并且连接这些Filter的后运行的播放器。这么做相对于使用RenderFile()这种“智能”创建Filter Graph的方法来说要复杂不少,但是可以让我们更加了解DirectShow的体系。流程图最简单的基于DirectShow的自定义的视频播放器的流程如下图所示。该流程图中包含如下变量:IGraphBuilder *pGraph:继承自IFilterGraph,用于构建Filter Graph。IMediaControl *pControl:提供和播放控制有关的一些接口。IMediaEvent
*pEvent:用来处理Filter Graph发出的事件。IBaseFilter *pF_source:源Filter。IFileSourceFilter* pFileSource:源Filter的暴露的接口,用于设置输入文件的路径。IBaseFilter *pF_demuxer:解复用Filter。IBaseFilter *pF_decoder:解码Filter。IBaseFilter *pF_render:渲染Filter。IPin *pOut:输出Pin。IPin *pIn:输入Pin。IPin **pPin:内部变量Pin。该流程图大体上可以分成以下步骤:(1)
初始化DirectShow包括以下几个步骤:a)
CoInitialize():初始化COM运行环境。b)
CoCreateInstance(…,pGraph):用指定的类标识符创建一个Com对象。在这里创建IGraphBuilder。c)
pGraph-&QueryInterface(…,pControl):通过QueryInterface()查询某个组件是否支持某个特定的接口。在这里查询IMediaControl接口。d)
pGraph-&QueryInterface(…,pEvent):同上。在这里查询IMediaEvent接口。(2)
添加Source Filter包括以下几个步骤:a)
CoCreateInstance(…,pF_source):创建Source Filter。b)
pGraph-&AddFilter(pF_source,…):将Source Filter加入Filter Graph。c)
pF_source-&QueryInterface(…,pFileSource):查找Source Filter的IFileSourceFilter接口。d)
pFileSource-&Load(L"xxx.mpg",pF_source):调用IFileSourceFilter的Load()方法加载视频文件。(3)
添加Demuxer Filter包括以下几个步骤:a)
CoCreateInstance(…,pF_demuxer):创建Demuxer Filter。b)
pGraph-&AddFilter(pF_demuxer,…):将Demuxer Filter加入Filter Graph。(4)
添加Decoder Filter包括以下几个步骤:a)
CoCreateInstance(…,pF_decoder):创建Decoder Filter。b)
pGraph-&AddFilter(pF_decoder,…):将Decoder Filter加入Filter Graph。(5)
添加Render Filter包括以下几个步骤:a)
CoCreateInstance(…,pF_render):创建Render Filter。b)
pGraph-&AddFilter(pF_render,…):将Render Filter加入Filter Graph。(6)
连接Source Filter和Demuxer Filter调用了一个函数connect_filters()用于连接2个Filter。connect_filters()的执行步骤如下:a)
调用get_unconnected_pin()从源Filter中选择一个没有链接的输出Pin。b)
调用get_unconnected_pin()从目的Filter中选择一个没有链接的输入Pin。c)
连接这两个Pinget_unconnected_pin()的执行步骤如下:a)
枚举Filter上的Pin。b)
遍历这些Pin,查找符合输出方向(通过IPin的QueryDirection()方法),而且没有在使用的Pin(通过IPin的ConnectedTo()方法)。(7)
连接Demuxer Filter和Decoder Filter过程同上。(8)
连接Decoder Filter和Render Filter过程同上。(9)
开始播放包括以下步骤:pControl-&Run():开始运行Filter Graph中的所有Filter。pEvent-&WaitForCompletion():等待Filter Graph处理完所有数据。 上述步骤可以理解为在GraphEdit软件中分别按照步骤添加以下控件。其中(1)、(2)、(3)、(4)为先添加的4个Filter,(5)、(6)、(7)为Filter之间的连接线。源代码/**
* 最简单的基于DirectShow的视频播放器(Custom)
* Simplest DirectShow Player (Custom)
* 雷霄骅 Lei Xiaohua
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* 本程序是一个简单的基于DirectShow的视频播放器。该播放器通过逐个添加
* 滤镜并连接这些滤镜实现了视频的播放。适合初学者学习DirectShow。
* This software is a simple video player based on DirectShow.
* It Add DirectShow Filter Manually and Link the Pins of these filters
* to play videos.Suitable for the beginner of DirectShow.
#include "stdafx.h"
#include &dshow.h&
//'1':Add filters manually
//'0':Add filters automatically
#define ADD_MANUAL 1
//Find unconnect pins
HRESULT get_unconnected_pin(
IBaseFilter *pFilter, // Pointer to the filter.
PIN_DIRECTION PinDir, // Direction of the pin to find.
IPin **ppPin) // Receives a pointer to the pin.
*ppPin = 0;
IEnumPins *pEnum = 0;
IPin *pPin = 0;
HRESULT hr = pFilter-&EnumPins(&pEnum);
if (FAILED(hr))
while (pEnum-&Next(1, &pPin, NULL) == S_OK)
PIN_DIRECTION ThisPinD
pPin-&QueryDirection(&ThisPinDir);
if (ThisPinDir == PinDir)
IPin *pTmp = 0;
hr = pPin-&ConnectedTo(&pTmp);
if (SUCCEEDED(hr)) // Already connected, not the pin we want.
pTmp-&Release();
else // Unconnected, the pin we want.
pEnum-&Release();
*ppPin = pP
return S_OK;
pPin-&Release();
pEnum-&Release();
// Did not find a matching pin.
return E_FAIL;
//Connect 2 filters
HRESULT connect_filters(
IGraphBuilder *pGraph,
IBaseFilter *pSrc,
IBaseFilter *pDest)
if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
return E_POINTER;
//Find Output pin in source filter
IPin *pOut = 0;
HRESULT hr = NULL;
hr=get_unconnected_pin(pSrc, PINDIR_OUTPUT, &pOut);
if (FAILED(hr)){
//Find Input pin in destination filter
IPin *pIn = 0;
hr = get_unconnected_pin(pDest, PINDIR_INPUT, &pIn);
if (FAILED(hr)){
//Connnect them
hr = pGraph-&Connect(pOut, pIn);
pIn-&Release();
pOut-&Release();
int _tmain(int argc, _TCHAR* argv[])
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent
*pEvent = NULL;
// Init COM
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)){
printf("Error - Can't init COM.");
return -1;
// Create FilterGraph
hr=CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr)){
printf("Error - Can't create Filter Graph.");
return -1;
// Query Interface
hr = pGraph-&QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph-&QueryInterface(IID_IMediaEvent, (void **)&pEvent);
//1. Add Filters=======================
IBaseFilter *pF_source = 0;
hr = CoCreateInstance(CLSID_AsyncReader, 0, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)(&pF_source));
if (FAILED(hr)){
printf("Failed to create File Source.\n");
return -1;
hr = pGraph-&AddFilter(pF_source, L"Lei's Source");
if (FAILED(hr)){
printf("Failed to add File Source to Filter Graph.\n");
return -1;
IFileSourceFilter* pFileS
pF_source-&QueryInterface(IID_IFileSourceFilter, (void**)&pFileSource);
pFileSource-&Load(L"cuc_ieschool.mpg", NULL);
pFileSource-&Release();
#if ADD_MANUAL
IBaseFilter *pF_demuxer = 0;
hr = CoCreateInstance(CLSID_MPEG1Splitter, 0, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)(&pF_demuxer));
if (FAILED(hr)){
printf("Failed to create Demuxer.\n");
return -1;
hr = pGraph-&AddFilter(pF_demuxer, L"Lei's Demuxer");
if (FAILED(hr)){
printf("Failed to add Demuxer to Filter Graph.\n");
return -1;
IBaseFilter *pF_decoder = 0;
hr = CoCreateInstance(CLSID_CMpegVideoCodec, 0, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)(&pF_decoder));
if (FAILED(hr)){
printf("Failed to create Decoder.\n");
return -1;
hr = pGraph-&AddFilter(pF_decoder, L"Lei's Decoder");
if (FAILED(hr)){
printf("Failed to add Decoder to Filter Graph.\n");
return -1;
IBaseFilter *pF_render = 0;
hr = CoCreateInstance(CLSID_VideoRenderer, 0, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)(&pF_render));
if (FAILED(hr)){
printf("Failed to create Video Render.\n");
return -1;
hr = pGraph-&AddFilter(pF_render, L"Lei's Render");
if (FAILED(hr)){
printf("Failed to add Video Render to Filter Graph.\n");
return -1;
//2. Connect Filters=======================
hr = connect_filters(pGraph, pF_source, pF_demuxer);
if (FAILED(hr)){
printf("Failed to link Source and Demuxer.\n");
return -1;
hr = connect_filters(pGraph, pF_demuxer, pF_decoder);
if (FAILED(hr)){
printf("Failed to link Demuxer and Decoder.\n");
return -1;
hr = connect_filters(pGraph, pF_decoder, pF_render);
if (FAILED(hr)){
printf("Failed to link Decoder and Render.\n");
return -1;
pF_source-&Release();
pF_demuxer-&Release();
pF_decoder-&Release();
pF_render-&Release();
// get output pin
IEnumPins* pEnumP
hr = pF_source-&EnumPins(&pEnumPins);
hr = pEnumPins-&Reset();
hr = pEnumPins-&Next(1, &Pin, &fetched);
pEnumPins-&Release();
// render pin, graph builder automatically complete rest works
hr = pGraph-&Render(Pin);
if (SUCCEEDED(hr)){
hr = pControl-&Run();
if (SUCCEEDED(hr)){
long evCode=0;
pEvent-&WaitForCompletion(INFINITE, &evCode);
pControl-&Release();
pEvent-&Release();
pGraph-&Release();
CoUninitialize();
}运行结果程序的运行结果如下图所示。运行后会播放“cuc_ieschool.mpg”文件。需要注意的是,本程序并没有加入音频解码和播放的Filter,所以播放视频的时候是没有声音的。除了手动一个一个添加Filter之外,也可以在获得“源”Filter的Pin之后,直接调用IFilterGraph的Render()方法“智能”自动构建Filter Graph。注意Render()方法和RenderFile()方法是不一样的。RenderFile()是指定一个文件路径后,自动构建整个Filter Graph,相对来说更加简单些;而Render()方法则是首先要创建一个Source Filter之后,才可以自动构建整个Filter Graph。可以通过修改源文件首部的宏定义ADD_MANUAL来设定是否手动添加Filter,如下所示。//'1':Add filters manually
//'0':Add filters automatically
#define ADD_MANUAL 1 下载Simplest DirectShow Example 项目主页SourceForge:Github:开源中国:CDSN下载地址: 本程序包含了DirectShow开发的示例程序。适合DirectShow初学者进行学习。它包含了以下几个子程序:simplest_directshow_player: 最简单的基于DirectShow的视频播放器。simplest_directshow_player_custom: 最简单的基于DirectShow的视频播放器(Custom)。playerGUI: 最简单的基于DirectShow的播放器-图形界面版。simplest_directshow_info: 最简单的Directshow信息显示例子。simplest_directshow_filter: 目前还未完成。
如果您想留下此文,您可以将其发送至您的邮箱(将同时以邮件内容&PDF形式发送)
相关文章推荐
(Ctrl+Enter提交) &&
已有0人在此发表见解
&在& 18:05收藏到了
&&在信息爆炸的时代,您的知识需要整理,沉淀,积累!Lai18为您提供一个简单实用的文章整理收藏工具,在这里您可以收藏对您有用的技术文章,自由分门别类,在整理的过程中,用心梳理自己的知识!相信,用不了多久,您收藏整理的文章将是您一生的知识宝库!
· 蜀ICP备号-1}

我要回帖

更多关于 行政许可 错误示例 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信