Android15 Camera框架中的StatusTracker

news2025/3/11 3:39:25

StatusTracker介绍

StatusTracker是Android15 Camera框架中用来协调Camera3各组件之间状态转换的类。

StatusTracker线程名:std::string("C3Dev-") + mId + "-Status"

Camera3 StatusTracker工作原理

StatusTracker实现批处理(状态转换)的基础

StatusTracker对组件(component)状态的跟踪和处理,主要围绕三个表一个线程来实现:

  • 三个表
    • mComponentName 用于记录注册的组件名字和跟踪id。
    • mState  用于记录注册的组件状态。
    • mPendingChangeQueue 用于记录组件pending StateChange(提交的某个组件的statechange, 待后续处理完成)。
  • 一个工作线程
    • threadLoop

首先,一个component通过addComponent()向StatusTracker注册跟踪,StatusTracker会根据当前注册情况为这个component分配一个trackId(mNextComponentId记录当前注册了多少component),并将这个component登记到mComponentName表,以默认IDLE的状态登记到mState表。

然后,一个component通过markComponentActive(trackId)或者makrComponentIdle(trackId, Fence)向StatusTracker提交一个状态转换(StateChange),StatusTracker将这个component的状态转换请求添加到mPendingChangeQueue。StatusTracker工作线程负责处理提交到mPendingChangeQueue的状态转换。

StatusTracker工作线程的6个状态

StatusTracker工作线程有6个状态,状态之间的转换如下

图1.StatusTracker工作线程状态转换图 

StatusTracker的生与死由Camera3Device控制。Camera3Device::initializeCommonLocked()初始化基础内容时创建并启动这个StatusTracker工作线程;Camera3Device::disconnectImpl()主动调用requestExit(),将StatusTracker工作线程标记为dead, 系统Thread实现触发最终的StatusTracker工作线程退出。

StatusTracker处理一次状态转换可能有两种情况

  • 跟踪的组件有变化。包括组件通过addComponent()/removeComponent()主动注册或注销,也包括状态转换处理后组件idle(idleFence)。
  • 跟踪的组件状态有变化。组件通过markComponentX()主动标记状态。

StatusTracker工作线程相关的两个信号

从图1.StatusTracker工作线程状态转换图中,StatusTracker工作线程协作有两个信号:

  • mPendingChangeSignal信号,是组件状态更改提交(尚未完成)的信号。组件主动注册/注销/标记状态会触发这个信号,Camera3Device结束StatusTracker工作线程也会发这个信号。
  • mFlushCondition信号,是一批状态变更完成的信号。当所有的状态变更处理完会清空mPendingChangeQueue,并发送这个信号,表示StatusTracker已经冲刷完成。

StatusTracker工作线程处理状态转换

StatusTracker一次状态处理使分三步做的:

1. 将mPendingChangeQueue中的各组件状态变更统一收集到mStateTransitions,同时更新跟踪状态表。

2.将状态变更通知给parent(这里也就是Camera3Device)

3.所有的pengding change处理完,标记tracker为flushed

代码如下:

StatusTracker收集组件状态转换(包括组件间中间状态转换)

         sp<Camera3Device> parent;
198      {
199          Mutex::Autolock pl(mPendingLock);
200          Mutex::Autolock l(mLock);
201  
202          // Collect all pending state updates and see if the device
203          // collectively transitions between idle and active for each one
204  
             //获取被跟踪组件的状态,优先获取到active状态的
             //如果所有的组件都是idle状态,那么检查fence时间戳确定xx状态
205          // First pass for changed components or fence completions
206          ComponentState prevState = getDeviceStateLocked();

             //疑问:组件状态和mDeviceState怎么达到一致?
             //这里收集状态的切换, 有两种可能:active->idle, idle->active
207          if (prevState != mDeviceState) {
208              // Only collect changes to overall device state
209              mStateTransitions.add(prevState);
210          }
211          // For each pending component state update, check if we've transitioned
212          // to a new overall device state
213          for (size_t i = 0; i < mPendingChangeQueue.size(); i++) {
                 //一个状态转换动作
214              const StateChange &newState = mPendingChangeQueue[i];
                 //这个状态转换动作是哪个组件来做
215              ssize_t idx = mStates.indexOfKey(newState.id);
216              // Ignore notices for unknown components
217              if (idx >= 0) {
                     //更新这个组件的状态
218                  // Update single component state
219                  mStates.replaceValueAt(idx, newState.state);
                     //这是什么意思?
220                  mIdleFence = Fence::merge(String8("idleFence"),
221                          mIdleFence, newState.fence);

                     //检查被跟踪的组件状态
                     //收集状态切换
222                  // .. and see if overall device state has changed
223                  ComponentState newState = getDeviceStateLocked();
224                  if (newState != prevState) {
225                      mStateTransitions.add(newState);
226                  }
227                  prevState = newState;
228              }
229          }
             //一次状态切换收集后,清空mPendingChangeQueue以进行下一次状态收集。
230          mPendingChangeQueue.clear();
231          mComponentsChanged = false;
232  
233          // Store final state after all pending state changes are done with
234          
             //一次状态收集后,得到StatusTracker的状态
235          mDeviceState = prevState;
236          parent = mParent.promote();
237      }

