当前位置: 首页 > news >正文

BufferQueue低延迟优化,以及SurfaceView帧率上限问题解决

目录

了解BufferQueue

为什么会出现问题?

如何优化?


最近在做一个与音视频播放相关的项目,使用到了MediaCodec解码后送到SurfaceView播放场景。发现SurfaceView播放上限是60HZ,不符合项目需求,故而进行了研究并找到了解决办法。

然而此方法需要修改aosp代码,并不合适普通的应用开发。

环境:AOSP14

了解BufferQueue

Android的显示框架使用了BufferQueue作为图形缓冲区的缓存队列,我们不需要深究BufferQueue的实现细节,只需要了解其大概工作原理即可。

Android图形系统使用BufferQueue实现了一个非常典型的生产者消费者模型。

生产者(如app的view或者视频解码器等)通过dequeueBuffer方法从BufferQueue中获取空闲图形缓冲区,填充数据后通过queueBuffer方法归还图形缓冲区,同时通知消费者可以消费。

消费者(一般为SurfaceFlinger,负责图像的显示)接收到生产者的通知后,通过acquirebuffer方法从BufferQueue获取一个可显示的图形缓冲区,等待垂直同步事件到来后显示(每秒60次)。显示完毕后通过releaseBuffer释放图形缓冲区。

为什么会出现问题?

假设生产和消费都是每秒60帧的速率时,理想的生产消费时序如下图所示:

生产和消费有序进行,生产一个图形缓冲区随后便消费一个。BufferQueue待消费的缓冲区始终不超过1个。

但是实际的情况,尤其是涉及到网络时,生产速率远没有如此理想,如下图所示:

生产端因为网络抖动的问题,有两帧没用及时到达,导致两次生产和消费被跳过。随后网络恢复后,极短的时间内达到了3帧数据(本次帧+延迟达到的2帧)。因为消费者只能按照固定的显示速度显示,生产也会继续以相同的速率生产,此时BufferQueue内会永远积压大于1帧的数据。直到下次网络抖动导致无生产输出,消费者才会消耗队列内的缓冲区。

这种模型有助于平滑抖动,轻微抖动时可以天然的被平滑过渡,不易被察觉卡顿。但是随之而来的是,队列积压导致的延迟增加。

更要致命的是,如果生产者是120帧的视频,但是显示是60帧,那视频就会被慢放至原来的二分之一。

典型的如SurfaceView,其播放速率为60HZ,如果播放大于此帧率的视频会被慢放。TextureView无此问题,但是TextureView需要GPU绘制,无论从延迟还是内存带宽占用上都是不小的开销,况且不需要后期处理的场景GPU绘制一次完全多此一举。

当前这种问题在播放30帧视频时问题不大,因为消费快于生产,积压很快会被消费。但是仍有短期的积压可能。

在延迟方面,SurfaceView整体占用小,延迟低,但是可能短期丢堆积帧,还有帧率上限;TextureView没有帧率上限,但是延迟高啊!如何既要又要?

如何优化?

如果是需要低延迟的场景,优化也很简单。

方案一:判断积压缓冲数量,积压较多时通知生产者丢帧处理或者降低生产速度。但是Android框架下无法得到积压数量,改动框架成本较大。放弃。

方案二:生产者向BufferQueue插入新的缓冲区时,如果BufferQueue存在未及时消费的缓冲区,直接丢弃。理所当然,Android也考虑到了这点,BufferQueue支持此操作,图形缓冲区有一个mIsDroppable属性,为True时若此帧在下一帧插入队列时未被消费,则丢弃。但是尚不清楚如何使之生效。故代码内直接写死,简单有效。

编辑frameworks/native/libs/gui/BufferQueueProducer.cpp


http://www.mrgr.cn/news/37879.html

相关文章:

  • 线性代数~行列式计算
  • 一款开源的通用PDF处理神器,功能强悍!
  • SpringBoot整合JPA实现CRUD详解
  • 【HTML|第1期】HTML5视频(Video)元素详解:从起源到应用
  • 鸿蒙开发(NEXT/API 12)【硬件(接入手写套件)】手写功能开发
  • 算法——冒泡排序
  • 【洛谷】AT_abc178_d [ABC178D] Redistribution 的题解
  • 手搓一个Agent#Datawhale 组队学习Task3
  • 1013. 将数组分成和相等的三个部分 数组切分
  • 物理学基础精解【30】
  • 用十万字解析《微积分(第三版)》
  • 如何注册和使用Disney+?Disney+会员账号可以合租?Disney+会员账号订阅购买使用教程
  • 并发编程---线程与进程
  • --杂项2--
  • ffmpeg 结合 opencv 显示ps流文件
  • MATLAB绘图基础9:多变量图形绘制
  • Android界面控件概述
  • 每日论文6—16ISCAS一种新型低电流失配和变化电流转向电荷泵
  • 算法学习3
  • 2024最新Linux Socket编程