=====================================================

最简单的基于DirectShow的示例文章列表:

最简单的基于DirectShow的示例:视频播放器

最简单的基于DirectShow的示例:视频播放器图形界面版

最简单的基于DirectShow的示例:视频播放器自定义版

最简单的基于DirectShow的示例:获取Filter信息

=====================================================

本文记录一个最简单的基于DirectShow的视频播放器。DirectShow是一个庞大的框架,可以在Windows下实现多种多样的视频处理需求。但是它的“庞大”也使得新手不太容易学习它的使用。本文的例子正是为解决这一问题而做的,它只包含了使用DirectShow播放一个视频文件所需要的最重要的函数。

流程图

最简单的使用DirectShow播放视频文件的流程如下图所示。

流程图中涉及到几个接口如下所示。

IGraphBuilder:继承自IFilterGraph,用于构建Filter Graph。相比于IFilterGraph来说IGraphBuilder提供了一些更加“智能”的方法,例如RenderFile()方法。
IMediaControl:提供和播放控制有关的一些接口。

IMediaEvent:用来处理Filter Graph发出的事件。

流程图中关键函数的作用如下所示。

CoInitialize() :初始化COM运行环境。
CoCreateInstance(…,pGraph) :用指定的类标识符创建一个Com对象。在该播放器中类标识符为“CLSID_FilterGraph”,用于创建IGraphBuilder。
pGraph->QueryInterface(…,pControl) :通过QueryInterface()查询某个组件是否支持某个特定的接口。在这里查询IMediaControl接口。
pGraph->QueryInterface(…,pEvent) :同上。在这里查询IMediaEvent接口。
pGraph->RenderFile("xxx.mkv"):为指定的文件智能的构建一个Filter Graph。
pControl->Run() :开始运行Filter Graph中的所有Filter。
pEvent->WaitForCompletion() :等待Filter Graph处理完所有数据。

CoUninitialize():释放CoInitialize()初始化的COM运行环境。

注意上述几个函数是构建一个基于DirectShow的视频播放器所必须的函数,除了上述几个接口之外还经常用到以下几个接口:

IBasicVideo:提供和视频有关的一些接口。
IBasicAudio:提供和音频有关的一些接口。
IVideoWindow:提供和窗口有关的一些接口。
IMediaSeeking:提供和播放位置有关的一些接口。

源代码

/*** 最简单的基于DirectShow的视频播放器* Simplest DirectShow Player** 雷霄骅 Lei Xiaohua* leixiaohua1020@126.com* 中国传媒大学/数字电视技术* Communication University of China / Digital TV Technology* http://blog.csdn.net/leixiaohua1020** 本程序是一个最简单的基于DirectShow的播放器。* 适合初学者学习DirectShow。** This example is the simplest Player based on DirectShow.* Suitable for the beginner of DirectShow.*/#include "stdafx.h"#include <dshow.h>
#include <atlconv.h>#define OUTPUT_INFO 1//Show Filter in FilterGpragh
int show_filters_in_filtergraph(IGraphBuilder *pGraph){printf("Filters in FilterGpragh=======\n");USES_CONVERSION;IEnumFilters *pFilterEnum=NULL;if(FAILED(pGraph->EnumFilters(&pFilterEnum))){pFilterEnum->Release();return -1;}pFilterEnum->Reset();IBaseFilter * filter = NULL;ULONG fetchCount = 0;//Pin Infowhile (SUCCEEDED(pFilterEnum->Next(1, &filter, &fetchCount)) && fetchCount){if (!filter){continue;}FILTER_INFO FilterInfo;if (FAILED(filter->QueryFilterInfo(&FilterInfo))){continue;}printf("[%s]\n",W2A(FilterInfo.achName));filter->Release();}pFilterEnum->Release();printf("==============================\n");return 0;
}int _tmain(int argc, _TCHAR* argv[])
{IGraphBuilder *pGraph = NULL;IMediaControl *pControl = NULL;IMediaEvent   *pEvent = NULL; //Get some param--------------HRESULT hr1;IBasicVideo *pVideo=NULL;IBasicAudio *pAudio=NULL;IVideoWindow *pWindow=NULL;IMediaSeeking *pSeeking=NULL;// Init COMHRESULT hr = CoInitialize(NULL);if (FAILED(hr)){printf("Error - Can't init COM.");return -1;}// Create FilterGraphhr=CoCreateInstance(CLSID_FilterGraph, NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGraph);if (FAILED(hr)){printf("Error - Can't create Filter Graph.");return -1;}//  Query Interfacehr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);// RenderFilehr = pGraph->RenderFile(L"cuc_ieschool.mov", NULL);if (FAILED(hr)){printf("Error - Can't Render File.");return -1;}
#if OUTPUT_INFO//Get some information----------long video_w=0,video_h=0,video_bitrate=0,audio_volume=0;long long duration_1=0,position_1=0;REFTIME avgtimeperframe=0;float framerate=0,duration_sec=0,progress=0,position_sec=0;//Videohr1=pGraph->QueryInterface(IID_IBasicVideo, (void **)&pVideo);pVideo->get_VideoWidth(&video_w);pVideo->get_VideoHeight(&video_h);pVideo->get_AvgTimePerFrame(&avgtimeperframe);framerate=1/avgtimeperframe;//pVideo->get_BitRate(&video_bitrate);//Audiohr1=pGraph->QueryInterface(IID_IBasicAudio, (void **)&pAudio);//Mute//pAudio->put_Volume(-10000);printf("Some Information:\n");printf("Video Resolution:\t%dx%d\n",video_w,video_h);printf("Video Framerate:\t%.3f\n",framerate);//Windowhr1=pGraph->QueryInterface(IID_IVideoWindow, (void **)&pWindow);pWindow->put_Caption(L"Simplest DirectShow Player");//pWindow->put_Width(480);//pWindow->put_Height(272);//Seekhr1=pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pSeeking);pSeeking->GetDuration(&duration_1);//time unit:100ns=0.0000001sduration_sec=(float)duration_1/10000000.0;printf("Duration:\t%.2f s\n",duration_sec);//pSeeking->SetPositions();//PlayBack Rate//pSeeking->SetRate(2.0);//Show Filter in FilterGpaghshow_filters_in_filtergraph(pGraph);//----------------------
#endifprintf("Progress Info\n");printf("Position\tProgress\n");if (SUCCEEDED(hr)){// Runhr = pControl->Run();if (SUCCEEDED(hr)){long evCode=0;//pEvent->WaitForCompletion(INFINITE, &evCode);while(evCode!=EC_COMPLETE){//Info
#if OUTPUT_INFOpSeeking->GetCurrentPosition(&position_1);position_sec=(float)position_1/10000000.0;progress=position_sec*100/duration_sec;printf("%7.2fs\t%5.2f%%\n",position_sec,progress);
#endif//1000mspEvent->WaitForCompletion(1000, &evCode);}}}// Release resourcepControl->Release();pEvent->Release();pGraph->Release();CoUninitialize();return 0;
}

