• Android 视频播放延时抖动那些事


    一、背景

    局域网模式下,Android手机播放相机视频流,使用Android 自带MediaCodec解码,视频延时较大,约700ms左右。使用FFmpeg软解+转码,延时200ms左右,但是画面卡顿抖动严重。

    视频帧信息
    帧率:30fps
    码率:1Mbps
    GOP:10
    size:720P
    帧格式:IPPP(AUD SPS PPS)

    二、排查过程

    • 硬件解码
      因不同芯片video code不同,加速方式也不同,验证过瑞芯微的3399硬件解码,没有视频延迟这些问题,华为P30也没有这种问题,红米手机就会出现这种问题。也查过网络资料,是由于在解码过程中,AMediaCodec会缓存一定数据帧,导致视频播放往后推迟,调用“AMediaCodec_getInputBuffer”和“AMediaCodec_dequeueOutputBuffer”,延时是非常小的,大约1~5ms以内。

    • 软件解码
      因无法修改AMediaCodec,所以考虑使用FFmpeg进行解码,调用“avcodec_send_packet”和“avcodec_receive_frame”接口,在调用“sws_scale”进行转码。完成一个GOP解码转码耗时在400ms左右,I帧解码需要80ms,P帧平均帧也在35ms左右。

    • 网络抖动
      网络抖动是音视频优化的干扰指标之一,这里我们没有做特殊数据,只在发送端加了一个pcing平缓发送机制,测试结果还是一样,延时抖动。

    三、解决方法

    结合上面的排查项,我们在软解解码中 “完成一个GOP解码转码耗时在400ms左右”,在背景提到,我们的视频源GOP是10,帧率30,那就1秒有三个GOP,一个GOP是333ms,但是解码转码需要400ms,这就出现问题了,解码实现赶不上接收,导致后面的接收帧根本就来不及解码,会进行主动抛帧,视频就会出现一卡一卡了。

    着重排查解码和转码两个接口,去掉转码接口,抓取耗时日志,结果:一帧I帧解码耗时平均在,30~60ms左右,相比80,少了接近1半的时间,因为解码接口,我们是需要用FFmpeg的,但是转码接口,我回想起webrtc中嵌入式解码也用到libyuv,然后网上查了一下,果然有网友也出现这种问题:使用libyuv替换sws_scale,然后果断使用libyuv替换。

    最后使用FFmpeg + libyuv,终于解决了Android手机播放视频卡顿问题。
    出现这种情况还是和硬件有关,华为P30无论在硬解码或FFmpeg解码转码,都不会出现卡顿延时问题,软件解码极度依赖CPU处理。

  • 相关阅读:
    vue.js实现科室无限层选中和回显
    Linux-基础命令(黑马学习笔记)
    Python 实战:用 Scrapyd 打造个人化的爬虫部署管理控制台
    网络安全和隐私保护技术
    程序员想要网上接单却不知道如何是好?那这篇文章你可得收藏好了!
    泛型擦除的理解
    javaweb 之 Request 和 Response 常见案例 用户登录和注册
    笔记本电脑恢复删除数据的5种方法
    中秋特辑:Java事件监听实现一个猜灯谜小游戏
    元数据管理-解决方案调研二:元数据管理解决方案——Saas/内部解决方案(1)
  • 原文地址:https://blog.csdn.net/edw200/article/details/126757973