QuickTime Component实例(一)

原创 2005年05月29日 15:15:00

引 言

  此处介绍的QuickTime Component在原理上和拙文《Mac OS的Component技术简介》中的描述没有冲突,只是作为一种特例,加上QuickTime本身的一些特性,组织形式上有些区别,这些区别不是本质的。本文引用的实例是Apple官方网站上的示例程序:Electric Image Component。它是用于处理Electric Image(文件扩展名为EIM)的一个典型的QuickTime的Component(插件)。
  这个例子有两大优点:
  一、内容全面,包括静态图像的导入导出插件Image Importer和Image Exporter,静态图像的编解码插件Image Codec,活动图像导入导出插件Movie Importer和Movie Exporter。
  二、提供的示例是跨平台的,通过在Windows下安装QuickTime SDK可以编译测试(一般使用VC 6.0或VC .NET),生成名为"ElectricImageWindows.qtx"的插件,供Windows下的基于QuickTime的应用程序使用。

第一节 Image Importer和Image Exporter

  在本例程中,Image Importer和与之密切配合的Image Decompressor分别对应EI_GraphicsImport和EI_ImageDecompressor两个文件夹的源程序。这两部分可以从整个插件组中剥离出来独立工作,它们完成对静态图像的读取和解码。和完整的插件包一样,在Windows下编译生成插件,在NT系统下复制到"%SystemRoot%/System32/QuickTime"子目录下,就能用QuickTime 6 for Windows播放程序(可在Apple的官方网站免费下载)[1]打开Electric Image静态图像文件。
  需要注意的是,一般Image Importer数据导入后,是经过Decompressor绘制到显示端,这不同于导出压缩数据是直接在Image Exporter里进行。而在Decompressor中是对一个缓冲进行操作。事实上Decompressor是Still Image Codec的一个特例,在本例中,只实现了DrawBand,它正完成了上述的解码绘制的工作。而BandCompress和BandDecompress两个request handler(一称selector)均没有实现,它们完成的是码流的压缩和解压,这样编解码工作就能方便其他Comoponent调用。
  压缩数据,一般从静止图像文件中读取,由QuickTime默认的程序导入。在Image Importer中一个重要的request就是GetDataOffsetAndSize,它的handler向调用者返回图像有效数据的起始偏移和大小。它从基组件的同名request handler中得到偏移和大小,这一般分别就是文件的起始偏移(0)和文件大小,然后根据图像格式需要进行修改。而这个request不仅供一般调用者使用,在Decompressor中也将以此处指定的起始偏移规定的范围为准进行操作。Image Importer中另一个重要的request是GetImageDescription,在这个request的handler中要完成对ImageDescription结构的生成,这在Decompressor解码中也是必须的。
  Decompressor解码过程主要在名为DrawBand的request handler中进行,需要注意的是,QuickTime并不一定将全部的压缩数据都导入内存,而是只先导入指定尺寸的数据。所以数据馈送必须不断调用API函数InvokeICMDataUPP完成,用户可以指定每次馈送数据的大小,但不能低于上述的指定尺寸。
  Image Exporter相对简单,在其中的名为DoStandaloneExport的request handler中完成主要的导出工作,包括编码,此处编码的输入和输出均完全是对已分配内存的操作。

第二节 Movie Importer和Movie Exporter

  Movie Importer完成非QuickTime标准MOV规格的电影(视频或音频)数据的导入和整理。对于QuickTime标准规格的影片事实上并不需要通过Importer的支持而能直接为QuickTime所播放。QuickTime规格以Movie-Track-Media-Sample为主要层次结构的电影控制结构为核心。标准规格文件保存了这个控制结构的数据并能直接被QuickTime解析,从而不需要Importer;非标准的自定义文件格式(包括其他组织定义的如AVI、WMV、MPG、RM等)需要Importer完成解析并相应地建立上述控制结构而后递交QuickTime方能完成导入。这样对非标准文件格式,Exporter则调用QuickTime API获取源端播放音视频数据。由于它们已在QuickTime内部播放,因而显然也是以这种控制结构组织的。随后Exporter将数据根据格式需要输出,从而可形成一个非标准的电影文件,从而完成Importer的逆向工作。
  当然如选择以MAC为主要平台,更一般的需要是制作标准规格的MOV文件。而区别于各标准MOV格式的是其内部编码方式,这也就是我们制作Component的意义所在。根据上述讨论,很显然,需要在Exporter端承担更多的Importer端的工作即建立控制结构并落实到最终的输出中,这些也主要通过调用QuickTime API得以实现。
  值得注意的是对于Exporter端的编码工作本身,QuickTime支持了编码器编码(调用Codec组件)、直接编码(Standalone方式)和可能的转码(Transcode方式,对于特定支持的导入导出组合,采用不经过解码的直接变换),可满足各种需要。本处的Electric Image Component无论是Graphics Exporter还是Movie Exporter均采用Standalone方式,所以编码工作在Exporter代码中可见。