运行结果

程序运行后即可开始播放一个“cuc_ieschool.mov”文件。程序运行时候的截图如下所示。由图可见运行的同时程序在控制台中打印出了两种信息:
(1) 该视频的相关信息

(2) 播放该视频的 Filter Graph中的Filter(该功能通过函数show_filters_in_filtergraph()完成)。

可以通过定义在代码最前面宏OUTPUT_INFO控制是否输出视频的信息。定义成“0”的话则不会输出视频的信息。如下所示。

#define OUTPUT_INFO 1

下载


Simplest DirectShow Example

项目主页

SourceForge:https://sourceforge.net/projects/simplestdirectshowexample/

Github:https://github.com/leixiaohua1020/simplest_directshow_example

开源中国:http://git.oschina.net/leixiaohua1020/simplest_directshow_example

CDSN下载地址: http://download.csdn.net/detail/leixiaohua1020/8348163

本程序包含了DirectShow开发的示例程序。适合DirectShow初学者进行学习。
它包含了以下几个子程序:
simplest_directshow_player: 最简单的基于DirectShow的视频播放器。
simplest_directshow_player_custom: 最简单的基于DirectShow的视频播放器(Custom)。
playerGUI: 最简单的基于DirectShow的播放器-图形界面版。
simplest_directshow_info: 最简单的Directshow信息显示例子。
simplest_directshow_filter: 目前还未完成。

最简单的基于DirectShow的示例:视频播放器相关推荐

  1. 最简单的基于DirectShow的示例:视频播放器自定义版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  2. 最简单的基于DirectShow的示例:视频播放器图形界面版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  3. 最简单的基于DirectShow的示例:获取Filter信息

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  4. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  5. 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  6. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  7. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器

    简介 FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手.我刚接触FFMPEG的时候也感觉不知从何学起. 因此我把自己做项目过程中实现的一个非常简单的视频 ...

  8. 最简单的基于 DirectShow 的视频播放器

    源程序下载链接:https://download.csdn.net/download/bmjhappy/11250669 50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍 ...

  9. 转:最简单的基于 DirectShow 的视频播放器

    50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...

最新文章

  1. POJ3114强连通+spfa
  2. LongestPalindromeSequence
  3. 练习_用if语句实现考试成绩划分
  4. China .NET Conf 2019-.NET技术架构下的混沌工程实践
  5. java 1.8 vm_HotSpot虚拟机在java 1.8中的新实现
  6. ueditor编辑器php上传配置,php版本UEditor编辑器图片上传设置
  7. 工作97:父子组件传值
  8. Netflix正在搞的混沌工程到底是什么?终于有人讲明白了
  9. python编辑编程器_用Python制作编辑器
  10. (67)FPGA面试题-为priority encoder编写Verilog代码,实现MUX4_1
  11. zabbix 获取不到自定义脚本的值解决
  12. python是什么-马哥教育官网-专业Linux培训班,Python培训机构
  13. CSDN《老友记》简记
  14. 【跟我一起学Unity3D】做一个2D的90坦克大战之各种各样的墙附上项目源码
  15. 年度回顾篇:2018年的亚马逊,众生虽苦,诸恶莫作
  16. 千年鸿蒙盼尔来兮,古言爱情誓言
  17. mysql left join like_使用LEFT JOIN和LIKE mysql
  18. Marvolo Gaunt's Ring ---CodeForces - 855B(思维题)
  19. 相机光学(零)——分辨率测试
  20. 国内12所最奢华的图书馆,看到这儿我愿意再考一年!

热门文章

  1. 十个计算机快捷键,10个常用的电脑快捷键,学会了可以让你进一步提升工作效率...
  2. 关于3DMAX2012提示MaxStartUI.mun无效,并显示启动不了MAX
  3. php引用公有类方法_php利用ReflectionClass反射机制获取类public公有方法
  4. ccc-Brief Introduction of Deep Learning-李宏毅(6)
  5. 学习笔记 | 2023 AAAI 对抗性权值扰动改善图神经网络的泛化性能
  6. 如何用 js 获取虚拟键盘高度?(适用所有平台)
  7. 第001讲:我和Python的第一次亲密接触 | 课后测试题及答案
  8. Dedecms 5.7sp1文章模型栏目接口使用手册
  9. 用Python通过163邮箱发送邮件
  10. PaddlePaddle21天深度学习训练营学习心得