StatusTracker将收集的状态转换通知给parent (Camera3Device)

if (mStateTransitions.size() > 0 && parent.get()) {
    for (size_t i = 0; i < mStateTransitions.size(); i++) {
        bool idle = (mStateTransitions[i] == IDLE);
        ALOGV("Camera device is now %s", idle ? "idle" : "active");
        parent->notifyStatus(idle);
    }
}
mStateTransitions.clear();

StatusTracker代码实现中的几个点

//StatusTracker工作线程退出需要Camera3Device主动触发
//但是StatusTracker本质是Android Thread, 退出有一定的延时性。
//退出相关代码:
void StatusTracker::requestExit()
{
    //First mark thread dead.
    Thread::requestExit();

    //Then exit any waits
    mPendingChangeSignal.signal();
    mFlushCondition.signal();
}

bool StatusTracker::threadLoop()
{
    {
        Mutex::Autolock pl(mPendinglock);
        while (mPendingChangeQueueSize() == 0 && !mComponentsChanged) {
            //等待pending change处理信号
            res = mPendingChangeSignal.waitRelative(mPendingLock, kWaitDuration);
            
            //线程退出
            if (exitPending()) return false;

            if (res != OK) {
                if (res != TIMED_OUT) {
                    ALOGE("%s: Error waiting on state changes: %s (%d)",
                        __FUNCTION__, strerror(-res), res);
                }
                //TIMED_OUT is expected
                break;
            }
        }
    }
    ...
}

Camera3中的StatusTracker

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313017.html

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

相关文章

边缘计算盒子:解决交通拥堵的智能方案

在当今的智能交通系统中&#xff0c;边缘计算盒子&#xff08;Edge Computing Box&#xff09;正逐渐成为不可或缺的核心组件。这种设备通过将计算能力下沉到网络边缘&#xff0c;极大地提升了数据处理的速度和效率&#xff0c;特别适用于实时性要求极高的交通监控场景。本文将…

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…

php虚拟站点提示No input file specified时的问题及权限处理方法

访问站点&#xff0c;提示如下 No input file specified. 可能是文件权限有问题&#xff0c;也可能是“.user.ini”文件路径没有配置对&#xff0c;最简单的办法就是直接将它删除掉&#xff0c;还有就是将它设置正确 #配置成自己服务器上正确的路径 open_basedir/mnt/qiy/te…

RISC-V汇编学习(三)—— RV指令集

有了前两节对于RISC-V汇编、寄存器、汇编语法等的认识&#xff0c;本节开始介绍RISC-V指令集和伪指令。 前面说了RISC-V的模块化特点&#xff0c;是以RV32I为作为ISA的核心模块&#xff0c;其他都是要基于此为基础&#xff0c;可以这样认为&#xff1a;RISC-V ISA 基本整数指…

java 重点知识 — JVM存储模块与类加载器

1 jvm主要模块 方法区 存储了由类加载器从.class文件中解析的类的元数据&#xff08;类型信息、域信息、方法信息&#xff09;及运行时常量池&#xff08;引用符号及字面量&#xff09;。 所有线程共享&#xff1b;内存不要求连续&#xff0c;可扩展&#xff0c;可能发生垃圾回…

idea中使用DeepSeek让编程更加便捷

