基于DirectShow的流媒体解码和回放

一、 前言

  流媒体的定义很广泛,大多数时候指的是把连续的影像和声音信息经过压缩处理后放上网站服务器,让用户一边下载一边观看、收听,而不需要等整个压缩文件下载到自己机器就可以观看的视频/音频传输、压缩技术。流媒体也指代由这种技术支持的某种特定文件格式:压缩流式文件,它通过网络传输,并通过个人电脑软件进行解码。

  MCI是微软为Windows最初提出的多媒体编程接口,随着多媒体技术的迅速发展,各种压缩算法在该领域的的应用,MCI技术越来越显的力不从心,最明显的是它不支持可变比特率的压缩算法,对于处理DVD等近年出现的多种新的媒体格式已显得无能为力,而使用微软提供的vfw之类的多媒体库又太麻烦。怎么办呢?
作为MCI的"接班人",微软又适时推出了建立在DirectX(包含DirectDraw、DirectSound、Direct3D)之上的DirectShow技术,它是在DirectX之上的媒体层,支持来自本地或网络的各种视频、音频压缩格式的媒体文件的解码和回放,可以从设备上捕捉多媒体流,也可以处理各种压缩算法处理的流媒体。这些格式包括:MPEG的音频和视频标准、音频和视频交互标准(AVI)、WAVE、MIDI和高级流格式ASF。DirectShow对媒体数据处理采用流媒体(Multimedia Stream)的方式,在应用中使用该方式可以大大的减少编程的复杂程度,同时又可以自动协商从数据源到应用的转换,流接口提供了统一的、可以预测的数据存取的控制方法,这样应用程序在播放媒体数据时不需要考虑它最初的来源和格式。
 
  二、理解DirectX

  DirectX是一个用于多媒体应用程序和硬件增强的编程环境,它是微软为了将其Windows建设成适应各种多媒体的最好平台而开发设计的。DirectX目前已经成为微软自身SDK的一部分,而Windows 98/Windows 2000内则集成了DirectX,表明它已成为操作系统的一部分。

  DirectX技术是一种API(应用程序接口),每个DirectX部件都是用户可调用的API的总和,通过它应用程序可以直接访问计算机的硬件。这样,应用程序就可以利用硬件加速器(Hardware Accelerator)。如果硬件加速器不能使用,DirectX还可以仿真加速器以提供强大的多媒体环境。

  为了理解DirectX,我们可以把系统分为四层:

  ●硬件/网络层:放置有多媒体设备,包括图形加速器、声卡、输入设备以及网络通信设备等;

  ●DirectX基础层:为图像、声音和设备提供多媒体基本服务;

  ●DirectX媒体层:为动画制作、音频和视频等提供API功能;

  ●组件层:包括ActiveX控制和应用,它利用DirectX的API功能的优势为用户提供多媒体服务。

  DirectShow就是建立在DirectX媒体层之上的技术,其前身是ActiveMovie2.0。它以一组API函数或ActiveX控件出现,用途是让开发者能够在网络上传递高质量的音频和视频信号。值得一提的是,DirectShow为我们提供了一个开放式的开发环境,我们可以根据自己的需要定制组件。

  三、DirectShow技术结构

  DirectShow定义了如何利用标准组件来处理流媒体数据,这些组件称为过滤器。过滤器带有输入、输出针角(pin),或二者兼而有之。在DirectShow技术中处于最核心位置的就是作为"过滤器"的可插入标准组件,它是执行特定任务的COM对象。过滤器又可被细分为源过滤器(Source filter)、变换过滤器(Transform filter)、表现过滤器(Renderer filter)等。过滤器通过向文件读写、修改数据和显示数据到输出设备上来操作流媒体。为了完成整个任务,必须要将所有的过滤器Filter连接起来,这三种过滤器组成了过滤器图表结构,如图3.1所示:


图3.1 过滤器图表结构(Filter Graph)


  从图3.1中可以看出,过滤器图表是各种过滤器的集合,它是通过过滤器的输入输出针脚"pin"顺序连接而成的,这些过滤器的针脚通过协商来决定它们将支持何种形式多媒体。由于DirectShow支持可重构的过滤器图表结构,所以使用相同的软件组件可以播放多种类型的媒体。开发人员可以通过定义自己的过滤器来扩展DirectShow对媒体的支持功能。

  在过滤器图表结构中,源过滤器用来从数据源获取数据,并将数据传送到过滤器图表中,这里的数据源可以是摄像机、因特网、磁盘文件等;转换过滤器用来获取、处理和传送媒体数据,它包括分离视频和音频的分解变换过滤器(Splitter transform filter)、解压视频数据的视频转换过滤器(Video transform filter)、解压音频数据的音频转换过滤器(Audio transform filter);表现过滤器用来在硬件上表现媒体数据,如显卡和声卡,或者是任何可以接受媒体数据的地方,如磁盘文件。它包括用来显示图像的视频表现过滤器(Video renderer filter)、将音频数据送到声卡上去的音频表现过滤器(Audio renderer filter)。

  在过滤器图表中,为了完成特定的任务,必须将所有需要的过滤器连接起来,因此前级过滤器的输出必定成为下级过滤器的输入。一个过滤器至少有一个输入针(Input pin),并将特定的输出送到输出针(Output pin);图3.2显示了一个过滤器连接图:


3.2 过滤器连接图


  你的应用程序不需要对过滤器图表中的各个过滤器进行单独的处理,因为在更高的层次上,DirectShow提供的一个称为过滤图表管理器的部件(FGM)管理着这些过滤器的连接和流媒体数据在过滤器之间的流动,FGM提供了一套COM接口,应用程序可以通过它来访问过滤器图表、控制流媒体或者接收过滤器事件。如果需要,它可以自动的插入一个合适的解码器,并将转换过滤器的输出针脚连接到表现过滤器。应用程序可以通过与过滤图表管理器的通信来控制过滤器图表的活动。程序开发人员只需要调用API函数来实现对流媒体的控制,如run方法启动流媒体在过滤器图表(Filter graph)中的流动;pause方法暂停流媒体的播放;stop方法停止播放流媒体等。

  另外,利用Filter Graph Manager能够将事件信息传送到应用层这一特点,可以使应用程序可以响应事件处理,例如播放或搜索流媒体中的特定时间段的数据、流结束信息等。

  图3.3是一个MPEG解码播放的实例,可以看出Source filter将获取的多媒体数据通过Outpin送到MPEG分解转换过滤器,MPEG分解转换过滤器有一个输入针脚,两个输出针角分别将视频和音频解释码器进行解码,最后两路数据分别通过视频表示过滤器、音频表示过滤器送到显卡和声卡进行回放。


图3.3 MPEG解码实例

 

四、DirectShow程序开发

  DirectShow建立在COM组件技术基础上,所以开发DirectShow程序必须要掌握COM组件技术。DirectShow与COM紧密相连,它所有的部件和功能都由COM接口来构造和实现,其开发方式相当灵活,没有固定的模式,通常随不同的需要使用不同的COM接口。但是其中几个重要的接口确实经常需要用到的:IGraphBuilder接口,这是最为重用的COM接口,用来创建Filter Graph Manager;IMediaControl接口,用来控制流媒体在滤波器图表(Filter Graph)中的流动,例如流媒体的启动和停止;IMediaEvent接口,该接口在Filter Graph发生一些事件时用来创建事件的标志信息并传送给应用程序。

  一个典型的DirectShow应用程序的开发通常遵循的步骤为:

  1)通过API函数CoCreateInstance()创建一个Filter Graph Manager 实例;

  2)通过调用QueryInterface ( )函数来获取Filter Graph 和IMediaEvent组件的指针;

  3)对Filter Graph进行控制和对事件作出响应。

  下面举一个简单的例子来说明如何利用DirectShow技术对多媒体流进行解码回放的。首先生成一个名为MediaPlay的单文档应用程序,定义一个名字为MediaPlay的函数,该函数的具体实现代码为:

void PlayMovie(LPTSTR lpszMovie)
{
 IMediaControl *pMC = NULL;
 IGraphBuilder *pGB = NULL;
 IMediaEventEx *pME = NULL;
 long evCode; // something to hold a returned event code
 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
 IID_IMediaControl, (void **)&pMC);
 hr = pMC->QueryInterface(IID_IGraphBuilder, (void **)&pGB);
 hr = pMC->QueryInterface(IID_IMediaEventEx, (void **)&pME);
 hr = pGB->RenderFile(lpszMovie, NULL);
 hr = pMC->Run();
 hr = pME->WaitForCompletion(INFINITE, &evCode);
 if(pMC)pMC->Release();
  if(pGB)pGB->Release();
   if(pME)pME->Release();
}

  上述代码中,CoCreateInstance()函数创建了一个过滤器图表(Filter Graph)对象,并返回一个媒体控制(ImediaControl)接口,这个接口通过过滤器来实现播放、暂停、停止等媒体放映功能,但是这时候图表对象并不包含具体的过滤器,因为此时DirectX并不清楚需要播放何种类型的媒体;接下来创建一个图表构建接口,该接口可以实现创建过滤器图表、向图表对象添加、删除各种过滤器、列举当前过滤器图表中所有的过滤器、连接图表对象中的各个过滤器等功能;本例中使用了IGraphBuilder 接口的RenderFile()函数,告诉DirectX需要播放的媒体文件名,此时IgraphBuilder对象接口根据多媒体文件的类型,自动向过滤器图表添加播放该类型媒体所需的的各种过滤器,并实现其连接。

  最后,函数调用ImediaControl接口对象的Run()函数,就可以开始播放媒体文件了。为了实现从头至尾的顺序播放完多媒体文件,需要调用IMediaEventEx 对象接口的WaitForCompletion()阻塞函数的运行,直到媒体文件结束后才可以释放对象、结束函数的运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/455271.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汕头市队赛 SRM16 T2

描述 猫和老鼠,看过吧?猫来了,老鼠要躲进洞里。在一条数轴上,一共有n个洞,位置分别在xi,能容纳vi只老鼠。一共有m只老鼠位置分别在Xi,要躲进洞里,问所有老鼠跑进洞里的距离总和最小是…

C#调用WebService实例和开发(转)

http://www.cnblogs.com/peterpc/p/4628441.html 一、基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件…

智能情绪分析技术_简单分析人工智能的表现在计算机网络应用技术中的优势

简单分析人工智能的表现在计算机网络应用技术中的优势大数据时代背景下, 计算机网络技术迅猛发展, 而人工智能技术的发展也进一步推动了计算机网络技术的发展, 两者相互融合, 相互促进, 实现了双赢发展。从人工智能技术…

MV预测过程详解

