在做了充分的准备后,我信心满满的向着 H265 8K 视频解码这个目标发起进攻,然而,正打算动手的时候,我突然发现,别说支持 H265 ,自编的 Chromium WebView 连 H264 解码都不支持。使用 WebView Shell 访问测试页面,结果如下:

错误日志如下:

03-05 23:20:21.731  9061  9124 E chromium: [ERROR:batching_media_log.cc(26)] MediaEvent: MEDIA_ERROR_LOG_ENTRY {"error":"FFmpegDemuxer: no supported streams"}

令我不解的是,Android 10 的预编译 Webview 却没这样的问题。

测试的视频是 MP4 格式,从日志上看,大致可以判断是对流的解析出现问题。浏览 media 部分的代码,可以看到有 mp4_stream_parser.h / mp4_stream_parser.cc 文件,基本可以判断 MP4StreamParser 类的作用就是解析 MP4 格式的。StreamParser 使用工厂模式创建,工厂类为 StreamParserFactory,查看源码,可以发现有很多代码被 BUILDFLAG(USE_PROPRIETARY_CODECS) 宏包起来了。

联想到 Chromium 文档中有提到专有解码器的,原话为:

此外,您可能希望包括对专有音频和视频编解码器的支持,就像 Google 的 WebView 所做的那样。 这些编解码器可能受到专利或许可协议的保护,在分发包含它们的 WebView 构建之前,您应该寻求法律建议。

因为平台是支持硬解 H264 / H265 的,没有联想到和这个有关系。赶紧加到编译选项中:

ffmpeg_branding = "Chrome"
proprietary_codecs = true

问题得到圆满的解决?答案是没有。

点击页面上的播放箭头,没有视频画面出现,查看 log,有如下信息:

03-04 14:11:37.069 26846 26910 W cr_MediaCodecUtil: HW encoder for video/avc is not available on this device.

怎么会找不到硬件解码器?

之前看 Media 模块的文档,文档讲到可通过 chrome://media-internals 可以查看媒体解码信息以及相关日志。WebView Shell 并不支持在地址栏输入 chrome://media-internals 。这也难不倒我,可以在这个代码上编译出一个 Chromium 浏览器。

$ autoninja -C out/Default chrome_public_apk

安装之后,一个 tab 播放网页,另一个 tab 执行  chrome://media-internals ,可以看到:

视频解码器为 MojoVideoDecoder ,而使用 Google 官方发布的 Chrome for Android,视频解码器为 MediaCodecVideoDecoder:

从对比图看似乎是解码器创建错误。但经过一番代码跟踪,其实 MojoVideoDecoder 还是会调用 MediaCodecVideoDecoder。这里不要被 MojoVideoDecoder 给骗了,以为它是对表情符进行解码的。关于 Mojo 的解释如下:

We use mojom interfaces as the transport layer of each media component to support hosting them remotely. These interfaces are called media player mojo interfaces. They are very similar to their C++ counterparts:

也就是说 Mojo 只是一个抽象层,在 Android 平台上,还是会走到 MediaCodec 组件进行解码。至于这里为什么显示使用的 MojoVideoDecoder,原因在于 MediaCodecVideoDecoder 没有创建成功。从 log 上也印证了这一点:

