转载请注明出处: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解析)的更多相关文章

  1. Chromium源码--视频播放流程分析(拨开云雾)

    转载请注明出处: http://www.cnblogs.com/fangkm/p/3791964.html 在PC浏览器中播放视频,大部分视频网站都是采用flash播放器,这多亏了Adobe Flas ...

  2. Chromium源码--网络请求流程分析

    转载请注明出处:http://www.cnblogs.com/fangkm/p/3784660.html 本文探讨一下chromium中加载URL的流程,具体来说是从地址栏输入URL地址到通过URLR ...

  3. java基础解析系列(十)---ArrayList和LinkedList源码及使用分析

    java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...

  4. 通过官方API结合源码,如何分析程序流程

    通过官方API结合源码,如何分析程序流程通过官方API找到我们关注的API的某个方法,然后把整个流程执行起来,然后在idea中,把我们关注的方法打上断点,然后通过Step Out,从内向外一层一层分析 ...

  5. 从源码的角度分析ViewGruop的事件分发

    从源码的角度分析ViewGruop的事件分发. 首先我们来探讨一下,什么是ViewGroup?它和普通的View有什么区别? 顾名思义,ViewGroup就是一组View的集合,它包含很多的子View ...

  6. chromium源码阅读--Browser进程初始化

    最近在研读chromium源码,经过一段懵懂期,查阅了官网和网上的技术文章,是时候自己总结一下了,首先IPC message loop开始吧,这是每个主线程必须有的一个IPC消息轮训主体,类似之前的q ...

  7. vue源码逐行注释分析+40多m的vue源码程序流程图思维导图 (diff部分待后续更新)

    vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...

  8. 曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  9. 【转载】chromium浏览器开发系列第一篇:如何获取最新chromium源码

    背景:     最近摊上一个事儿,领导非要让写一篇技术文章,思来想去,自己接触chrome浏览器时间也不短了,干脆就总结一下吧.于是乎,本文顺理成章.由于有些细节必需描述清楚,所以这次先讲如何拿到ch ...

随机推荐

  1. [ruby on rails] 跟我学之(4)路由映射

    前面<[ruby on rails] 跟我学之Hello World>提到,路由对应的文件是 config/routes.rb 实际上我们只是添加了一句代码: resources :pos ...

  2. 【OpenStack】OpenStack系列7之Nova详解

    源码下载.安装 参考: https://github.com/yongluo2013/osf-openstack-training/blob/master/installation/openstack ...

  3. 【leetcode】Interleaving String

    Interleaving String Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Fo ...

  4. chrome浏览器关闭标签页面

    chrome浏览器关闭标签页提示:Scripts may close only the windows that were opened by it. 解决办法:通过open方法进行关闭. open( ...

  5. codeforces 467C.George and Job 解题报告

    题目链接:http://codeforces.com/problemset/problem/467/C 题目意思:给出一条含有 n 个数的序列,需要从中找出 k 对,每对长度为 m 的子序列,使得 找 ...

  6. Cocos2d-JS坐标系统

    标准屏幕坐标系 如果接触过iOS,Android,Windows Phone等系统的应用开发,或使用DOM,CSS开发过Web网页,开发者会非常熟悉所谓的标准屏幕坐标系:左上角为原点,向右为X轴正方向 ...

  7. 新建myeclipse工作空间需要的工作

    接触了许多个项目,都挺大的,每次都需要配置,简单总结总结. 第一.右击项目,选择Text file encoding 第二.点击window-->preferences-->myeclip ...

  8. ionic添加admob广告教程

    1.在你的ionic项目中使用如下命令添加admob插件: cordova plugin add cordova-plugin-admobpro 2.添加完成后,在$ionicPlatform.rea ...

  9. 解决remove @override annotation(jdk1.5和jdk1.6)

    在@override注释在jdk1.5环境下只能用于对继承的类的方法的重写,而不能用于对实现的接口中的方法的实现. 解决方法: 删除 @override

  10. MVC学习笔记---MVC生命周期及管道

    ASP.NET和ASP.NET MVC的HttpApplication请求处理管道有共同的部分和不同之处,本系列将体验ASP.NET MVC请求处理管道生命周期的19个关键环节. ①以IIS6.0为例 ...