从Chrome源码看audio/video流媒体实现二(转)

第一篇主要介绍了Chrome加载音视频的缓冲控制机制和编解码基础,本篇将比较深入地介绍解码播放的过程。以Chromium 69版本做研究。

由于Chromium默认不能播放Mp4,所以需要需要改一下源码重新编译一下。

1. 编译一个能播放mp4的Chromium

自行编译出来的Chromium是无法播放mp4视频,在官网下载的也不行,终端会提示这个错误:

[69542:775:0714/132557.522659:ERROR:render_media_log.cc(30)] MediaEvent: PIPELINE_ERROR DEMUXER_ERROR_NO_SUPPORTED_STREAMS

说是在demux即多路解复用的时候发生了错误,不支持当前流格式,也就是Chromium不支持mp4格式的解析,这是为什么呢?经过一番搜索和摸索,发现只要把ffmpeg的编译模式从Chromium改成Chrome就可以。编辑third_party/ffmpeg/ffmpeg_options.gni这个文件,把前面几行代码改一下——把_default_ffmpeg_branding强制设置成Chrome,再重新编译一下就行了,如下代码所示:

# if (is_chrome_branded) {
  _default_ffmpeg_branding = "Chrome"
# } else {
#  _default_ffmpeg_branding = "Chromium"
# }复制代码

编译出来的Chromium就能播放视频了。Chromium工程的编译目标branding可以设置成Chrome(正式版)/Chromium/Chrome OS三种模式,ffmpeg的编译设定会根据这个branding类型自动选择它自己的branding,如上代码的判断,如果branding是Chrome,会额外多加一些解码器,就能够播放mp4了。

不过如果你想编译成正式版Chrome,由于缺少相关的主题theme文件,是编译不了的。

另外它还有一个proprietary_codecs的设置:

proprietary_codecs = is_chrome_branded || is_chromecast复制代码

编译正式版的Chrome会默认打开,它的作用是增加一些额外的解码器,如对EME(Encrypted Media Extensions)加密媒体扩展的支持。

最后一开始不能打开和能打开播放的效果对比如下图所示:

那么为什么Chromium不直接打开mp4支持呢,它可能受到mp4或者ffmpeg的一些开源协议和专利限制。

2. mp4格式和解复用

一个视频可以有3个轨道(Track):视频、音频和文本,但是数据的存储是一维的,从1个字节到第n个字节,那么视频应该放哪里,音频应该放哪里,mp4/avi等格式此做了规定,把视轨音轨合成一个mp4文件的过程就叫多路复用(mux),而把mp4文件里的音视频轨分离出来就叫多路解复用(demux),这两个词是从通信领域来的。

假设现在有个需求,需要取出用户上传视频的第一帧做为封面。这就要求我们去解析mp4文件,并做解码。


我们以这个 mountain.mp4时长为1s大小487kB的mp4视频做为研究对象,用sublime等编辑器打开显示其原始的二进制内容,如下图所示:
 

上图是用16进制表示的原始二进制内容,两个16进制(0000)就表示1个字节,如上图第4个字节是0x18。

mp4是使用box盒子表示它的数据存储的,标准规定了若干种盒子类型,每种盒子存放的数据类型不一样,box可以嵌套box。每个box的前4个字节表示它占用的空间大小,如上面第一个box是0x18 = 24字节,也就是说在接下来的24字节都是这个box的内容,所以上图到第2行的3431就是第一个box的内容。在前4个表示大小的字节之后紧接着的4个字节是盒子类型,值为ASCII编码,第一个盒子的类型为:

6674 7970 => ftyp

ftyp盒子的作用是用来标志当前文件类型,紧接着的4个字节表示它是一个微软的MPEG-4格式,即平常说的mp4:

6d70 3432 => mp42

综上,第1个盒子整体解析如下图所示:

猜你喜欢

转载自www.cnblogs.com/eret9616/p/9465812.html