转载请注明出处: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. abstract class和interface的区别

    1. 引言 2. 概念引入 ●什么是接口? 接口是包含一组虚方法的抽象类型,其中每一种方法都有其名称.参数和返回值.接口方法不能包含任何实现,CLR允许接口可以包含事件.属性.索引 器.静态方法.静态 ...

  2. Swap Two Nodes in Linked List

    Given a linked list and two values v1 and v2. Swap the two nodes in the linked list with values v1 a ...

  3. linux 学习一:安装jdk和tomcat

    使用secureCRT 一.首先安装centos的rzsz. 1.yum自动安装:(yum安装rzsz) yum install lrzsz 2.手动安装方法如下:(包有问题,还是采用第一种方式) 2 ...

  4. Windbg程序调试--转载

    WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. WinDbg是微软很重要的诊断调试工具: 可以查 ...

  5. 【动态规划】盖房子(house)--未提交--已提交

    问题 D: 盖房子(house) 时间限制: 1 Sec  内存限制: 64 MB提交: 27  解决: 16[提交][状态][讨论版] 题目描述 FJ最近得到了面积为n*m的一大块土地,他想在这块土 ...

  6. mybatis异常:Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}问题分析及解决

    转载自:http://blog.csdn.net/jackpk/article/details/44158701 mybatis异常:Improper inline parameter map for ...

  7. CodeForces - 417B (思维题)

    Crash Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit Status ...

  8. [Android UI] shape和selector的结合使用

    shape和selector是Android UI设计中经常用到的,比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到shape和selector.可以这样说,shape和 ...

  9. ubuntu下使用反编译apk,工具dex2jar和jd-gui

    ubuntu下使用反编译apk, 工具 1:通过apk-tool反编译出资源文件: http://code.google.com/p/android-apktool/ 2.首先使用dex2jar反编译 ...

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

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