第三节 Media Handler

  Media Handler是一种重要的QuickTime Component,它主要涉及媒体播放时的具体操作。从前面的叙述可知,Importer并不对播放作任何处理,只是做数据的收集,所以播放过程就交给各种Media对应的Media Handler进行处理。QuickTime针对大多数媒体定义了相应的Media Handler,所以用户很少会有必要编写一个Media Handler,即所谓的Derived Media Handler。例外的情况主要有:
  一、要面对一种新型的Media类型,当然,这是一种数据类型,但是必须是基于时间的(Time-based),这其实是QuickTime的处理对象的抽象定义。例如:Flash、某些有帧间相互关系的媒体类型等。
  二、对一些特殊的传输介质的不同处理。例如某些网络协议,存储结构等,但在这种情况下首先应该改写另一种QuickTime的Component——Data Handler。
  三、对一个已有的默认处理不满意。例如笔者遇到的需要对数据文件进行截取的情况。
  Media Handler在QuickTime的架构中是出于Toolbox之下,Data Handler之上。他供ToolBox调用以实现播放,而数据访问则通过Data Handler。
  编写Derived Media Handler一般在Open的处理中要设置Base Media Handler,一般它的Subtype设为BaseMediaType。笔者发现对于派生Video类的Media Handler,如果选择VideoMediaType为Subtype的Handler作Base Handler,会绕开本身的处理,其原因还不明。
  Media Handler中最主要的request是Idle,它在QuickTime认为适当的时候就会调用。几乎所有的操作都是在响应这个request的函数中完成。对于处理Video的Media Handler而言,最一般的情况就是在这个函数中解码并显示(一般调用QuickDraw)规定时间位置的帧。
  在Media Handler中可以得到大量的播放参数,所以有极大的灵活度。如播放环境,影片数据等都是透明的,甚至可以获取合适的参数,绕开Data Handler,直接用C标准函数对影片文件进行操作。

  (完)

注释:
[1] 某些常用的通用播放器如MPC由于并不使用Windows下的QuickTime架构,而只是采用了自身的QuickTime插件播放MOV格式影片,所以它们与此处的所有讨论完全无关。

[zz]QuickTime电影(Movie)

文件格式  Apple公司的QuickTime电影文件现已成为是数字媒体领域的工业标准。 QuickTime电影文件格式定义了存储数字媒体内容的标准方法,使用这种文件格式不仅可以存储单个的媒体内容(如...
  • jinbing
  • jinbing
  • 2005年07月05日 15:59
  • 3093

[zz]QuickTime SDK编程

第一节 QuickTime流式传输   QT流是通过网络将视频从服务器发送到客户的传输方式。与文件传输不同,客户端边下载边播放,而不必等到下载完毕。服务器将视频内容分成包,通过网络发送出去;在接收端,...
  • jinbing
  • jinbing
  • 2005年07月05日 16:04
  • 3890

SpringMVC开发@Component注解类被两次实例化问题分析与解决

需要写一个Job类,思路是利用Job实例初始化的时候启动一个ScheduleExecutorTask,定时update一些东西。 @Component("RefreshJob") public cl...

RESTLET开发实例(二)使用Component、Application的REST服务

一、基于ServerResource的REST,来实现JAX-RS中get方法。 1、新建RestApplication Web工程。 然后把相应的restlet的lib下的全部jar加入工程...

java report component开发实例

  • 2010年05月12日 09:20
  • 175KB
  • 下载

创建可以重复利用的QML Component--Podcast播放器代码实例

在我们设计QML应用时,很重要的一点就是设计一个可以被重复利用的软件Component.它可以反复在其它的应用中被利用.这如同在我们的C++及其它语言中设计自己的应用一样,我们可以创建自己的模块.只需...

关于Unity中不用安装QuickTime播放视频的方法

前言由于Unity中能够识别的视频格式主要有:.mov, .mpg, .mpeg, .mp4, .avi, .asf,但是其实最后这些格式的时候在导入到Unity中的时候,都会再进行一次Unity内部...

从QuickTime到Beats:回顾苹果历史上的音乐传奇

随着收购的尘埃落定,苹果CEO库克的手终于和Beats的创始人Dr.Dre和Jimmy Iovine的手握在了一起。这也标志着,苹果在耳机设备和流媒体音乐方面又向上迈了一个台阶。   苹果作为掀起数...

MAC上QuickTime截取音乐片段/iphone换铃声

1.--------iPhone支持的铃声格式为.m4r;可以直接把.mp3改成.m4r; 2.-----剪辑歌曲,铃声最长40秒的时间--------打开quicktime,选择要剪辑的歌曲; ...

苹果发布了QuickTime Windows版本的安全升级补丁

苹果发布了QuickTime Windows版本的安全升级补丁   随着苹果发布了一个能修复多重安全漏洞的补丁,苹果要求Windows用户升级他们的QuickTime。   QuickTi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:QuickTime Component实例(一)
举报原因:
原因补充:

(最多只允许输入30个字)