第一步:确定相邻块 MV 预测以宏块分割(或亚宏块分割,如果宏块存在亚分割)为单位,同一个宏块分割(或亚宏块分割)内所有 4*4 块 MV 预测值相同。以每个宏块分割(或亚宏块分割&…

Zabbix2.2.6邮件报警设置方法

http://www.jb51.net/article/56973.htm 这篇文章主要介绍了Zabbix邮件报警设置方法,在Zabbix服务端设置邮件报警,当被监控主机宕机或者达到触发器预设值时,会自动发送报警邮件到指定邮箱说明:Zabbix监控服务端、客户端都已经部署完…

matlab 矩阵拼接

E[a,b]%水平方向上的拼接 E[a ;b] %垂直方向上的拼接 转载于:https://www.cnblogs.com/hsy1941/p/7124083.html

Machine Learning——octave矩阵操作(2)——DAY3

矩阵的数学操作: Assumed: a为一个矩阵,m是一个向量 Log(a)——求每一个元素的对数 Exp(a)——以e为底的指数 1./a——求每个元素的导师 [a,b]max(m)——m是一个向量,a为m当中最大的元素,b为a在m中的排列序号(已按从小…

字符串中文判断

2019独角兽企业重金招聘Python工程师标准>>> 1、判断字符串是否全是中文或含有中文 <?php header(Content-type:text/html; charsetutf-8); $str 你好; if(preg_match(/^[\x{4e00}-\x{9fa5}]$/u, $str)>0){ echo 全是中文; …

分治2--取余运算

分治2--取余运算 一、心得 二、题目和分析 题目描述 输入b&#xff0c;p&#xff0c;k的值&#xff0c;求bp mod k的值。其中b&#xff0c;p&#xff0c;k*k为长整型数。输入 三个整数&#xff0c;分别为b&#xff0c;p&#xff0c;k的值输出 bp mod k样例输入 2 10 9样例输出 …

-mysql-锁机制分为表级锁和行级锁

2019独角兽企业重金招聘Python工程师标准>>> 声明&#xff1a;本栏目所使用的素材都是凯哥学堂VIP学员所写&#xff0c;学员有权匿名&#xff0c;对文章有最终解释权&#xff1b;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 mysql锁机制分为表级锁和行级锁 …

托福试卷真题_干货解答考生疑惑,自考真题考过了还会在出吗?

重视真题&#xff01;重视真题&#xff01;重视真题&#xff01;重要的话要说三遍。想自考的你们一定要注意&#xff0c;对于历年真题&#xff0c;从来都是“备考必做”的态度。做自考真题&#xff0c;除了可以让自己尽快熟悉考试题型和考点外&#xff0c;还有什么好处呢&#…

2016 ACM/ICPC Asia Regional Dalian Online

自己还是太菜&#xff0c;补题离不开题解。。。 但还是留个博客&#xff0c;万一以后忘了。。。 1001 Different Circle Permutation Polya定理&#xff0c;第一次遇见&#xff0c;学习了一下。不旋转的时候可以得到 f[i]f[i-1]f[i-2] 斐波那契数列&#xff0c;旋转后就可以通过…

天融信安全接入客户端_天融信提示您警惕物联网设备Ripple20漏洞风险

近日&#xff0c;天融信阿尔法实验室在JSOF实验室发布的由Treck公司开发的TCP/IP软件库中获取到一系列0day漏洞。JSOF实验室发布的这批漏洞共计19个&#xff0c;被JSOF研究人员称为"Ripple20"。受此软件库影响的产品数量估计超过数亿&#xff0c;其中包括智能家居设备…

GreenSock (TweenMax) 动画案例(二)

实现效果 动画分解 1.灯光闪烁2.文字出现3.水流4.心电图 知识点 1.AI(可尽情骚扰UI欧巴)2.SVG(了解基本的知识点)3.TweenMax(GreenSock)4.CSS animation 写在前面 写过第一篇文章后GreenSock (TweenMax) 动画案例(一)再回头看发现代码太多&#xff0c;根本没耐心去看完。所以每…

无限轮播图片的实现原理

无限轮播图相信是很多开发人员常用的一个功能&#xff0c;这里总结一下常用的两种方式的实现原理 一、使用UIScrollview实现无限轮播用UIScrollView实现&#xff0c;在scrollView上添加3个UIImageView&#xff0c;分别用来显示上一张图片&#xff0c;当前显示的图片&#xff0c…

开启 JM 的 trace 功能

[JM代码] 开启 JM 的 trace 功能本帖最后由 firstime 于 2009-6-15 11:16 AM 编辑 城里汉子说过&#xff1a; trace文件对分析码流结构很有效。我说的是trace文件&#xff0c;不是一步一步跟踪&#xff0c;就是编解码同时生成的 trace_enc.txt 这个文件&#xff0c;里面对每个比…

kafka入门介绍(转载)

Kafka作为一个分布式的流平台&#xff0c;这到底意味着什么&#xff1f; 我们认为&#xff0c;一个流处理平台具有三个关键能力&#xff1a; 发布和订阅消息&#xff08;流&#xff09;&#xff0c;在这方面&#xff0c;它类似于一个消息队列或企业消息系统。 以容错的方式存储…

Cmd Markdown 编辑阅读器

欢迎使用 Cmd Markdown 编辑阅读器 我们理解您需要更便捷更高效的工具记录思想&#xff0c;整理笔记、知识&#xff0c;并将其中承载的价值传播给他人&#xff0c;Cmd Markdown 是我们给出的答案 —— 我们为记录思想和分享知识提供更专业的工具。 您可以使用 Cmd Markdown&…

Ubuntu GitLab CI Docker ASP.NET Core 2.0 自动化发布和部署(1)

相关博文&#xff1a; Ubuntu 简单安装和配置 GitLabUbuntu 简单安装 DockerUbuntu Docker 简单安装 GitLabUbuntu Docker 安装和配置 GitLab CI 持续集成服务器版本 Ubuntu 16.04 LTS。 经过上面四篇博文中的相关安装和配置&#xff0c;我们主要完成了两个容器的创建和运行&am…

django-ckeditor表情包修改

一、版本 Django1.11django-ckeditor5.2.2 二、关键步骤 1.删除旧的ckeditor静态文件 所在目录&#xff1a;项目目录下的static文件夹下的ckditor文件夹 rm ckeditor -rf 原因&#xff1a;在安装ckeditor后需要执行collectstatic命令&#xff0c;这个过程中的查找静态文件会去…