Chromium源码--视频播放流程分析(WebMediaPlayerImpl解析)
转载请注明出处:http://www.cnblogs.com/fangkm/p/3797278.html
承接上一篇文章。媒体播放,需要指定一个源文件,html5用URL格式来指定视频源文件地址,可以是http链接,也可以使本地源文件(不能直接指定,需要借助blob二进制类型)。播放网络文件比播放本地文件多了个下载流程, 所以下面直接分析网络文件的播放流程,本地文件的播放流程也就清楚了。首先分析下网络视频资源的加载流程,相关结构图如下:

WebMediaPlayerImpl类有一成员BufferedDataSource来负责管理URL网络资源的加载逻辑。
BufferedDataSource资源加载逻辑主要由BufferedResourceLoader完成,
BufferedResourceLoader类维护一个WebURLLoader接口的派生类AssociatedURLLoader对象, AssociatedURLLoader类也并没有真正的和webkit_glue层的WebURLLoaderImpl一样实现WebURLLoader的接口,而是通过DocumentThreadableLoader类最终依赖WebURLLoaderImpl的实现给主进程发送URL请求WebURLLoaderImpl(WebURLLoaderImpl的流程请参见:http://www.cnblogs.com/fangkm/p/3784660.html)。
AssociatedURLLoader对象与frame对象关联,当调用WebFrame的stopLoading方法时,该请求也会取消。
BufferedResourceLoader内部维护一个可增长的内存缓冲区来保存请求到的视频数据。
分析到这里我始终没发现暂停缓冲机制,也没有找到缓冲到磁盘文件的地方,如果视频文件过大的话,全部积放在内存,资源消耗过大肯定造成极不好的程序体验。当然我这里的Chromium代码也有点老了,可能新版的已经改进了。
视频数据已经准备完毕,接下来的工作就是解析音视频数据了。在分析这部分之前首先简单普及下音视频的相关概念。一般的视频文件都有视频流和音频流两部分组成,不同的视频格式音视频的封装格式肯定不一样。将音频流和视频流合成文件的过程称为muxer,反之从媒体文件中分离音频流和视频流的过程称为demuxer. 播放视频文件就需要从文件流中分离出音频流和视频流,分别对其进行解码,解码后的视频帧可以直接渲染,音频帧可以送到音频输出设备的缓冲区进行播放,当然,视频渲染和音频播放的时间戳一定要控制同步。
WebMediaPlayerImpl中有关demuxer的逻辑结构如下:

WebMediaPlayerImpl根据资源的不同创建不同的demuxer对象。
如果视频源是通过JavaScript传送过来的二进制数据,则创建ChunkDemuxer对象来分离音频流和视频流;
如果视频源是通过URL指定的网络源,则创建FFmpegDemuxer对象,依赖BufferedDataSource对象来访问通过网络加载的媒体流数据。
ChunkDemuxer和FFmpegDemuxer的具体实现暂且不表,先只需要了解他们的作用是将媒体流分离出视频流和音频流。先分析整个播放流程。

WebMediaPlayerImpl类有一个Pipeline对象来负责视频的播放流程, Pipeline本身就是流水线的意思,正适合视频播放的一系列流程。Pipeline内部利用状态机维护播放中的各种阶段的逻辑。Pipeline调用AudioRendererImpl初始化时,会调用Demuxer的GetStream方法,指定获取音频流数据传入AudioRendererImpl对象;同理调用VideoRendererBase初始化时,会取到视频流数据来传入。音视频流的读取操作由DemuxerStream接口来抽象。
下面分析一下VideoRendererBase的流程, VideoRendererBase这名字起的有点奇怪,带个Render单词,确做的是视频流的解码逻辑,真正的绘制操作还是抛到WebMediaPlayerImpl类,具体请参见WebMediaPlayerImpl的paint方法。先看结构:

VideoRendererBase维护了一个VideoDecoder列表,内部主要逻辑都交给VideoFrameStream处理, VideoFrameStream的主要功能包括解码器的选取、从DemuxerStream读取视频流进行解码,解码后的结果为一视频帧结构VideoFrame,这个结构封装的是YUV数据,可以直接或转换成RGB进行渲染操作。
简单介绍下这里的视频解码器创建和选取逻辑:
在WebMediaPlayerImpl类中就已经创建好视频解码器列表,按顺序依次为:
1. 如果gpu支持视频解码,则创建GpuVideoDecoder对象
2. 创建VpxVideoDecoder对象
3. 创建FFmpegVideoDecoder对象
创建好解码器列表后传入VideoRendererBase对象,最终由VideoFrameStream来管理选取逻辑:
1. 如果视频配置信息里有加密选项,则创建DecryptingVideoDecoder做为解码器
2. 如果无加密选项,则从传入的解码器列表中选择第一个做为解码器。
3. 如果调用选择的解码器的Initialize无效(解码器不支持该格式的解码),则按顺序选择列表中的下一个解码器。
AudioRendererImpl的结构与VideoRendererBase类似,在音频渲染方面比视频渲染稍微复杂一点,需要将音频数据输出到声卡设备进行播放。相关结构图:

到此为止,网页播放器整个流程差不多已经清晰了,当然还有很多细节没扒,比如说Media Source流对应的分离器ChunkDemuxer的实现、FFmpegDemuxer内部怎么对ffmpeg的使用、各种解码器的实现等,没有开发经验,要研究透这些细节真的很耗时,有兴趣的童鞋可以自己研究。
Chromium源码--视频播放流程分析(WebMediaPlayerImpl解析)的更多相关文章
- Chromium源码--视频播放流程分析(拨开云雾)
转载请注明出处: http://www.cnblogs.com/fangkm/p/3791964.html 在PC浏览器中播放视频,大部分视频网站都是采用flash播放器,这多亏了Adobe Flas ...
- Chromium源码--网络请求流程分析
转载请注明出处:http://www.cnblogs.com/fangkm/p/3784660.html 本文探讨一下chromium中加载URL的流程,具体来说是从地址栏输入URL地址到通过URLR ...
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- 通过官方API结合源码,如何分析程序流程
通过官方API结合源码,如何分析程序流程通过官方API找到我们关注的API的某个方法,然后把整个流程执行起来,然后在idea中,把我们关注的方法打上断点,然后通过Step Out,从内向外一层一层分析 ...
- 从源码的角度分析ViewGruop的事件分发
从源码的角度分析ViewGruop的事件分发. 首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View ...
- chromium源码阅读--Browser进程初始化
最近在研读chromium源码,经过一段懵懂期,查阅了官网和网上的技术文章,是时候自己总结一下了,首先IPC message loop开始吧,这是每个主线程必须有的一个IPC消息轮训主体,类似之前的q ...
- vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)
vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...
- 曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 【转载】chromium浏览器开发系列第一篇:如何获取最新chromium源码
背景: 最近摊上一个事儿,领导非要让写一篇技术文章,思来想去,自己接触chrome浏览器时间也不短了,干脆就总结一下吧.于是乎,本文顺理成章.由于有些细节必需描述清楚,所以这次先讲如何拿到ch ...
随机推荐
- NGINX userid 分析、解码
NGINX userid 分析.解码 生成userid的代码在 http/modules/ngx_http_userid_filter_module.c 大概550行左右. uid_set 是4个ui ...
- 查看一些特定sql需求的书写
user表,5个人abcde, content表10篇文章,一个人对应两篇文章,有 time字段,查询出五个人的最新文章. select a.id,a.SName,a.ClsNo,a.Scorefr ...
- 12.从上往下遍历二元树[LevelOrderOfBinaryTree]
[题目] 输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印. 例如输入 8 / \ 6 10 /\ /\ 5 7 9 11 输出8 ...
- ubuntu命令行相关命令使用心得
一.Ubuntu解压缩zip,tar,tar.gz,tar.bz2 ZIP zip可能是目前使用得最多的文档压缩格式.它最大的优点就是在不同的操作系统平台,比如Linux, Windows以及Mac ...
- HDU1297 Children’s Queue (高精度+递推)
Children’s Queue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Car的旅行路线(codevs 1041)
题目描述 Description 又到暑假了,住在城市A的Car想和朋友一起去城市B旅游.她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I ...
- 手机 无法转移到SD卡 Andriod 导出应用程序
今天下载了一个应用Meridian,因为是直接从google商店里面装的,因此无法找到SDK,需要从新找到导出方式: 豌豆荚==> 软件和游戏管理==>输入Meridian搜素==> ...
- 发现磁盘的shell
#!/bin/bash #set -x diskarray=(`cat /proc/diskstats |grep -E "\bsd[a-z]\b|\bxvd[a-z]\b|\bvd[a-z ...
- hdu 1242:Rescue(BFS广搜 + 优先队列)
Rescue Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submis ...
- Java Hour 25 Packages
有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 25 Hours. Packages Programs are organiz ...