版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、vlc播放器架构2014播放器简述包含内容播放器的基本原理介绍sk_media播放器介绍vlc播放器基本架构介绍一般情况下,播放一个音视频分为4个步骤:1). acess 访问2). demux 解复用3). decode 解码4). output 输出一.播放器的基本原理介绍可以理解为接收、获取、得到数据资源,包括解析访问源(url)、使用http协议(ftp、rtsp协议.)建立连接、获取数据等。acess :访问demux :解复用就是把通常合在一起的音频和视频分离(还有可能的字幕),通过分析数据包头来判断是什么数据文件,需要用什么解码格式。为什么需要demux其实之所以需要demux,
2、是因为音视频在制作的时候实际上都是独立编码的,得到的是分开的数据,为了传输方便必须要用某种方式合起来,这就有了各种封装 格式,也就有了demux。decode 解码包括音频和视频的解码,或者软件解码和硬件解码。output 输出分为音频和视频的输出(aout和vout) access部分负责从网络接收组播流,放到播放器的内存缓冲区中,access模块关注IP协议,如是否IPv6、组播地址、组播协议、 端口等信息;如果检测出来是RTP协议(RTP协议在UDP头部简单得加上了固定12个字节的信息),还要分析RTP头部信息。(对于VLC播放器,这部分可以参看VLC源码 /modules/access
3、/udp.c )。例如: 播放一个UDP组播的MPEG TS流而demux部分首先要解析TS流的信息。TS格式是MPEG2协议的一部分,一般,TS通常是固定188字节的一个packet,一个TS流可以包含多个program(节目),一个program又可以包含多个视频、音频、和文字信息的ES流;每个ES流会有不同的PID标示。而又为了可以分析这 些ES流,TS有一些固定的PID用来间隔发送program和es流信息的表格:PAT和PMT表。对于VLC播放器,使用库libdvbpsi来解析和编码TS流.(调用代码可以参见VLC源码 /modules/demux/ts.c。)demux分解出来的音
4、频和视频流分别送往音频解码器和视频解码器。因为原始的音视频都是占用大量空间,而且冗余度较高的数据,通常在制作的时候就会进行 某种压缩。这就是我们熟知的音视频编码格式,包括MPEG1(VCD)、MPEG2(DVD)、MPEG4、H.264、rmvb等等。音视频解码器的作用就是把这些压缩了的数据还原成原始的音视频数据。(VLC解码MPEG2使用了一个独立的库libmpeg2,调用它的源文件是 codec/libmpeg2.c。VLC关于编解码的模块都放在/modules/codec目录下,其中包括著名的庞大的 ffmpeg。)output模块,视频解码器输出的是一张一张的类似位图格式的图像,但是要
5、让人从屏幕看得到,还需要一个视频输出的模块。音频也是一样,需要将pcm等数据转化为声音二.sk_media播放器介绍sk_media播放器使用开源软件vlc_2.1.0(后面介绍)。sk_media播放器的解码部分,mp3(mpga)格式用软件解码,其它格式使用硬件解码,以便加快解码速度。sk_media播放器以插件的形式提供接口(sk_media.h)给浏览器和应用,以达到平台无关性。sk_media.h是公司提供的统一的播放器对外接口。1.sk_media播放器使用流程图及部分接口 2.简单的sk_media播放器demostatic int main_media_test ()int r
6、et;sk_media_t skplayer_service_data;char *url=NULL;int res; sk_media_init(NULL);ret = sk_media_create_player(&skplayer_service_data,NULL);url=93/HEAAC_128K_3sec.mp4;sk_media_player_set_file(skplayer_service_data,0,2,url,url); ret = sk_media_player_start(skplayer_service_data, 0, 1, 0); Sleep(10); sk
7、_media_player_stop(skplayer_service_data); sk_media_destroy_player(skplayer_service_data,NULL); sk_media_term(NULL);三.vlc播放器基本架构介绍vlc(Video Lan Client)设计框架结构。vlc是一个完整的多媒体框架(如DirectShow或GStreamer的),最大特点是可以根据需要动态加载许多插件模块,支持大量的音视频传输、封装和编码格式。框架核心就是用程序将各模块连接起来,对输入媒体数据 经过各模块处理后输出。1.VLC 源代码结构 2.module功能模块目
8、录树VLC建立在很多独立的功能模块上面的,象很多媒体播放器系统框架一样,每个模块实现一个新的功能 3.src模块目录介绍LibVLC是VLC的重要部分。它是一个提供接口的库,比如给VLC提供功能接口:流的接入,音频和视频输出,插件管理,线程系统。LibVLC源码位于src/及其子目录:Interface/:包含与用户交互的代码如按键和设备弹出。Playlist/:管理播放列表的交互,如停止、播放、暂停 、下一个,或者随机播放。Input/:打开一个输入组件,读包,解析它们并且将被还原的基本流传递给解码器。Video_output/:初始化video显示器,从解码器得到所有的图片和子图片(如su
9、btitles)。随意将它们转换为其它格式(如:YUV到RGB)并且播放。Audio_output/:初始化音频mixer(混合器)。如:发现正确的播放频率,然后重新制作从解码器接收过来的音频帧。Stream_output/:类似Audio_output。Misc/:被libvlc其它部分使用的杂项,如线程系统,消息队列,CPU探测,对象查询系统,或者特定平台代码。关于block_t结构 的一些功能也在其中(block.c),包括队列的存放、删除等。(如果做本地缓存可以考虑在block.c里处理)4.vlc常用名词 容器比较常见的容器格式包括AVI(.avi)、MPEG(.mpg, .mpeg
10、)、QuickTime(.mov)、RealMedia(.rm)、MP4(.mp4)、Matroska(.mkv)、Ogg Media(.ogg)等视频格式常见的有:MPEG-1/2/4,divx,h.263, H.264 / MPEG-4 AVC, wmv, mov,音频格式MPEG 1/2/3, AAC (MPEG4 part3), AC3 - A/52 (Dolby Digital),WMA ,FLAC, Real Audio 2, AMR (3GPP)视频输出DirectX、X11、XVideo、SDL、FrameBuffer、ASCIIUDP/RTP Unicast(单播),UDP/
11、RTP Multicast(组播),TCP/RTP Unicast,DCCP/RTP Unicast,HTTP / FTP, MPEG encoder,Video acquisition(视频采集)DVB,File访问输入控制界面Gtk、QT4、Web、Telnet、Command line、Lgui字幕文件内字幕,外挂字幕5.数据处理流程框架VLC由一个运行核(libvlc)和很多功能模块组成,很多功能都由模块提供.在目前vlc设计框架的基础上,将vlc中使用的demux模块, decoder模块, out模块, 置换成目前硬件平台支持的硬件demux, decoder, out模块,从而使
12、用硬件解码。demux, decoder 探测部分使用开源的ffmpeg 中的库文件。vlc播放器的数据处理流程框图 播放列表playlist对gui 页面提供统一接口,使用vlc 统一接口。Access网络或本地文件下载,移植vlc 支持的网络下载协议。-http、tcp/udp、RTSP/RTPdemux先按照给出的文件流类型,选择容器解析和demux解析。若无文件流类型,则使用探测的方式尝试。解析容器,使用软件ffmpeg提供的或其他插件提供等。对于音视频加扰的流,使用软件demux解码器可能会产生ca解扰问题,考虑使用硬件demux,不在讨论范围内。软件解码依赖ffmpeg提供库或其他
13、开放的源代码解码器。针对ts 流的格式的文件,vlc使用软件libdvbpsi 开源库。 如果使用硬件demux, 对于decoder模块,hdi需要提供独立操作的接口。decoder根据判断硬件支持情况,选择使用软硬件解码器,视频都使用硬件解码器,有些独立的音频播放可以使用软件解码器(mpeg audio layer 1/2/3 (mpga)。对于加扰的视频需另外增加处理。软件解码依赖ffmpeg提供库或其他开放的源代码解码器。 如果使用软件decoder, 对于out输出模块,hdi需要提供独立的音视频接口。output音视频模块,提供独立的可操作接口subtitle 外挂字幕软件解析后,
14、直接发送至输出接口。6.vlc调用内部接口运行过程附:直接调用vlc上api播放音视频demostatic void test_media_local(const char* argv, int argc) libvlc_media_t *md1, *md2, *md3, *md4; libvlc_instance_t *vlc; libvlc_media_t *md; libvlc_media_player_t *mp; const char * file0 = test_default_sample0;/file vlc = libvlc_new (argc, argv); md = li
15、bvlc_media_new_path (vlc, file0); mp = libvlc_media_player_new_from_media (md); libvlc_media_player_play (mp); sleep(100);1.首先程序调用libvlc_new(libcore.c)接口,实现创建一个VLC运行实例libvlc_instance_t,该实例在程序运行过程中唯一。2.在libvlc_new接口中,调用了libvlc_InternalInit函数实现具体的初始化工作.3.libvlc_InternalInit(srclibvlc.c)函数中,首先通过system_
16、Init函数完成传入参数对系统的相关初始化,接着通过module_InitBank(srcmodulesbank.c)函数初始化module_bank结构体,并创建了main模块,然后通过module_InitStatic载入静态模块,通过module_LoadPlugins(srcmodulesbank.c)函数载入动态模块.4.调用libvlc_media_new_path接口,载入播放节目单.5.在获取流时,通过调用stream_UrlNew(srcinputstream.c)函数完成对access、demux和path的解析。最后调用stream_AccessNew(srcinputs
17、tream.c)函数,创建stream_t结构体对象,并初始化对象中所有函数指针;6.再调用stream_Seek(includevlc_stream.h)内联函数,设置起始位置7.调用stream_Size(includevlc_stream.h)获得大小;8.调用stream_Read(includevlc_stream.h),读取到缓冲区;9.libvlc_media_player_play播放通过input_Create创建线程运行空间,input_Start中创建线程Run(srcinputinput.c)10.Run线程是整个VLC作为流媒体服务器的核心。其主要分为如下几个步骤:I
18、nit、MainLoop和End。其中MainLoop是一个无限循环,是完成流媒体的整个发布过程:a.首先调用Init(srcinputinput.c)函数,初始化相关统计参数;b.其次再调用input_EsOutNew(srcinputes_out.c)函数,初始化es_out_t结构体对象和es_out_sys_t结构体对象,并设置相关函数指针;c.再调用InputSourceInit(srcinputinput.c)函数,初始化input_thread_t对象中的input_source_t对象,主要有access_t、stream_t、demux_t三个结构体对象;d.再调用MainL
19、oop(srcinputinput.c)函数,完成读取、解复用、解码、复用和传输;e.MainLoop函数为无限循环,直到input_thread_t对象存在b_die、b_error、b_eof时为止。在该函数中,存在如下行代码:i_ret=p_input-input.p_demux-pf_demux(p_input-input.p_demux);它就是流媒体服务器运行的起点,所有的后续操作都会在该函数中继续衍生。f.pf_demux调用的是(modulesdemuxps)中的Demux函数,在该函数中主要完成如下操作:1).PS流中数据包重新同步2).再调用ps_pkt_read(modu
20、lesdemuxps.c)函数,最终调用stream_Block函数,这个函数内部会根据实际情况,调用stream_t模块中的pf_read或pf_block函数,函数结果会返回一个读取的buffer;3).根据数据包的i_code的值,做不同的处理,对于音视频数据流,调用es_out_Send(includevlc_es_out.h)函数处理;4.)es_out_Send一个抽象层函数,其通过函数指针,实际调用的是EsOutSend(srcinputes_out.c)函数;5.)EsOutSend函数最终会调用input_DecoderDecode(srcinputdecoder.c)函数;
21、6.)input_DecoderDecode函数会将数据发送到音视频队列fifo;7.)DecoderProcess里分别处理音视频的解码,硬件解码也可以在这里将数据注入到硬件(hdi)接口中。pf_demux函数为流媒体所有操作的起点,通过该处衍生了很多其他模块的处理VLC运行过程在PC上运行时,vlc(exe)先被动态加载,然后主线程就变成了接口线程并且在src/interface/interface.c中开始。它执行下列步骤:1.cpu探测?2.消息接口初始化;3.命令行选项解析组件4.创建播放列表5.仓库初始化6.加载所有内置和动态组件7.打开接口8.安装信号处理器:SIGHUP,SI
22、GINT和SIGQUIT(捕获一个,忽略后来的并退出)。9.派生音频输出线程;10.派生视频输出线程;11.主循环:事件管理; 7.VLC组件结构和加载组件位于modules子目录,在运行时被加载。每一个组件提供不同的特征适应特定的文件的环境。组件中的插件被位于srcmiscmodules.c和includemodules*.h中的函数动态加载和卸载。组件的API描述如下,共3种:(1)组件描述宏:声明组件具有哪种优先级的能力(接口,demux2等等),还有GUI组件的实现参数,特定组件的配置变量,快捷方式,子组件等等;(2)Open(vlc_objeet_t*p_object):(3)Clo
23、se(vlc_objeet_t*p_object):eg:vlc_module_begin () set_shortname( Matroska ) set_description( N_(Matroska stream demuxer ) ) set_capability( demux, 50 ) set_callbacks( Open, Close ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_DEMUX )vlc_module_end ()说明:1.vlc注册模块用的是一套标准模板,组件名“Matroska,_()可以
24、用来创建需要翻译的字符串,类型demux。set_capability的50参数表示该插件的优先级,越大越可能被使用,如果是0的话就不会自动使用,只能手动强制使用。如果VLC需要装载某一类型的功能模块(如解码器),VLC将装载所有的具有该能力的模块,按照匹配分数降序排列,然后调用Open()函数,如果返回VLC_SUCCESS,结束。set_callbacks( Open, Close ),这个很关键,其实是告诉vlc开始播放的时候调用Open,结束播放的时候调用Close。2.消息映射宏vlc_module_begin();.vlc_module_end();3.配置分类包括:CAT_INT
25、ERFACECAT_AUDIOCAT_VIDEOCAT_INPUTCAT_SOUTCAT_ADVANCEDCAT_PLAYLIST同时,也可以使用某一个子类进行配置。所有的配置分类和子类的定义,参考include/vlc_config_cat.h include/vlc_configuration.h(2)static int Open ( vlc_object_t * );VLC运行核尝试打开模块的时候,将调用该函数,进行模块装载。在Open函数里面,设置各种结构,设备或I/O。可以正常打开的函数将返回VLC_SUCCESS。否则,将认为装载失败。Open函数里面还进行私有数据的分配(如有)
26、,对私有结构进行设置。如果打开失败,需要用户自己清理结构里面的资源。被VLC调用初始化这个组件,它被组件描述宏赋值给了结构体module_t中的pf_activate函数指针,被Module_Need调用;Open里面主要的工作就是设置另外几个回调函数以及绑定上面定义的私有数据结构,设置回调函数(如control)、绑定私有数据等:p_demux-pf_demux = Demux;p_demux-pf_control = Control;(3)static int Close ( vlc_object_t * )VLC运行核尝试关闭或卸载模块的时候,调用Close函数。在关闭函数里面,将清理一
27、些数据结构,I/O或设备。同时,关闭函数也释放一些私有数据。Close比较简单,主要工作是释放自己的私有数据被VLC调用负初始化这个组件,保证消耗Open分配的所有资源。它被组件描述宏赋值给了结构体module_t中的pf_deactivate函数指针,被Module_Unneed调用。(4)用LibVLC写的组件能够直接被编译进VLC,因为有的OS不支持动态加载代码。被静态编译进VLC的组件叫做内置组件。(5)模块类型根据模块的能力的类别不同,需要实现的函数或方法也不一样,用户可以在相应的模块分类里面找到更多的信息。下面是一些主要的模块类别清单:Access/获取Demux/解复Access
28、_Demux / 获取并解复Decoder/解码Interface/用户界面Videofilter / 视频滤波Audiofilter /音频滤波Audio output /语音输出8.vlc组建仓库功能函数在启动的时候,VLC创建一个包含所有插件接口(.so和内置插件)的仓库,每一个插件都会被检查其实现的功能(见vlc_modules.h)管理这些插件的API如下:Module_InitBank:创建组件仓库,然后调用module_LoadMain将主程序信息导入组件银行。Module_LoadMain:将主程序信息导入组件仓库。Module_LoadBulltins:加载所有内置组件。Mo
29、dule_Loadplugins:加载所有动态组件。Module_EndBank:清空组件仓库。Module_ReSetBank:通过卸载所有无用的动态(插件)组件,重置组件仓库。Module_EndBank:卸载所有动态(插件)组件,清空模仓库。Module_Need:得到能力最符合要求的组件。Module_Unneed:减少一个组件的引用计数,必须被Module_Need的同一个线程调用。9.数据访问模块(access)access数据访问的输入和输出函数实现VLC大部分的基本IO功能。这些通常是一些协议如 (http,ftp,.)或一些设备访问如网络摄像头,图像采集卡。set_capab
30、ility( access, 60 ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_ACCESS )结构定义:ssize_t (*pf_read) ( access_t *, uint8_t *, size_t );block_t *(*pf_block)( access_t * );int (*pf_seek) ( access_t *, uint64_t );int (*pf_control)( access_t *, int i_query, va_list args);如果采用的协议返回未知大小的数据块,Block类型
31、比较合适。如果能够控制给采用的协议的数据大小,Read类型比较合适.实现的函数除了实现Open() 和Close()函数以外,还需要实现几个主要的数据访问类模块的函数。在include/vlc_access.h定义了下面几个函数:Seek, pf_seek 指针指向的函数。Control, pf_control 指针指向的函数。Seek原型:int (*pf_seek) ( access_t *, uint64_t );数据位置定位函数可以根据请求随时调用。该函数的参数为模块指针和请求的位置。注意:如果制定的协议或设备不支持数据位置定位功能,该可以为空。如果函数正常工作,需要将 p_acces
32、s-info.b_eof设置为false.返回值:如果函数运行成功,返回VLC_SUCCESS,否则,返回VLC_EGENERIC.Control原型:int (*pf_control)( access_t *, int i_query, va_list args);控制函数非常简单,运行核将使用下面的参数对模块进行查询:指向模块结构的指针。i_query参数可以有几种类型,args,根据i_query的类型,通过列表输入一些子参数。返回值:如果运行成功,返回VLC_SUCCESS.否则,返回VLC_EGENERIC.控制查询类型下面的标记必须设置为true.ACCESS_CAN_SEEK,
33、ACCESS_CAN_FASTSEEK, ACCESS_CAN_PAUSE, ACCESS_CAN_CONTROL_PACE,ACCESS_GET_PTS_DELAYRead 原型:ssize_t (*pf_read) ( access_t *, uint8_t *, size_t );返回值:如果还没有数据,返回 -1;如果数据已经读取完毕,返回0;否则,返回实际读取到的数据大小。Block原型:block_t *(*pf_block)( access_t * );返回原始大小的数据块,如果没有数据或到数据末尾,将返回NULL。没有数据和已经到达数据末尾的区别是,在到达数据末尾的时候,p_a
34、ccess-info.b_eof应该为true.VLC线程分析vlc线程管理VLC是一个密集的多线程应用。由于解码器必须预先清空,播放工序也必须预先做好流程(比如说解码器和输出必须被分开使用,否则无法保证在要求的时间里播放文件),因此VLC不采用单线程方法。目前不支持单线程的客户端,多线程的解码器通常就意味着更多的开销(各线程共享内存的问题等),进程间的通信也会比较复杂。VLC的线程结构基于pthreads线程模型。为了可移植的目的,没有直接使用pthreads函数,而是做了一系列类似的包裹函数:vlc_thread_create,vlc_thread_exit,vlc_thread_join,vlc_mutex_init,vlc_mutex_lock,vlc_mutex_unlock,vlc_mutex_destroy,vlc_cond_init,vlc_cond_signal,vlc_cond_broadcast,vlc_cond_wait,vlc_cond_destroy和类似结构:vlc_thread_t,vlc_mutex_t,and vlc_cond_t。vlc线程同步VLC的另一个关键特征就是解码和播放是异步的:解码由一个解码器线程工作,播放由音频输出线
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 三网融合的政策解读与运营商解决方案
- 2026巡视条例考试题及答案
- 2026青马班笔试题目及答案
- 医学26年:糖尿病护理管理要点 查房课件
- 医学26年:神经莱姆病诊疗要点 查房课件
- 2025年城市公共交通一卡通系统在智慧城市社区服务中的应用可行性分析报告
- 2026年智能睡眠监测仪市场潜力评估创新报告
- 2026年能源行业绿色转型行业报告
- 人工智能教育空间互动教学在美术学科中的创新实践教学研究课题报告
- 2026年现代农业种子科技创新报告
- Unit5OldtoysPartALet'sspell(课件)人教PEP版英语三年级下册
- 2026年民法典宣传月专题知识竞答
- 2026年深度学习及其应用-复旦大学中国大学mooc课后章节答案期末练习题(典型题)附答案详解
- 2026云南昆华医院投资管理有限公司(云南新昆华医院)招聘5人备考题库及答案详解参考
- 2026届陕西省西安市五校中考三模语文试题含解析
- 2026小升初语文专项冲刺辅导
- 2025年东莞市康复实验学校招聘笔试真题
- 2026年医师定期考核业务水平测评理论(人文医学)考试卷含答案
- (新)生物安全年度工作计划
- GB/T 19587-2017气体吸附BET法测定固态物质比表面积
- GB 37479-2019风管送风式空调机组能效限定值及能效等级
评论
0/150
提交评论