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

news2024/9/27 23:10:56

目录

了解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.coloradmin.cn/o/2171410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jupyter Notebook 产生 jupyter_notebook_config.py 配置文件

Jupyter Notebook 产生 jupyter_notebook_config.py 配置文件 引言正文第一步第二步第三步引言 今天遇到了一个问题,当我安装了 VS code,之后又在 VS code 中安装了 Jupyter notebook 的 extension。之后可以在 VS code 中正常使用 Jupyter Notebook 的所有功能。但是,当我…

sqli-labs时间盲注、布尔盲注脚本

script.py:提供参数,用于调用布尔盲注或时间注入的函数 import time_type import bool_type ​ ​ # inject_type: 1.布尔盲注2.时间注入 # http_type:1.GET请求2.POST请求 # dict_para_data:所有的参数,和默认值 # v…

打靶记录18——narak

靶机: https://download.vulnhub.com/ha/narak.ova 推荐使用 VM Ware 打开靶机 难度:中 目标:取得 root 权限 2 Flag 攻击方法: 主机发现端口扫描信息收集密码字典定制爆破密码Webdav 漏洞PUT 方法上传BF 语言解码MOTD 注入CVE-2021-3…

SQL | 查询带有单引号的异常数据和replace与insert插入的区别

学习SQL 查找单引号异常数据知识点 replace 和 insertinsert 插入 timestamp 参数 查找单引号异常数据 表数据 代码 SELECT * FROM sys_barcode WHERE name LIKE %%;知识点 单引号()在 SQL 查询中需要使用两个连续的单引号()来表…

Vue3.X + SpringBoot小程序 | AI大模型项目 | 饮食陪伴官

gitee平台源码 github平台源码 饮食陪伴师是一个管理饮食的原生大模型小程序,优势: 精确营养监控:用户记录饮食后,我们会计算出食用的营养成分与分量,并反馈给用户。饮食建议有效:大模型经过我们训练具备大…

003、网关路由问题

1. nginx配置404跳转回默认路由 https://blog.csdn.net/masteryee/article/details/83689954 https://blog.csdn.net/IbcVue/article/details/133230460 https://www.jb51.net/server/317970ynk.htm https://blog.csdn.net/u014438244/article/details/120531287 https://blog…

光耦合器在信号传输和隔离中的作用

光耦合器,也称为光隔离器,是电子电路中的关键元件,它结合了两个基本功能:信号传输和电气隔离。它们允许信号在电路的不同部分之间传递,同时保持它们彼此电气隔离。此功能对于保护敏感的低压控制电路免受更高电压、噪声…

ST188单光束反射式红外光电传感器心率测量原理

光电传感器心率测量原理 ST188传感器测量脉搏的具体原理如下: 当手指轻轻按压在ST188红外光电传感器上时,传感器内部的红外发射二极管会发出红外线。这些红外线穿透手指皮肤,照射到血液上。由于脉搏跳动时,血液的体积和压力会发生…

manjaro KDE桌面的使用

manjaro KDE桌面的使用 正儿八经的摆龙门阵 近些年不喜欢发博客的我,今天来一篇与开发扯不上关系的文章。这篇文章发布后,该文章不再做更新。有相关爱好的小伙伴们可以选择私信。 manjaro的介绍我就不用说了,想大家看到这里都是对manjaro有…

Python实战:爬取网页图片

文章目录 一、实战概述二、图片网站三、爬取图片1、编写程序,实现功能2、运行程序,查看结果 四、实战小结 一、实战概述 在本实战项目中,我们编写了一个Python程序,用于从指定的图片网站(https://pic.netbian.com/4kf…

西圣、漫步者头戴式耳机哪个音质好?热门主流头戴式耳机专业评测

一直以来头戴式蓝牙耳机凭借其独特的优势,逐渐成为了音乐爱好者、游戏玩家以及日常通勤者的首选,它们不仅融合了卓越的音质体验、便捷的无线连接,还融入了先进的降噪技术和人性化的佩戴设计,为用户带来了前所未有的听觉盛宴与舒适…

第十一章 分布式存储之哈希算法

目录 一、哈希取余分区 二、一致性哈希算法分区 三、哈希槽分区 在学习通过Docker进行Redis集群部署之前,简单聊一点Redis分布式集群存储相关的哈希算法问题: 一、哈希取余分区 2亿条记录就是2亿个KV,我们单机不行必须要分布式多机&…

高分作品《基于Java+MySQL图书销售管理系统》+源代码+文档说明

文章目录 源代码下载地址项目介绍项目功能界面预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 使用JavaSEJavaawtMySQL搭建的一个图书销售管理系统,主要涉及一个数据库,内含四张SQL表,管理员信息表,用…

Cesium 展示——倾斜摄影模型添加

文章目录 需求分析需求 这个图是网上随便找的,请忽略,就大概展示个加载后的样子。主要看代码思路和加载代码,代码中我不仅写了倾斜摄影加载的过程,还有加载后位置不太匹配进行的微调 分析 let tilesetUrlNew = /gt-qxsy/gt-caijian/tileset.json // 新的倾斜摄影模型 cons…

Redis在window下和linux下的区别

早期,redis只能运行在linux上,原因是底层调用的是epoll方法,而windows下没有该方法。除此之外,windows下也没有fork( )函数。最终为了强行能在windows上运行,使用的是select IOCP方式。 Epoll 是当事件资源满足时发出…

Python编码系列—Python责任链模式:打造灵活的请求处理流程

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

“天翼云息壤杯”高校AI大赛开启:国云的一场“造林”计划

文 | 智能相对论 作者 | 叶远风 2024年年初《政府工作报告》中明确提到了“人工智能”行动,人工智能的发展被提到前所未有的高度。 如何落实AI在数字经济发展中引擎作用,是业界当下面临的课题。 9月25日,“2024年中国国际信息通信展览会”…

java中的四种引用

在java中对象的引用有强、软、弱、虚四种,这些引用级别的区别主要体现在对象的生命周期、回收时机的不同。这里在已知结论的情况下对其进行验证。 准备工作 1. 设置内存 为方便调试,将内存设置为16MB 依次点击菜单栏的Run—>Edit Configurations …

常用性能优化方法

在一个Java项目中进行性能优化是至关重要的。性能优化能够提高项目的效率和响应速度,提升用户体验,并且可以节省服务器资源和成本。 首先,性能优化可以确保项目的高效运行。当项目在运行时,性能问题可能会导致应用程序变慢、响应时…

Python集成测试详解

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 软件开发过程中,确保代码的稳定性和功能性至关重要。集成测试是一项关键步骤,旨在验证不同模块或组件能够协同工作,实现预期的…