03-07 08:35:05.895 29840 30203 I ACodec  : 0x6fbdb77900 [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 7 *minUndequeuedBuffers: 4  extraBuffers:3
03-07 08:35:05.895  3081 30389 I SOCT_OMXVDEC: set_parameter: setted buf cnt 7 exceed range(0, 3)!
03-07 08:35:05.895  3081 30389 E OMXNodeInstance: setParameter(0xe836c360:uapi.decoder.avc, ParamPortDefinition(0x2000001)) ERROR: Undefined(0x80001001)
03-07 08:35:05.895 29840 30203 W ACodec  : [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 7 failed: -2147483648
03-07 08:35:05.895 29840 30203 I ACodec  : 0x6fbdb77900 [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 6 *minUndequeuedBuffers: 4  extraBuffers:2
03-07 08:35:05.895  3081 30389 I SOCT_OMXVDEC: set_parameter: setted buf cnt 6 exceed range(0, 3)!
03-07 08:35:05.895  3081 30389 E OMXNodeInstance: setParameter(0xe836c360:uapi.decoder.avc, ParamPortDefinition(0x2000001)) ERROR: Undefined(0x80001001)
03-07 08:35:05.895 29840 30203 W ACodec  : [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 6 failed: -2147483648
03-07 08:35:05.895 29840 30203 I ACodec  : 0x6fbdb77900 [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 5 *minUndequeuedBuffers: 4  extraBuffers:1
03-07 08:35:05.895  3081 30389 I SOCT_OMXVDEC: set_parameter: setted buf cnt 5 exceed range(0, 3)!
03-07 08:35:05.896  3081 30389 E OMXNodeInstance: setParameter(0xe836c360:uapi.decoder.avc, ParamPortDefinition(0x2000001)) ERROR: Undefined(0x80001001)
03-07 08:35:05.896 29840 30203 W ACodec  : [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 5 failed: -2147483648
03-07 08:35:05.896 29840 30203 I ACodec  : 0x6fbdb77900 [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 4 *minUndequeuedBuffers: 4  extraBuffers:0
03-07 08:35:05.896  3081 30389 I SOCT_OMXVDEC: set_parameter: setted buf cnt 4 exceed range(0, 3)!
03-07 08:35:05.896  3081 30389 E OMXNodeInstance: setParameter(0xe836c360:uapi.decoder.avc, ParamPortDefinition(0x2000001)) ERROR: Undefined(0x80001001)
03-07 08:35:05.896 29840 30203 W ACodec  : [OMX.uapi.video.decoder.avc] setting nBufferCountActual to 4 failed: -2147483648
03-07 08:35:05.896 29840 30203 E ACodec  : Failed to allocate buffers after transitioning to IDLE state (error 0x80000000)
03-07 08:35:05.896 29840 30203 E ACodec  : signalError(omxError 0x80001001, internalError -2147483648)
03-07 08:35:05.896 29840 30202 E MediaCodec: Codec reported err 0x80001001, actionCode 0, while in state 5

在梳理了一遍又一遍的流程,跟踪调试了一遍又一遍的代码,两眼发花。这样持续了三天,一点没找到头绪。再 google 一把,有人说从 Chromium 105 之后的版本开始,对于 H265 的支持比较完善。那编译一个最新的版本试试吧,看看具体是什么情况。

由于前面坑都踩过了一遍,在现有代码上切换新版本很顺利。编译运行后发现,H264 / H265 的支持都没有问题。

选择不那么新的版本,主要是考虑想更快的熟悉代码。但即使不是那么新的中间版本,代码已经改得面目全非。而最新版本解决了大麻烦,那还是选择最新的版本吧。最终我选择的是一个稳定版本 111.0.5563.49 。

最后需要说明一下,不能简单说 Chromium 105 之后的版本支持 H264 / H265,在 Android 上,还取决于 MediaCodec 组件的解码能力,Chromium 只是把上面的流程走通了,但实际解码还是依赖底层硬件。

如何判断系统的 MediaCodec 对各种视频编码格式的支持,这里需要介绍 google 的开源播放器 exoplayer。

ExoPlayer 是适用于 Android 的应用程序级媒体播放器。它不基于 MediaPlayer API 开发,所以 ExoPlayer 支持 Android 的 MediaPlayer API 目前不支持的功能,包括 DASH 和 SmoothStreaming 自适应播放。与 MediaPlayer API 不同,ExoPlayer 易于定制和扩展,并且可以通过 Play Store 应用程序更新进行更新。

exoplayer 的项目地址:

https://github.com/google/ExoPlayer

构建和安装 exoplayer 后,可以使用命令行来播放指定的视频:

$ adb shell am start -a com.google.android.exoplayer.demo.action.VIEW -d <url>

如果某种格式在 chromium 中无法播放,先使用 exoplayer 确认一下,在 MediaCodec 这一层面上时候支持,可以更好的确认问题是在 chromium 还是在 Android 系统层。

选择最新 Chromium,支持 H264 / H265相关推荐

  1. C语言从头开始写一次hls视频转发服务器,支持H264和H265

    由于2020年后,谷歌浏览器将不再支持flashplay了,从而网页视频的播放,在谷歌浏览器上,不得不像其他办法,而hls是一个不错的方式,前端H5有现成的js标签,能直接支持苹果的hls,并且不用下 ...

  2. chromium编译与支持H264编码支持

    背景android中自带的webview不支持H264解码.但是android chrome支持. 我也试了国内的一些第三方webkit,比如TBS,但是TBS还是有坑,视屏播放的时候就是黑屏.: ( ...

  3. web无插件解码播放H264/H265(js解码HTML5播放)

    项目意义: 长久以来,安防领域的网络摄像机(IPC)的WEB视频直播都依赖于浏览器插件,IE浏览器使用ActiveX插件,Chrome和Firefox浏览器使用NPAPI插件. 之所以开发浏览器插件来 ...

  4. iOS H264,H265视频编码(Video encode)

    本例需求:使用H264, H265实现视频数据的编码并录制开始200帧存为文件. 原理:比如做直播功能,需要将客户端的视频数据传给服务器,如果分辨率过大如2K,4K则传输压力太大,所以需要对视频数据进 ...

  5. 支持HEVC/H265 RTMP播放的VLC WINDOWS版本

    本文镜像:https://www.linkpi.cn/archives/1225 本文链接:https://blog.csdn.net/weixin_45326556/article/details/ ...

  6. 让WebRTC支持H264编解码

    最近实验了下如何让WebRTC支持H264编码,记录下,供有需要的人参考. 说明一下,我是在 Ubuntu Server 14.04 下编译的 WebRTC ,使用 native(C++) api 开 ...

  7. RTP协议解析及H264/H265 音视频RTP打包分析

    一 概述 实时传输协议(Real-time Transport Protocol或简写RTP)是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的. RTP协议详 ...

  8. 视频系统 流媒体 rtsp hls h264 h265 aac 高并发 低延时 系统 设计 录像 视频合成 转发 点播 快进 快退 单步播放 分布式集群

    系统改名为:,升级包改使用jpg图像封装,从2.124版本开始,1.*的升级包停止使用 系统工具            下载地址(2019-04-19) :https://pan.baidu.com/ ...

  9. 支持HEVC/H265 RTMP接收的FFMPEG/FFPLAY WINDOWS版本

    本文镜像:https://linkpi.cn/archives/1249 本文链接:https://blog.csdn.net/weixin_45326556/article/details/1111 ...

最新文章

  1. Spring(5)——Spring 和数据库编程
  2. 卷积核里面的参数怎么来的_FSNet:利用卷积核概要进行深度卷积神经网络的压缩...
  3. android中setdate不是静态,为什么当setData()和setType()不起作用时,android intent的setDataAndType()工作正常?...
  4. java课后习题_【整理】java私塾教程课后习题
  5. 吸烟打电话检测、车道线识别等,2020中国华录杯·数据湖算法大赛火热进行中!...
  6. 深信服云计算BU专家组组长王佳玮:全融合时代的企业云新架构
  7. 设计字体打包_再也不用熬夜设计字体了!525款世界级绝美PS字体包免费送
  8. Socket API: I/O函数recvmsg()与sendmsg()
  9. c#精彩编程200例百度云_每天宅家创客5分钟|智龙6号星球车:01唤醒星球车——温州中小学趣味信息技术云课程...
  10. Windows Phone 地图定位 及导出GPX文件
  11. 系统分析与设计方法---面向对象的分析与设计
  12. 实现计算机系统的资源共享,实现多操作系统计算机的资源共享.pdf
  13. [渝粤教育] 西南科技大学 语言学概论(英语) 在线考试复习资料
  14. 教你做Android逆向
  15. Rust入门教程(三):Package、Crate 和 Module
  16. LR 杂记--nmon 分析 AIX 和 Linux 性能
  17. 山西省将率先实现全覆盖社保“一卡通”
  18. 怎么拯救一个不大靠谱的数据库系统 (5 不靠谱的前生)
  19. 小学生python趣味编程-【少儿编程】python趣味编程第二课:写文字
  20. mybatis plus 看这篇就够了,一发入魂

热门文章

  1. 服装仓库混乱的原因及解决办法
  2. 西门子S7-1500高速脉冲采集功能和应用 及 数据的处理
  3. php 实现无限极分类树 (引用和递归)
  4. 银行为什么不给我兑换菲律宾比索
  5. 用inkscape临摹logo
  6. 峰哥it-推荐-AnyDesk多ID集中控制台V1.2
  7. NLP-Highway Network代码实现
  8. 2021-2027全球与中国汽车玻璃清洁剂市场现状及未来发展趋势
  9. float和double的精度区别
  10. react 父组件调子组件的方法