基于Directshow的H.264流媒体播放器设计
因此,为了传送流媒体数据,必须使用面向连接的可靠的传输协议(TCP)。客户端与服务器端的控制与反馈消息,则可以使用(UDP)来传输。服务器端首先创建一个侦听Socket,侦听来自客户端的连接请求。一旦侦听到客户端的请求,服务器端就创建一个用于数据传送的Socket,并绑定到请求连接的客户端,此时,服务器处于数据传送的就绪状态。当客户端发出命令,服务器再根据命令的类型执行相应的操作,如数据发送、停止、断开连接等。
在服务器端首先将连续的H.264流分成一块一块小包的负载数据,并且加上一个信息头一起使用TCP协议发送;在客户端根据信息头描述,将小包的负载数据进行拼装,然后进行H.264的解码播放。Socket数据传送结构为:负载类型(8bit)、负载数据长度(16bit)和负载数据包(2324Byte)。
客户端的实现可以参考SDK中的MEMFileFilter,直接从SDK例子将asyncrdr.cpp、asyncrdr.h、asyncio.cpp、asyneio.h四个文件拷贝过来,然后在MemFilter.h文件中从CAsyncStream派生流处理类CMemStream,定制数据源并进行数据的读取操作;从CAsyncReader派生滤波器类CMemReader,实现含1个输出PIN的SourceFilter框架,完成与SplitterFilter的连接。
网络源滤波器类间数据流程如图2,下一级Filter“拉”线程数据流程如图3。其中:CAsyneStream用以标示数据流;CAsyneRequest标示输入与输出请求;CAsyncIo实现数据输入和输出的控制。编程主要实现CMemStream:Read()函数以实现从特定的数据源读取数据到下一级Filter的Sample中。
该滤波器工作于Splitter和Rendererfilter之间,包含一个输入和一个输出,且输入和输出pin上的媒体类型不一致,故选择CTrans-formFilter作为基类,派生子类CX264Decode。
ffmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。利用ffmpeg中的Libavformat和libavcodec库访问大多数视频文件格式是一个很好的方法。将ffmpeg中关于h.264解码的操作封装为C++类,供H.264解码Filter调用以实现解码功能。
子类CX264Decode必须要实现的纯虚函数有:CheckInputType()实现输入Pin上的媒体类型检查;CheckTransform()检查是否支持从该输入pin到输出pin的变换操作;DecideBufferSize()决定Samlple内存的大小;GetMediaType():提供输出Pin上的首选媒体类型;Transform():实现解码变换。
子类CX264Decode可选的重写虚函数有:初始化和反初始化流:StartStreaming()和StopStreaming();响应质量通告消息:AlterQuali-ty();获取媒体类型被实际设置的时间:SetMediaType();连接时获取额外的接口:CheckConnect()、BreakConnect()和CompleteConneet();定制变换过程:Receive();标准化设置输出Sample:InitializeOutputSample()。
本Filter设计主要流程如下:
(1)Filter注册信息
定义类工厂模板,填写Filter的注册信息;同时实现DLL文件所必须实现的注册和反注册函数:DLLRegisterServer和DLLUnregisterSe-rver。
(2)框架函数的实现
实现函数CreateInstanee,用于创建Filter对象实例;实现函数CheeklnputType,用于对输入Pin上的媒体类型检查;实现函数Transfo-rm,用于H.264的解码操作;实现函数NonDelegafingQueryIntefface,用于暴露Filter支持的自定义接口,使应用程序可以设置解码器的参数;实现函数CompleteConnect,可以在输入Pin成功连接后取得媒体类型描述,并将输入数据的格式设置给应用逻辑控制对象;实现函数St-artStreaming和StopStreaming,可以分别调用应用控制逻辑对象的相应函数,进行流处理的初始化和反初始化操作。
(3)逻辑控制类的实现
逻辑控制类是本Filter设计的核心,框架函数和自定义接口函数的相关操作都是委托给逻辑控制类来实现的。该类实现了H.264.的解码参数的设置与解码操作,主要调用封装了H.26 4解码的C++类来实现。
利用ffmpeg库进行H.264解码时,需要自定义两个关键函数:open_net_file()和read_buffer_frame()。其中,open_net_file()函数完成与流媒体服务器的连接,接收指定流媒体文件的流相关信息,并返回类型为AVFormatContext结构体的值。read_buffer_frame()函数从bu-ffer缓冲中读取一帧数据,并交由库函数avcodec_decode_video()解码。
(4)自定义接口的实现
将Filter类从自定义接口类派生,并声明自定义接口的所有接口方法;然后在Filter类的实现文件中实现这些接口法,其实大都是调用应用逻辑控制类的相应函数;最后在函数NonDelegatingQueryInteRFace中暴露我们的自定义接口。
3.4播放器的设计
播放器采用DirectsHow应
模拟电路 模拟芯片 德州仪器 放大器 ADI 模拟电子 相关文章:
- 12位串行A/D转换器MAX187的应用(10-06)
- AGC中频放大器设计(下)(10-07)
- 低功耗、3V工作电压、精度0.05% 的A/D变换器(10-09)
- PIC16C5X单片机睡眠状态的键唤醒方法(11-16)
- 用简化方法对高可用性系统中的电源进行数字化管理(10-02)
- 利用GM6801实现智能快速充电器设计(11-20)