IDEA中使用DeepSeek让编程更加便捷 对于开发者来说&#xff0c;IDEA&#xff08;IntelliJ IDEA&#xff09;是一款强大的开发工具。但你是否知道&#xff0c;通过安装DeepSeek这款插件&#xff0c;可以让你的编程体验更上一层楼&#xff1f;今天&#xff0c;我们就来聊聊如何在…

elasticsearch是哪家的

Elasticsearch&#xff1a;数据搜索与分析的领航者 在当今这个信息爆炸的时代&#xff0c;快速且准确地处理海量数据成为了众多企业和组织追求的目标。而Elasticsearch正是在这个背景下脱颖而出的一款强大的开源搜索引擎。它是由位于美国加利福尼亚州的Elastic公司所开发和维护…

5. MySQL 存储引擎(详解说明)

5. MySQL 存储引擎(详解说明) 文章目录 5. MySQL 存储引擎(详解说明)1. 查看存储引擎2. 设置系统默认的存储引擎3. 设置表的存储引擎3.1 创建表时指定存储引擎3.2 修改表的存储引擎 4. 引擎介绍4.1 InnoDB 引擎&#xff1a;具备外键支持功能的事务存储引擎4.2 MyISAM 引擎&…

基于LabVIEW的伺服阀高频振动测试闭环控制系统

为实现伺服阀在设定位置上下快速移动&#xff08;1kHz控制频率&#xff09;的振动测试目标&#xff0c;需构建基于LabVIEW的闭环控制系统。系统需满足高速数据采集、实时控制算法&#xff08;如PID或自适应控制&#xff09;、高精度电流驱动及传感器反馈处理等需求。结合用户提…

97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)

前言 在许多卫星应用场景中&#xff0c;我们需要 基于 TLE&#xff08;Two-Line Element Set, 两行根数&#xff09;计算卫星轨迹&#xff0c;并在地图上进行可视化。本文将使用 Vue 3 OpenLayers satellite.js&#xff0c;实现 实时计算卫星轨迹&#xff0c;并在地图上动态更…

fastjson漏洞#不出网#原理#流量特征

原理 本质是java的反序列化漏洞&#xff0c;由于引进了自动检测类型的&#xff08;autotype&#xff09;功能&#xff0c;fastjson在对json字符串反序列化的时候&#xff0c;会读取type内容&#xff0c;会试图将json内容反序列化成这个对象&#xff0c;并调用这个类的setter方…

Linux系统基于ARM平台的LVGL移植

软硬件介绍&#xff1a;Ubuntu 20.04 ARM 和&#xff08;Cortex-A53架构&#xff09;开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的&#xff0c;如果想要实现在ARM开发板上运行LVGL图形库&#xff0c;那么就需要把LVGL图形库提供的关于帧缓冲设…

电力场景绝缘子缺陷分割数据集labelme格式1585张4类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1585 标注数量(json文件个数)&#xff1a;1585 标注类别数&#xff1a;4 标注类别名称:["broken part","broken insulat…

【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式

网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议&#xff1a; HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站&#xff0c;就是通过HTTP协议来…

SpringBoot优雅关机,监听关机事件,docker配置

Spring Boot 提供了多种方法来实现优雅停机&#xff08;Graceful Shutdown&#xff09;&#xff0c;这意味着在关闭应用程序之前&#xff0c;它会等待当前正在处理的请求完成&#xff0c;并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下&#xff1a; …

在【k8s】中部署Jenkins的实践指南

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Kubernetes航线图&#xff1a;从船长到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…

Unity DOTS从入门到精通之 C# Job System

文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程&#xff0c;我们将创建一个旋转立方体的简单程序&#xff0c;并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…

【Godot4.4】浅尝Godot中的MVC

概述 基于一个Unity的视频。学习了一下基本的MVC概念&#xff0c;并尝试在Godot中实现了一下。 原始的MVC&#xff1a; Godot中的MVC&#xff1a; Model、View和Controller各自应该实现的功能如下&#xff1a; Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…

Elasticsearch为索引设置自动时间戳,ES自动时间戳

文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时&#xff0c;时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…

计算机网络:计算机网络的组成和功能

计算机网络的组成&#xff1a; 计算机网络的工作方式&#xff1a; 计算机网络的逻辑功能; 总结&#xff1a; 计算机网络的功能&#xff1a; 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点&#xff08;计算机或设备&…