SteamVR媒体播放器分析(三):解码、播放及立体格式自动匹配

最近对 SteamVR 媒体播放器比较感兴趣,简单记录下其技术细节和实现方式(顺带看看它和之前本人从业做过的播放器有何不同)。

前情提要

这是关于媒体播放器分析的最后一篇文章,前两篇文章如下:

简述

一般 VR 播放器播放视频的流程为:

  • 实时解码得到帧纹理
  • 根据视频的立体格式,对纹理进行处理
  • 渲染上屏

SteamVR播放器也不例外。

解码

和上文(二)类似,播放器的解码同样是突出一个大道至简,解码直接使用 Unity 内置的 VideoPlayer,后续操作均利用 VideoPlayer 解码出的 Texture 做文章。

正是由于使用了内置的 VideoPlayer,碍于其有限的解码能力,播放大码率视频时性能不佳。

VideoPlayer 对文件后缀名有限制,基于此,播放器对视频文件后缀名做了限制,只播放.mp4.avi.mov后缀的视频文件,因此哪怕是内封编码为 H.264 的 .mkv 文件,VideoPlayer 也不能播放

目前利用 MKV 这一万金油封装格式的视频文件越来越多,其内部视频的编码格式也五花八门,按照后缀来判断不是一个好主意。

匹配立体格式

目前 SteamVR 播放器支持的 Layout 为:

  • 单(Mono)
  • 左右/右左(StereoLR/StereoRL)
  • 上下/下上(StereoTB/StereoBT)
  • Anaglyph(红蓝/Gray)

针对每个 Layout,支持如下渲染方式:

  • 平面
  • 180°
  • 360°
  • 鱼眼

注意:目前业界还有一种特殊的 360° 立体视频实现方式,它是利用四台或八台双目摄像机同时录制四或八个方向的立体影像,根据用户的观看角度拼接,成本较高,且需要专用软件播放,非上述通用的立体视频格式。

用户除了通过(一)文章中的 UI 进行格式控制外,对于没有播放过的视频,会进行立体格式自动匹配。

立体格式自动匹配的逻辑是先用路径及文件名进行关键字匹配,若不行,则按照文件宽高比匹配。

由于路径匹配关键字很多,列在这里篇幅太长,因此仅列举前五个关键字:

Text Layout Format
_2dp Mono 2D
_3dph Mono LR
_3dpv Mono TB
_180x180_3dh,_stereo180 180 LR
还有很多,略……

路径关键字匹配失败后,宽高比匹配格式对应关系为:

Width Layout Format
<1.5 180 LR
>=1.5 360 TB

按照宽高比匹配的话,大部分匹配是错误的,需要用户通过 UI 手动更改立体格式。

更改完成后,会将信息存储下来,以便下次播放读取使用。

播放

每个逻辑帧,通过 Graphic.Blit 将 VideoPlayer 解码的帧拷贝到一张自己创建的 Texture 上。

场景中有两组平面,一组平面,一组球面,平面用于 Mono Layout 播放,球面用于 180、360、鱼眼 Layout 播放。

每一组平面中有两个面,分别对应着左右眼。

播放开始时,将自己创建的 Texture 和配套的参数送到四个面的 Shader 里,由 Shader 进行采样。

由于 Shader 是 DXBC 的,常见工具不能直接解出,只能根据字节码反推,因此不过多研究。

但 Shader 的逻辑应该并不复杂,因为其无非是根据视频立体格式进行采样,不是多么复杂的事情。

完结

SteamVR 播放器分析文章到此完成。

综合来看,SteamVR 播放器这个项目即简单,又复杂。简单体现在它的实现思路均未超出引擎自身能力,复杂则体现在其对于 Native 的掌控(见文章二)。

分析完成后,计划复刻一个播放器出来:复刻播放器同样支持鼠标 + VR 手柄操作,也有 Desktop UI 及 VR 镜像 UI,并用现代化播放器插件取代 VideoPlayer。

梓喵出没博客(azimiao.com)版权所有,转载请注明链接:https://www.azimiao.com/10019.html
欢迎加入梓喵出没博客交流群:313732000

我来吐槽

*

*