Chromium为视频签全屏播放的过程分析.docx
《Chromium为视频签全屏播放的过程分析.docx》由会员分享,可在线阅读,更多相关《Chromium为视频签全屏播放的过程分析.docx(49页珍藏版)》请在三一办公上搜索。
1、Chromium为视频签全屏播放的过程分析Chromium为视频标签全屏播放的过程分析 在Chromium中,标签有全屏和非全屏两种播放模式。在非全屏模式下,标签播放的视频嵌入在网页中显示,也就是视频画面作为网页的一部分显示。在全屏模式下,我们是看不到网页其它内容的,因此标签播放的视频可以在一个独立的全屏窗口中显示。这两种截然不同的播放模式,导致Chromium使用不同的方式渲染视频画面。本文接下来就详细分析标签全屏播放的过程。 从前面文章中一文可以知道,在Android平台上,标签指定的视频是通过系统提供的MediaPlayer进行播放的。MediaPlayer提供了一个setSurface
2、接口,用来给MediaPlayer设置一个Surface。Surface内部有一个GPU缓冲区队列,以后MediaPlayer会将解码出来的视频画面写入到这个队列中去。 Surface有两种获取方式。第一种方式是通过SurfaceTexture构造一个新的Surface。第二种方式是从SurfaceView内部获得。在非全屏模式下,Chromium就是通过第一种方式构造一个Surface,然后设置给MediaPlayer的。在全屏模式下,Chromium将会直接创建一个全屏的SurfaceView,然后再从这个SurfaceView内部获得一个Surface,并且设置给MediaPlayer。
3、 在Android平台上,SurfaceView的本质是一个窗口。既然是窗口,那么它的UI就是由系统合成在屏幕上显示的。它的UI就来源于它内部的Surface描述的GPU缓冲区队列。因此,当MediaPlayer将解码出来的视频画面写入到SurfaceView内部的Surface描述的GPU缓冲区队列去时,SurfaceFlinger就会从该GPU缓冲区队列中将新写入的视频画面提取出来,并且合成在屏幕上显示。关于SurfaceView的更多知识,可以参考前面文章中一文。 Surface描述的GPU缓冲区队列,是一个生产者/消息者模型。在我们这个情景中,生产者便是MediaPlayer。如果Su
4、rface是通过SurfaceTexture构造的,那么SurfaceTexture的所有者,也就是Chromium,就是消费者。消费者有责任将视频画面从GPU缓冲区队列中提取出来,并且进行渲染。渲染完成后,再交给SurfaceFlinger合成显示在屏幕中。如果Surface是从SurfaceView内部获取的,那么SurfaceView就是消费者,然后再交给SurfaceFlinger合成显示在屏幕中。 简单来说,在非全屏模式下,标签的视频画面经过MediaPlayer-Chromium-SurfaceFlinger显示在屏幕中,而在全屏模式下,经过MediaPlayer-SurfaceV
5、iew-SurfaceFlinger显示在屏幕中。 Chromium支持标签在全屏和非全屏模式之间无缝切换,也就是从一个模式切换到另外一个模式的时候,不需要重新创建MediaPlayer,只需要给原先使用的MediaPlayer设置一个新的Surface即可。图1描述的是标签从非全屏模式切换为全屏模式的示意图,如下所示: 当标签从非全屏模式切换为全屏模式时,Chromium会为它创建一个全屏的SurfaceView,并且将这个SurfaceView内部的Surface设置给MediaPlayer。以后MediaPlayer就不会再将解码出来的视频画面通过原先设置的SurfaceTexture交
6、给Chromium处理,而是通过后面设置的Surface交给SurfaceView处理。 接下来,我们就结合源代码,从标签进入全屏模式开始,分析标签全屏播放视频的过程。从前面文章中一文可以知道,在WebKit中,标签是通过HTMLMediaElement类描述的。当标签进入全屏模式时,HTMLMediaElement类的成员函数enterFullscreen就会被调用,它的实现如下所示: cpp view plain copy 在CODE上查看代码片派生到我的代码片 void HTMLMediaElement:enterFullscreen WTF_LOG(Media, HTMLMediaEl
7、ement:enterFullscreen); FullscreenElementStack:from(document).requestFullScreenForElement(this, 0, FullscreenElementStack:ExemptIFrameAllowFullScreenRequirement); 这个函数定义在文件external/chromium_org/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp中。 在WebKit中,网页的每一个标签都可以进入全屏模式。每一个网页都对应有一个Fullscree
8、nElementStack对象。这个FullscreenElementStack对象内部有一个栈,用来记录它对应的网页有哪些标签进入了全屏模式。 HTMLMediaElement类的成员函数enterFullscreen首先调用成员函数document获得当前正在处理的标签所属的网页,然后再通过调用FullscreenElementStack类的静态成员函数from获得这个网页所对应的FullscreenElementStack对象。有了这个FullscreenElementStack对象之后,就可以调用它的成员函数requestFullScreenForElement请求将当前正在处理的标签
9、设置为全屏模式。 FullscreenElementStack类的成员函数requestFullScreenForElement的实现如下所示: cpp view plain copy 在CODE上查看代码片派生到我的代码片 void FullscreenElementStack:requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType) . / The Mozilla Full Screen API has different requirements /
10、 for full screen mode, and do not have the concept of a full screen element stack. bool inLegacyMozillaMode = (flags & Element:LEGACY_MOZILLA_REQUEST); do . / 1. If any of the following conditions are true, terminate these steps and queue a task to fire / an event named fullscreenerror with its bubb
11、les attribute set to true on the context objects / node document: . / The context objects node document fullscreen element stack is not empty and its top element / is not an ancestor of the context object. (NOTE: Ignore this requirement if the request was / made via the legacy Mozilla-style API.) if
12、 (!m_fullScreenElementStack.isEmpty & !inLegacyMozillaMode) Element* lastElementOnStack = m_fullScreenElementStack.last.get; if (lastElementOnStack = element | !lastElementOnStack-contains(element) break; / A descendant browsing contexts document has a non-empty fullscreen element stack. bool descen
13、dentHasNonEmptyStack = false; for (Frame* descendant = document-frame ? document-frame-tree.traverseNext : 0; descendant; descendant = descendant-tree.traverseNext) . if (fullscreenElementFrom(*toLocalFrame(descendant)-document) descendentHasNonEmptyStack = true; break; if (descendentHasNonEmptyStac
14、k & !inLegacyMozillaMode) break; . / 2. Let doc be elements node document. (i.e. this) Document* currentDoc = document; / 3. Let docs be all docs ancestor browsing contexts documents (if any) and doc. Deque docs; do docs.prepend(currentDoc); currentDoc = currentDoc-ownerElement ? tDoc-ownerElement-d
15、ocument : 0; while (currentDoc); / 4. For each document in docs, run these substeps: Deque:iterator current = docs.begin, following = docs.begin; do +following; / 1. Let following document be the document after document in docs, or null if there is no / such document. Document* currentDoc = *current
16、; Document* followingDoc = following != docs.end ? *following : 0; / 2. If following document is null, push context object on documents fullscreen element / stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute / set to true on the document. if (!followingDoc) fr
17、om(*currentDoc).pushFullscreenElementStack(element); addDocumentToFullScreenChangeEventQueue(currentDoc); continue; / 3. Otherwise, if documents fullscreen element stack is either empty or its top element / is not following documents browsing context container, Element* topElement = fullscreenElemen
18、tFrom(*currentDoc); if (!topElement | topElement != followingDoc-ownerElement) / .push following documents browsing context container on documents fullscreen element / stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute / set to true on document. from(*currentD
19、oc).pushFullscreenElementStack(followingDoc-ownerElement); addDocumentToFullScreenChangeEventQueue(currentDoc); continue; / 4. Otherwise, do nothing for this document. It stays the same. while (+current != docs.end); / 5. Return, and run the remaining steps asynchronously. / 6. Optionally, perform s
20、ome animation. . document-frameHost-chrome.client.enterFullScreenForElement(element); / 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen. return; while (0); . 这个函数定义在文件external/chromium_org/third_party/WebKit/Source/core/dom/FullscreenElement
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Chromium 视频 全屏 播放 过程 分析
链接地址:https://www.31ppt.com/p-3154555.html