生产者Producer往BufferQueue中写数据的过程
In normal operation, the producer calls
- dequeueBuffer() to get an empty buffer, fills it with data, then
calls
queueBuffer() to make it available to the consumer
代码如下:
// XXX: Tests that fork a process to hold the BufferQueue must run before tests
// that use a local BufferQueue, or else Binder will get unhappy
//
// In one instance this was a crash in the createBufferQueue where the
// binder call to create a buffer allocator apparently got garbage back.
// See b/36592665.
TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {const String16 PRODUCER_NAME = String16("BQTestProducer");const String16 CONSUMER_NAME = String16("BQTestConsumer");pid_t forkPid = fork();ASSERT_NE(forkPid, -1);if (forkPid == 0) {// Child processsp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;BufferQueue::createBufferQueue(&producer, &consumer);sp<IServiceManager> serviceManager = defaultServiceManager();serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();LOG_ALWAYS_FATAL("Shouldn't be here");}sp<IServiceManager> serviceManager = defaultServiceManager();sp<IBinder> binderProducer =serviceManager->getService(PRODUCER_NAME);mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);EXPECT_TRUE(mProducer != nullptr);sp<IBinder> binderConsumer =serviceManager->getService(CONSUMER_NAME);mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);EXPECT_TRUE(mConsumer != nullptr);sp<MockConsumer> mc(new MockConsumer);ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));IGraphicBufferProducer::QueueBufferOutput output;ASSERT_EQ(OK,mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));int slot;sp<Fence> fence;sp<GraphicBuffer> buffer;ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,nullptr, nullptr));ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));uint32_t* dataIn;ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,reinterpret_cast<void**>(&dataIn)));*dataIn = TEST_DATA;ASSERT_EQ(OK, buffer->unlock());IGraphicBufferProducer::QueueBufferInput input(0, false,HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));BufferItem item;ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));uint32_t* dataOut;ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,reinterpret_cast<void**>(&dataOut)));ASSERT_EQ(*dataOut, TEST_DATA);ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
在Android图形系统中,生产者往BufferQueue中写数据的过程通常涉及以下步骤:
-
创建BufferQueue:
- 生产者首先需要与BufferQueue建立联系,通常通过
BufferQueue::createBufferQueue
等方法创建BufferQueue的生产者和消费者接口(IGraphicBufferProducer
和IGraphicBufferConsumer
)。
- 生产者首先需要与BufferQueue建立联系,通常通过
-
请求缓冲区:
- 生产者调用
IGraphicBufferProducer::dequeueBuffer
方法请求一个新的缓冲区。此方法会返回一个缓冲区槽(slot)编号以及一个Fence对象,表明缓冲区何时准备就绪。
- 生产者调用
-
锁定缓冲区:
- 获得缓冲区后,生产者调用
GraphicBuffer::lock
方法锁定缓冲区,这样就可以获得指向缓冲区内存的指针。生产者会指定所需的访问模式,如GRALLOC_USAGE_SW_WRITE_OFTEN
(常用于软件写入)。
- 获得缓冲区后,生产者调用
-
填充数据:
- 生产者使用获得的内存指针来填充图像数据,例如像素数据。
-
解锁缓冲区:
- 数据填充完成后,生产者必须调用
GraphicBuffer::unlock
来解锁缓冲区,使其可以被消费者读取或被操作系统调度。
- 数据填充完成后,生产者必须调用
-
设置缓冲区属性并入队:
- 生产者创建一个
IGraphicBufferProducer::QueueBufferInput
结构体,设置缓冲区的属性,如时间戳、裁剪区域、缩放模式、变换等。 - 然后,调用
IGraphicBufferProducer::queueBuffer
方法,将填充好的缓冲区和相应的属性入队到BufferQueue中。
- 生产者创建一个
-
通知消费者:
- 当缓冲区入队后,如果设置了正确的同步机制,BufferQueue会自动或通过回调通知消费者有新的缓冲区可用。
总之,生产者往BufferQueue中写数据的关键步骤包括:请求缓冲区、填充数据、解锁缓冲区和将缓冲区入队。在这个过程中,BufferQueue作为生产者和消费者之间的桥梁,确保了数据的有效传递和管理。
相关文章:
生产者Producer往BufferQueue中写数据的过程
In normal operation, the producer calls dequeueBuffer() to get an empty buffer, fills it with data, then calls queueBuffer() to make it available to the consumer 代码如下: // XXX: Tests that fork a process to hold the BufferQueue must run bef…...
使用 Vite 和 Bun 构建前端
虽然 Vite 目前可以与 Bun 配合使用,但它尚未进行大量优化,也未调整以使用 Bun 的打包器、模块解析器或转译器。 Vite 可以与 Bun 完美兼容。从 Vite 的模板开始使用吧。 bun create vite my-app ✔ Select a framework: › React ✔ Select a variant:…...

如何设置IDEA远程连接服务器开发环境并结合cpolar实现ssh远程开发
文章目录 1. 检查Linux SSH服务2. 本地连接测试3. Linux 安装Cpolar4. 创建远程连接公网地址5. 公网远程连接测试6. 固定连接公网地址7. 固定地址连接测试 本文主要介绍如何在IDEA中设置远程连接服务器开发环境,并结合Cpolar内网穿透工具实现无公网远程连接…...

【项目管理后台】Vue3+Ts+Sass实战框架搭建二
Vue3TsSass搭建 git cz的配置mock 数据配置viteMockServe 建立mock/user.ts文件夹测试一下mock是否配置成功 axios二次封装解决env报错问题,ImportMeta”上不存在属性“env” 统一管理相关接口新建api/index.js 路由的配置建立router/index.ts将路由进行集中封装&am…...

制作一个RISC-V的操作系统六-bootstrap program(risv 引导程序)
文章目录 硬件基本概念qemu-virt地址映射系统引导CSRmachine模式下的csr对应的csr指令csrrwcsrrs mhartid引导程序做的事情判断当前hart是不是第一个hart初始化栈跳转到c语言的…...
haproxy和keepalived的区别与联系
HAProxy(High Availability Proxy) 是一个开源的、高效且可靠的解决方案,主要用于负载均衡。它工作在应用层(第七层),支持多种协议,如HTTP、HTTPS、FTP等。HAProxy通过健康检查机制持续监控后…...

云效 AppStack + 阿里云 MSE 实现应用服务全链路灰度
作者:周静、吴宇奇、泮圣伟 在应用开发测试验证通过后、进行生产发布前,为了降低新版本发布带来的风险,期望能够先部署到灰度环境,用小部分业务流量进行全链路灰度验证,验证通过后再全量发布生产。本文主要介绍如何通…...
pta L1-004 计算摄氏温度
L1-004 计算摄氏温度 分数 5 全屏浏览 切换布局 作者 陈建海 单位 浙江大学 给定一个华氏温度F,本题要求编写程序,计算对应的摄氏温度C。计算公式:C5(F−32)/9。题目保证输入与输出均在整型范围内。 输入格式: 输入在一行中给出一个华氏…...

毕业论文降重(gpt+完美降重指令),sci论文降重gpt指令——超级好用,重复率低于4%
1. 降重方法:gpt降重指令 2. gpt网站 https://yiyan.baidu.com/ https://chat.openai.com/ 3. 降重指令——非常好用!!sci论文,本硕大论文都可使用! 请帮我把下面句子重新组织,通过调整句子逻辑࿰…...

Qt 多元素控件
Qt开发 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别 以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件. QTableView 自身不持有数据. 使用QTableView 的 …...
LeetCode热题Hot100-两数相加
一刷一刷 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 请你将两个数相加,并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外,这两个数都不…...

Selenium 自动化 —— 浏览器窗口操作
更多内容请关注我的专栏: 入门和 Hello World 实例使用WebDriverManager自动下载驱动Selenium IDE录制、回放、导出Java源码 当用 Selenium 打开浏览器后,我们就可以通过 Selenium 对浏览器做各种操作,就像我们日常用鼠标和键盘操作浏览器一…...

二、Kubernetes(k8s)中部署项目wordpress(php博客项目,数据库mysql)
前期准备 1、关机顺序 2、开机顺序 (1)、k8s-ha1、k8s-ha2 (2)、master01、master02、master03 (3)、node01、node02 一、集群服务对外提供访问,需要通过Ingress代理发布域名 mast01上传 ingress-nginx.yaml node01、node02 上传 ingress-nginx.tar 、kube-webh…...
linux系统Kubernetes工具Service暴露服务
Service ServiceService创建service页面请求测试pod内部请求测试端口解析kube-proxy 使用ipvs 意义pod和Service的关系常用类型ClusterIpNodePortLoadBalancernode内网部署应用,外网访问不到 Service 服务基于ip端口的虚拟主机,定义一组pod的访问规则 Se…...

【算法篇】逐步理解动态规划1(斐波那契数列模型)
目录 斐波那契数列模型 1. 第N个泰波那契数 2.使用最小花费爬楼梯 3.解码方法 学过算法的应该知道,动态规划一直都是一个非常难的模块,无论是状态转移方程的定义还是dp表的填表,都非常难找到思路。在这个算法的支线专题中我会结合很多力…...

软件测试 - postman高级使用
断言 概念:让程序代替人判断测试用例执行的结果是否符合预期的一个过程 特点: postman断言使用js编写,断言写在postman的tests中 tests脚本在发送请求之后执行,会把断言的结果最终在testresult中进行展示 常用的postman提供的…...

数据交换技术
目录 <线路交换> <报文交换> <分组交换> 1.数据报分组交换 2.虚电路分组交换 计算机网络是以数据交换为目的的技术,从交换技术的发展过程来看,主要经历了线 路交换、报文交换、分组交换的过程。 <线路交换> 线路交换又称为…...
FFmpeg-- mp4文件合成1:aac和h264封装(c++实现)
文章目录 流程api核心代码muxer.hmuxer.cppaac 和 h264 封装为视频流,封装为c++的Muxter类 流程 分配视频文件上下文 int Init(const char *url); 创建流,赋值给视频的音频流和视频流 int AddStream(AVCodecContext *codec_ctx); 写视频流的head int SendHeader(); 写视频流的…...
【嵌入式开发 Linux 常用命令系列 1.3 -- 统计目录下有多少个文件】
统计目录下有多少个文件 在 Linux 中,你可以使用 find 命令和 wc(word count)命令的组合来统计当前目录及其子目录下的文件数量。如果你只对当前目录(不包括子目录)中的文件数量感兴趣,可以使用 ls 和 wc …...

JMeter 如何并发执行 Python 脚本
要在JMeter中并发执行Python脚本,可以使用Jython脚本或通过调用外部Python脚本的方式实现。 使用Jython脚本并发执行Python脚本的步骤: 1、创建一个线程组:在JMeter界面中,右键点击测试计划,选择 “添加” -> “线…...

图上合成:用于大型语言模型持续预训练的知识合成数据生成
摘要 大型语言模型(LLM)已经取得了显著的成功,但仍然是数据效率低下,特别是当学习小型,专业语料库与有限的专有数据。现有的用于连续预训练的合成数据生成方法集中于文档内内容,而忽略了跨文档的知识关联&a…...
【判断既约分数】2022-4-3
缘由既约分数,除了辗转相除法-编程语言-CSDN问答 void 判断既约分数() {int a 1, b 2020, aa b, y 2, gs 0;while (aa){while (a < b){while (y < a && y < aa)if (a%y 0 && aa%y 0)a, y 2;elsey;if (a < b)gs; else;a, y 2;…...
DelayQueue、ScheduledThreadPoolExecutor 和 PriorityBlockingQueue :怎么利用堆实现定时任务
DelayQueue DelayQueue 的最大亮点: 并不是简单全局锁的“单调队列”实现,而是用Leader-Follower 模式极大减少了线程唤醒的开销。插入与唤醒、等待与 leader 变更,都通过巧妙的锁和条件变量组合完成。 如果只关注“线程安全的优先队列全局…...
clickhouse 和 influxdb 选型
以下是 ClickHouse、InfluxDB 和 HBase 在体系架构、存储引擎、数据类型、性能及场景的详细对比分析: 🏗️ 一、体系架构对比 维度ClickHouseInfluxDBHBase设计目标大规模OLAP分析,高吞吐复杂查询 时序数据采集与监控,优化时间线管理高吞吐随机…...
Gartner《How to Create and Maintain a Knowledge Base forHumans and AI》学习报告
核心观点 本研究是一份 Gartne关于如何创建和维护面向人类与人工智能(AI)的知识库的研究报告。报告强调了知识库在知识管理(KM)中的核心地位,尤其是在生成式人工智能(GenAI)时代,一个结构良好的知识库是知识管理成功的关键,反之则可能成为整个知识管理实践的失败点。…...
SQL Server 日期时间类型全解析:从精确存储到灵活转换
SQL Server 日期时间类型全解析:从精确存储到灵活转换 一、引言:日期时间处理的核心挑战 在数据管理中,日期时间类型是最常用却最容易出错的数据类型之一。不同业务场景对时间精度、时区感知、存储效率的需求差异极大: 金融交易…...

Microsoft前后端不分离编程新风向:cshtml
文章目录 什么是CSHTML?基础语法内联表达式代码块控制结构 布局页面_ViewStart.cshtml_Layout.cshtml使用布局 模型绑定强类型视图模型集合 HTML辅助方法基本表单验证 局部视图创建局部视图使用局部视图 高级特性视图组件依赖注入Tag Helpers 性能优化缓存捆绑和压缩…...

产品经理课程(十一)
(一)复习 1、用户需求不等于产品需求,挖掘用户的本质需求 2、功能设计的前提:不违背我们的产品的基础定位(用一句话阐述我们的产品:工具:产品画布) 3、判断设计好坏的标准…...

获取 OpenAI API Key
你可以按照以下步骤来获取 openai.api_key,用于调用 OpenAI 的 GPT-4、DALLE、Whisper 等 API 服务: 🧭 获取 OpenAI API Key 的步骤: ✅ 1. 注册或登录 OpenAI 账号 打开 https://platform.openai.com/ 使用你的邮箱或 Google/…...

【计算机组成原理】计算机硬件的基本组成、详细结构、工作原理
引言 计算机如同现代科技的“大脑”,其硬件结构的设计逻辑承载着信息处理的核心奥秘。从早期程序员手动输入指令的低效操作,到冯诺依曼提出“存储程序”概念引发的革命性突破,计算机硬件经历了从机械操控到自动化逻辑的蜕变。本文将深入拆解…...