Android CameraServer PreviewFrameSpacer梳理

Android CameraServer PreviewFrameSpacer梳理
PreviewFrameSpacer 设计与实现文件位置:device3/PreviewFrameSpacer.h/PreviewFrameSpacer.cpp1. 问题背景理想情况下,预览帧应按传感器输出节奏呈现给用户。但实际中,CPU 负载、请求设置差异等因素导致帧处理延迟不均匀,造成预览帧间距忽大忽小,用户感知到卡顿。2. 核心设计PreviewFrameSpacer 继承Thread,运行在独立线程中:Camera3OutputStream::returnBufferCheckedLocked() │ (HAL 返回 buffer) ▼ PreviewFrameSpacer::queuePreviewBuffer() │ 入队到 mPendingBuffers ▼ PreviewFrameSpacer::threadLoop() [独立线程] ├── 等待 buffer 到达 ├── 计算 readoutInterval = 当前帧 readoutTimestamp - 上一帧 readoutTimestamp ├── if readoutInterval = 80ms: 直接入队(帧间距过大,不等待) ├── else: 按 readoutInterval 节奏等待后入队 └── queueBufferToClientLocked() → mConsumer-queueBuffer()3. 关键常量常量值含义kWaitDuration50ms无 buffer 时的等待超时kFrameIntervalThreshold80ms帧间距阈值,超过则直接入队kMaxFrameWaitTime10ms最大等待时间,避免过度延迟kFrameAdjustThreshold2ms提前量,补偿代码执行时间4. threadLoop() 核心逻辑boolPreviewFrameSpacer::threadLoop(){// 1. 无 buffer 时等待 50msif(mPendingBuffers.empty()){mBufferCond.waitRelative(mLock,kWaitDuration);returntrue;}// 2. 计算与上一帧的 readout 间隔nsecs_t readoutInterval=buffer.readoutTimestamp-mLastCameraReadoutTime;// 3. 间隔 = 80ms: 直接入队(非连续预览帧)if(readoutInterval=kFrameIntervalThreshold){queueBufferToClientLocked(buffer,currentTime);returntrue;