C++中的安全指针(智能指针)
2025/12/17 1:26:54
视频文件处理模块 ├── 文件生成层 │ ├── 事件视频生成 │ │ ├── 碰撞事件视频 (crashEventFileUpload) │ │ ├── DMS事件视频 (dmsEventOperate) │ │ └── RFID事件视频 (onDataReceive) │ ├── 定时视频生成 │ │ ├── 定时拍照 (MSG_TIMER_PICTURE) │ │ └── 远程控制拍照 (RemoteEvent) │ └── 实时视频流 │ ├── 实时视频命令 (CMD_REALVIDEO) │ └── RTMP流处理 (ACTION_RTMP_TIMEOUT) ├── 文件管理层 │ ├── 文件命名规范 │ │ ├── 事件文件名生成 (getEventFileUploadName) │ │ ├── RFID文件名生成 (createRfidFileName) │ │ └── 时间戳格式化 │ ├── 文件路径管理 │ │ ├── 存储路径确定 │ │ ├── 文件存在性检查 │ │ └── 文件大小管理 │ └── 文件列表管理 │ ├── 文件列表获取 (Utils.getFilelistList) │ ├── 文件匹配算法 (getUploadFileName) │ └── 文件ID提取 ├── 文件上传层 │ ├── 上传调度器 │ │ ├── 延迟上传机制 (setDelayUploadAlarm) │ │ ├── 重传机制 (fileReUploadNumberOfTimes) │ │ └── 上传状态管理 (UploadFileState) │ ├── 上传执行器 │ │ ├── 上传管理器 (UploadManager) │ │ ├── 数据库同步 (DBHelper) │ │ └── 网络传输 │ └── 上传回调层 │ ├── 成功处理 (onUploadResponse) │ ├── 失败处理 (重传逻辑) │ └── 状态更新 ├── 视频服务层 │ ├── 服务启动器 (Utils.startToService) │ ├── 服务参数封装 │ └── 服务结果回调 └── 视频分析层 ├── DMS视频分析 ├── 驾驶行为视频关联 └── 位置信息关联
视频文件类型体系 ├── 事件触发视频 │ ├── 碰撞事件视频 │ │ ├── 文件路径: mApp.getDeviceInfo().getmCrashFilePath() │ │ ├── 服务器标志: mApp.getDeviceInfo().getmCrashServerFlag() │ │ └── 上传类型: Constant.REMOTE_VIDEO_OUT │ ├── DMS事件视频 │ │ ├── 报警类型: ALARM_CLOSE_EYES/ALARM_YAWN等 │ │ ├── 动作类型: FileActionType.ACTION_TYPE_DMS_* │ │ └── 摄像头标识: "I" (内) / "F" (外) │ └── RFID事件视频 │ ├── 报警类型: Constant.ALARM_RFID │ ├── 文件操作: FileActionType.ACTION_TYPE_IDENTIFICATION │ └── 语音提示: AUDIO_SWIPE_SUCCESSFUL ├── 定时生成视频 │ ├── 定时拍照 │ │ ├── 开关控制: Constant.TIMER_PICTURE_SWITCH │ │ ├── 间隔时间: mTimerPicInterval │ │ └── 拍照数量: Constant.PICTURE_NUMBER │ └── 远程拍照 │ ├── 远程命令: Constant.REMOTE_PICTURE_IN/OUT │ └── 服务质量: 5 (Utils.startToService参数) ├── 历史剪辑视频 │ ├── 历史视频剪辑 │ │ ├── 搜索标志: FindFileRunnable.HISTORY_FILE_FORWARD_SERCH │ │ └── 文件来源: Constant.REMOTE_VIDEO_OUT │ └── 事件视频剪辑 │ ├── 事件标志: FindFileRunnable.EVENT_VIDEO_FORWARD_FLAG │ └── 文件来源: Constant.REMOTE_VIDEO_IN └── 实时视频流 ├── RTMP流 │ ├── 超时处理: ACTION_RTMP_TIMEOUT │ └── 日志记录: LogUtils.saveNetLogFile └── 实时视频命令 ├── 中继命令: relayCmdDataStr ├── 服务器ID: serverFlagId └── 消息封装: messagePackageSend
// 碰撞事件视频生成逻辑树 private void crashEventFileUpload(String msgContent, boolean isServerFlag) { // 1. 参数验证 if (TextUtils.isEmpty(msgContent)) return; // 2. 模式判断 (服务器标志模式/文件路径模式) if (isServerFlag) { // 服务器标志模式 serverFlag = msgContent; mApp.getDeviceInfo().setmCrashServerFlag(serverFlag); path = mApp.getDeviceInfo().getmCrashFilePath(); } else { // 文件路径模式 path = msgContent; mApp.getDeviceInfo().setmCrashFilePath(msgContent); serverFlag = mApp.getDeviceInfo().getmCrashServerFlag(); // 3. 远程开关检查 String remoteSw = Utils.getGlobalString(mContext, Constant.REMOTE_SWITCH); if (TextUtils.isEmpty(remoteSw)) remoteSw = Constant.ON; // 4. 立即上传判断 if (Constant.ON.equals(remoteSw)) { LocationInfo info = GpsControll.getInstance(mContext).getLastLocationInfo(); startUploadFile(Constant.REMOTE_VIDEO_OUT, "", msgContent, Constant.EVENT_TYPE_CRASH, getEventFileUploadName(path, null, Constant.REMOTE_VIDEO_OUT), -1); return; } } // 5. 延迟上传处理 if (!TextUtils.isEmpty(path) && !TextUtils.isEmpty(serverFlag)) { mApp.getDeviceInfo().setmCrashServerFlag(null); mApp.getDeviceInfo().setmCrashFilePath(null); LocationInfo info = GpsControll.getInstance(mContext).getLastLocationInfo(); startUploadFile(Constant.REMOTE_VIDEO_OUT, "", msgContent, Constant.EVENT_TYPE_CRASH, getEventFileUploadName(path, null, Constant.REMOTE_VIDEO_OUT), -1); } }// 事件文件上传名称生成逻辑树 private String getEventFileUploadName(String path, String serverFlag, int remoteType) { // 1. 文件存在性检查 File file = new File(path); if (!file.exists()) return "null"; // 2. 文件名构建器初始化 StringBuilder sb = new StringBuilder(); // 3. 基本前缀构建 sb.append(Constant.REMOTE_EVENT); // 远程事件前缀 sb.append("_"); sb.append(Utils.getImeiForFile(mContext)); // 设备IMEI sb.append("_"); sb.append(TextUtils.isEmpty(serverFlag) ? "00000000" : serverFlag); // 服务器标志 sb.append("_"); // 4. 文件名重构 int fileNameLength = file.getName().length(); String frontHalfName = file.getName().substring(0, fileNameLength - 6); String afterHalfName = file.getName().substring(fileNameLength - 6, fileNameLength); sb.append(frontHalfName); // 文件名前部分 sb.append(Utils.getFileCameraID(remoteType)); // 摄像头ID sb.append("_"); sb.append(afterHalfName); // 文件名后部分 // 5. 返回构建结果 return sb.toString(); } // 文件名格式解析: // REMOTE_EVENT_IMEI_SERVERFLAG_FILENAME_CAMERAID_TIMESTAMP // 例如: REMOTE_EVENT_868123456789012_00000000_20230515_120000_I_000001.mp4// DMS事件操作逻辑树 private void dmsEventOperate(String msgContent) { // 1. 参数解析 String[] dmsEventParams = msgContent.split(Constant.COMMA); String filePath = dmsEventParams[0]; String alarmType = dmsEventParams[1]; int actionType = Integer.parseInt(dmsEventParams[2]); // 2. 报警类型映射 int alarmTypeInt = -1; if ("DFW".equals(alarmType)) alarmTypeInt = Constant.ALARM_CLOSE_EYES; else if ("DYA".equals(alarmType)) alarmTypeInt = Constant.ALARM_YAWN; else if ("DDW".equals(alarmType)) alarmTypeInt = Constant.ALARM_DISTRACTION; else if ("DSA".equals(alarmType)) alarmTypeInt = Constant.ALARM_SMOKING; else if ("DCA".equals(alarmType)) alarmTypeInt = Constant.ALARM_PHONE_CALLING; else if ("DAA".equals(alarmType)) alarmTypeInt = Constant.ALARM_MISSING_FACE; else if ("CLIBABN".equals(alarmType)) alarmTypeInt = Constant.ALARM_ABNORMAL_FACE_CALIBRA; // 3. 报警值计算 int alarmValue = 0; if (actionType >= FileActionType.ACTION_TYPE_DMS_SEC_CLOSE_EYES && actionType <= FileActionType.ACTION_TYPE_DMS_SEC_MISSING_FACE) { alarmValue = 2; // 二级报警 } // 4. 文件名重构 File file = new File(filePath); int fileLength = file.getName().length(); String filenName = file.getName().substring(0, fileLength - 6) + "I_" + file.getName().substring(fileLength - 6, fileLength); // 5. 事件时间解析 long mEventTime = Utils.stringToLong(filenName.substring(0, 19), "yyyy_MM_dd_HH_mm_ss"); // 6. 事件文件名生成 String eventFileName = Utils.createEventFileName(filenName, Utils.getImeiForFile(mContext), "00000000"); // 7. 报警消息发送 AlarmControll.getIntance(mContext).sendAlarmMessage(alarmTypeInt, mEventTime, eventFileName, alarmValue, info); // 8. 文件上传 dmsEventFileUpload(filePath, actionType, eventFileName, alarmTypeInt); }// 定时拍照处理逻辑树 (MSG_TIMER_PICTURE) case Constant.MSG_TIMER_PICTURE: if (mApp.getDeviceInfo().ismTimerPicture()) { // 1. 开关检查 final int picNum = (Integer) SPUtils.get(Constant.PICTURE_NUMBER, 1); // 2. 拍照数量 // 3. 内摄像头拍照 Utils.startToService(mContext, "", FileActionType.ACTION_TYPE_TIMED_MEDIA, Constant.REMOTE_PICTURE_IN, 0, picNum, 5); // 4. 外摄像头拍照 (延迟500ms) new Handler().postDelayed(new Runnable() { @Override public void run() { Utils.startToService(mContext, "", FileActionType.ACTION_TYPE_TIMED_MEDIA, Constant.REMOTE_PICTURE_OUT, 0, picNum, 5); } }, 500); // 5. 下次定时设置 mTimerPicInterval = (Long) SPUtils.get( Constant.TIMER_PICTURE_INTERVAL, Constant.DEFAULT_TIMER_PICTURE_INTERVAL); setTimerPictureAlarm(SystemClock.elapsedRealtime() + mTimerPicInterval); } break;Framework视频服务架构 ├── 媒体服务层 (Media) │ ├── MediaRecorder视频录制 │ │ ├── setVideoSource() 视频源设置 │ │ ├── setOutputFormat() 输出格式 │ │ ├── setVideoEncoder() 编码器 │ │ ├── setVideoSize() 分辨率 │ │ ├── setVideoFrameRate() 帧率 │ │ ├── setVideoEncodingBitRate() 码率 │ │ ├── prepare() 准备录制 │ │ ├── start() 开始录制 │ │ └── stop() 停止录制 │ ├── Camera相机服务 │ │ ├── open() 打开相机 │ │ ├── setParameters() 参数设置 │ │ ├── takePicture() 拍照 │ │ ├── startPreview() 开始预览 │ │ └── release() 释放资源 │ └── MediaPlayer播放服务 │ ├── setDataSource() 数据源 │ ├── prepare() 准备播放 │ ├── start() 开始播放 │ └── stop() 停止播放 ├── 文件服务层 │ ├── File文件操作 │ │ ├── exists() 存在检查 │ │ ├── createNewFile() 创建文件 │ │ ├── delete() 删除文件 │ │ └── length() 文件大小 │ └── ContentResolver内容解析 │ ├── query() 查询内容 │ ├── insert() 插入内容 │ ├── update() 更新内容 │ └── delete() 删除内容 ├── 网络服务层 │ ├── DownloadManager下载管理 │ │ ├── enqueue() 加入下载队列 │ │ ├── query() 查询下载状态 │ │ └── remove() 移除下载 │ └── ConnectivityManager网络状态 │ └── getActiveNetworkInfo() 活动网络信息 └── 系统服务层 ├── AlarmManager定时服务 ├── PowerManager电源管理 └── WindowManager窗口管理
视频服务Binder通信架构 ┌─────────────────────────────────────────────────────┐ │ 应用进程 (GpsTrackerService) │ ├─────────────────────────────────────────────────────┤ │ 1. Utils.startToService() 启动视频服务 │ │ ├── Intent封装服务参数 │ │ ├── startService()调用 │ │ └→ Binder IPC调用 │ ├─────────────────────────────────────────────────────┤ │ 视频服务进程 (独立服务进程) │ ├─────────────────────────────────────────────────────┤ │ 2. Service.onCreate()/onStartCommand() │ │ 3. 初始化MediaRecorder/Camera │ │ 4. 开始录制/拍照 │ │ 5. 文件保存到指定路径 │ │ 6. 通过Broadcast/回调通知结果 │ │ ↑ (Binder跨进程回调) │ ├─────────────────────────────────────────────────────┤ │ 应用进程 (GpsTrackerService) │ ├─────────────────────────────────────────────────────┤ │ 7. 接收视频生成完成通知 │ │ 8. 触发文件上传逻辑 │ └─────────────────────────────────────────────────────┘ 具体Binder调用路径: startService() → ActivityManagerService → 视频服务进程启动 → Service绑定 → IPC方法调用 → 视频录制执行
// 1. 视频服务启动数据流 Utils.startToService() ├── 参数封装: │ ├── context: 上下文对象 │ ├── action: 空字符串 │ ├── actionType: FileActionType.ACTION_TYPE_TIMED_MEDIA │ ├── remoteType: Constant.REMOTE_PICTURE_IN/OUT │ ├── startTime: 0 (立即开始) │ ├── picNum: 拍照数量 │ └── quality: 5 (服务质量) ├── Intent构建: │ ├── 设置ComponentName (服务类名) │ ├── 添加Extra参数 │ └── 设置Flags ├── Binder IPC调用: │ ├→ Context.startService() │ ├→ ActivityManagerService.startService() │ └→ 目标Service.onCreate()/onStartCommand() ├── 视频服务执行: │ ├── Camera.open()打开相机 │ ├── Camera.takePicture()拍照 │ ├── PictureCallback保存图片 │ └── 文件保存到存储 └── 结果返回: ├── 文件路径生成 ├── 广播通知发送 └→ 应用层接收处理 // 2. 文件上传数据流 startUploadFile(int dvrType, String fileId, String filePath, int eventType, String fileName, int actionType) ├── 参数准备: │ ├── 获取当前位置信息 │ ├── StringBuilder构建上传字符串 │ └── 逗号分隔参数拼接 ├── 上传管理器调用: │ ├→ mUploadManager.startUploadFile() │ ├→ 数据库记录插入 (DBHelper) │ └→ 网络传输准备 ├── 网络传输: │ ├── 文件分块读取 │ ├── HTTP/FTP协议传输 │ └── 进度回调处理 ├── 上传结果处理: │ ├── 成功: 数据库记录删除 │ ├── 失败: 重试机制触发 │ └── 状态更新 └── 应用回调: ├→ onUploadResponse()回调 ├→ 重传计数更新 └→ 下次上传调度
Native视频处理架构 ├── JNI接口层 │ ├── 视频编码接口 │ │ ├── native_setup() 初始化 │ │ ├── native_start() 开始 │ │ ├── native_stop() 停止 │ │ └── native_release() 释放 │ ├── 相机控制接口 │ │ ├── native_open_camera() 打开相机 │ │ ├── native_take_picture() 拍照 │ │ └── native_set_parameters() 设置参数 │ └── 文件操作接口 │ ├── native_save_file() 保存文件 │ ├── native_read_file() 读取文件 │ └── native_get_file_info() 文件信息 ├── 媒体框架层 │ ├── Stagefright框架 (Android原生) │ │ ├── OMX编解码组件 │ │ ├── MediaSource数据源 │ │ └── MediaBuffer数据缓冲 │ ├── OpenMAX IL接口 │ │ ├── OMX_Init() 初始化 │ │ ├── OMX_GetHandle() 获取句柄 │ │ └── OMX_FreeHandle() 释放句柄 │ └── 硬件编解码接口 │ ├── 硬件编码器 (H.264/H.265) │ ├── 硬件解码器 │ └── 图像处理ISP ├── 第三方库层 │ ├── FFmpeg多媒体库 │ │ ├── avcodec 编解码 │ │ ├── avformat 格式处理 │ │ ├── avfilter 滤镜处理 │ │ └── swscale 缩放转换 │ ├── OpenCV图像处理 │ │ ├── 图像采集 │ │ ├── 特征提取 │ │ └── 目标识别 │ └── x264/x265编码器 │ ├── 高质量H.264编码 │ └── 高效率H.265编码 └── 系统库层 ├── libc标准库 ├── libz压缩库 └── liblog日志库
// 视频文件处理的Native层伪代码 JNIEXPORT void JNICALL Java_com_android_gps_tracker_utils_Utils_saveVideoFrame( JNIEnv *env, jclass clazz, jbyteArray frameData, jint width, jint height, jstring filePath) { const char *path = (*env)->GetStringUTFChars(env, filePath, NULL); jbyte *data = (*env)->GetByteArrayElements(env, frameData, NULL); jsize length = (*env)->GetArrayLength(env, frameData); // 1. 打开文件 FILE *fp = fopen(path, "ab"); if (!fp) { // 错误处理 return; } // 2. 写入帧数据 // H.264 NAL单元处理 if (isH264Frame(data, length)) { // 查找起始码 0x00000001 或 0x000001 // 写入NAL单元 fwrite(data, 1, length, fp); } // H.265 HEVC处理 else if (isH265Frame(data, length)) { // HEVC NAL单元处理 fwrite(data, 1, length, fp); } // 3. 刷新缓冲区 fflush(fp); fclose(fp); // 4. 释放资源 (*env)->ReleaseStringUTFChars(env, filePath, path); (*env)->ReleaseByteArrayElements(env, frameData, data, 0); } // DMS视频分析的Native处理 JNIEXPORT jint JNICALL Java_com_android_gps_tracker_utils_Utils_analyzeDMSFrame( JNIEnv *env, jclass clazz, jbyteArray frameData, jint width, jint height) { jbyte *data = (*env)->GetByteArrayElements(env, frameData, NULL); // 转换为OpenCV Mat cv::Mat frame(height, width, CV_8UC3, (void*)data); // 1. 人脸检测 std::vector<cv::Rect> faces; face_cascade.detectMultiScale(frame, faces, 1.1, 3, 0, cv::Size(30, 30)); // 2. 眼睛状态检测 int eye_state = EYE_OPEN; for (const auto& face : faces) { cv::Mat faceROI = frame(face); // 眼睛检测算法 if (isEyeClosed(faceROI)) { eye_state = EYE_CLOSED; break; } } // 3. 嘴部状态检测 (打哈欠) int mouth_state = MOUTH_CLOSED; for (const auto& face : faces) { cv::Mat faceROI = frame(face); if (isYawning(faceROI)) { mouth_state = MOUTH_OPEN_YAWN; break; } } // 4. 头部姿态检测 (分心驾驶) int head_pose = HEAD_FRONT; for (const auto& face : faces) { cv::Mat faceROI = frame(face); head_pose = estimateHeadPose(faceROI); } (*env)->ReleaseByteArrayElements(env, frameData, data, 0); // 返回检测结果 return (eye_state << 16) | (mouth_state << 8) | head_pose; }视频编码Native库架构 ├── 编码器核心层 │ ├── 视频编码器接口 │ │ ├── initEncoder() 初始化 │ │ ├── encodeFrame() 编码帧 │ │ ├── getEncodedData() 获取编码数据 │ │ └── releaseEncoder() 释放 │ ├── 音频编码器接口 │ │ ├── initAudioEncoder() 音频初始化 │ │ ├── encodeAudio() 音频编码 │ │ └── releaseAudioEncoder() 释放 │ └── 封装器接口 │ ├── initMuxer() 初始化封装 │ ├── writeFrame() 写入帧 │ └── finalizeMuxer() 完成封装 ├── 硬件加速层 │ ├── MediaCodec硬件编码 │ │ ├── createEncoderByType() 创建编码器 │ │ ├── configure() 配置 │ │ ├── start() 开始 │ │ └── release() 释放 │ ├── OpenGL ES渲染 │ │ ├── EGL环境初始化 │ │ ├── 纹理创建和绑定 │ │ └── 着色器编程 │ └── GPU计算 │ ├── OpenCL并行计算 │ └── RenderScript图像处理 ├── 格式处理层 │ ├── MP4封装器 │ │ ├── MP4文件头写入 │ │ ├── moov原子写入 │ │ ├── mdat原子写入 │ │ └── 索引表生成 │ ├── AVI封装器 │ │ ├── AVI文件头 │ │ ├── 视频流头 │ │ ├── 音频流头 │ │ └── 索引块 │ └── FLV封装器 │ ├── FLV文件头 │ ├── 脚本数据 │ └── 音视频标签 └── 质量控制层 ├── 码率控制 │ ├── CBR固定码率 │ ├── VBR可变码率 │ └── ABR自适应码率 ├── 质量评估 │ ├── PSNR峰值信噪比 │ ├── SSIM结构相似性 │ └── VMAF视频多方法评估 └── 预处理 ├── 降噪滤波 ├── 色彩校正 └── 分辨率缩放
摄像头HAL层架构 ├── 摄像头HAL接口定义 │ ├── camera_module_t结构体 │ │ ├── get_number_of_cameras() 获取摄像头数量 │ │ ├── get_camera_info() 获取摄像头信息 │ │ └── set_callbacks() 设置回调 │ ├── camera_device_t结构体 │ │ ├── common摄像头通用接口 │ │ └── ops操作函数表 │ └── camera_device_ops_t操作表 │ ├── set_preview_window() 设置预览窗口 │ ├── set_notify_callback() 设置通知回调 │ ├── start_preview() 开始预览 │ ├── stop_preview() 停止预览 │ ├── take_picture() 拍照 │ ├── cancel_picture() 取消拍照 │ ├── start_recording() 开始录制 │ ├── stop_recording() 停止录制 │ └── release() 释放资源 ├── Vendor HAL实现 │ ├── Qualcomm摄像头HAL │ │ ├── mm-camera驱动接口 │ │ ├── 3A算法 (AF/AE/AWB) │ │ ├── ISP图像处理 │ │ └── 传感器控制 │ ├── Samsung摄像头HAL │ │ ├── 多摄像头支持 │ │ ├── 双摄算法 │ │ └── 实时HDR │ └── 海思摄像头HAL │ ├── 智能编码 │ ├── 低光增强 │ └── 运动检测 ├── 摄像头服务层 │ ├── CameraService系统服务 │ │ ├── 摄像头设备管理 │ │ ├── 权限控制 │ │ ├── 资源调度 │ │ └── 状态监控 │ └── 相机应用框架 │ ├── Camera API (旧版) │ ├── Camera2 API (新版) │ └── CameraX Jetpack库 └── 内核驱动层 ├── V4L2视频驱动框架 │ ├── video_device结构体 │ ├── v4l2_ioctl_ops操作表 │ ├── 缓冲区管理 (mmap/userptr) │ └── 控制接口 (brightness/contrast) ├── 传感器驱动 │ ├── I2C总线通信 │ ├── 寄存器配置 │ ├── 时序控制 │ └── 数据读取 └── ISP图像处理 ├── 原始数据接收 ├── 图像处理流水线 ├── 统计信息收集 └── 输出格式转换
视频编码硬件加速HAL ├── 编码器HAL接口 │ ├── video_encoder_device_t结构体 │ │ ├── init_encoder() 初始化编码器 │ │ ├── encode_frame() 编码帧 │ │ ├── get_encoded_data() 获取编码数据 │ │ └── release_encoder() 释放编码器 │ └── 编码参数结构体 │ ├── 编码格式 (H.264/H.265/VP8/VP9) │ ├── 分辨率 (width/height) │ ├── 帧率 (fps) │ ├── 码率 (bitrate) │ └── GOP结构 ├── 硬件编码器实现 │ ├── 视频处理单元 (VPU) │ │ ├── 硬件编码引擎 │ │ ├── 运动估计硬件 │ │ ├── DCT/IDCT硬件 │ │ └── 熵编码硬件 │ ├── GPU编码 │ │ ├── NVIDIA NVENC │ │ ├── AMD VCE │ │ └── Intel Quick Sync │ └── DSP编码 │ ├── 高通Hexagon DSP │ ├── 海思HiVCodec │ └── 联发科APU ├── 内存管理 │ ├── DMA缓冲区 │ │ ├── 物理地址映射 │ │ ├── 缓存一致性 │ │ └── 零拷贝传输 │ └── 共享内存 │ ├── ion内存分配器 │ ├── dma-buf缓冲区共享 │ └── 内存保护 └── 电源管理 ├── DVFS动态调频调压 ├── 时钟门控 ├── 电源门控 └── 温度监控
视频文件相关系统服务调用路径 1. 摄像头拍照调用路径: App: Utils.startToService() → Intent → startService() → Framework: ActivityManagerService.startService() → 视频服务进程: onCreate() → onStartCommand() → Camera.open() → Camera.takePicture() → JNI: android_hardware_Camera.cpp → CameraService: connect() → startPreview() → takePicture() → Camera HAL: camera_device_ops_t.take_picture() → 内核驱动: V4L2 ioctl(VIDIOC_S_FMT/VIDIOC_REQBUFS/VIDIOC_QBUF) → 传感器: I2C寄存器配置 → 图像捕获 → ISP处理 → JPEG编码 → 文件保存 2. 视频录制调用路径: App: MediaRecorder.setVideoSource() → setOutputFormat() → prepare() → start() → Framework: MediaRecorder.java → JNI → Stagefright: MediaRecorderClient → MediaPlayerService → OMX编码器: OMXNodeInstance → 硬件编码器 → 摄像头数据流: Camera → Surface → BufferQueue → 编码数据流: MediaCodec → MediaMuxer → 文件写入 3. 文件上传调用路径: App: mUploadManager.startUploadFile() → 网络库: OkHttp/Retrofit 或 自定义Socket → Framework: java.net.Socket 或 HttpURLConnection → Bionic: libc socket系统调用 → 内核: TCP/IP协议栈 → 网络驱动 → 物理层: WiFi/4G/5G网络传输
V4L2内核驱动架构 ├── V4L2核心框架 │ ├── 设备管理 │ │ ├── video_device结构体 │ │ ├── v4l2_device结构体 │ │ ├── 设备注册 (video_register_device) │ │ └── 设备注销 (video_unregister_device) │ ├── 缓冲区管理 │ │ ├── videobuf2核心框架 │ │ │ ├── vb2_queue队列管理 │ │ │ ├── vb2_buffer缓冲区结构 │ │ │ ├── 内存分配器接口 │ │ │ └── 操作回调表 │ │ └── 内存类型支持 │ │ ├── V4L2_MEMORY_MMAP (内存映射) │ │ ├── V4L2_MEMORY_USERPTR (用户指针) │ │ ├── V4L2_MEMORY_DMABUF (DMA缓冲区) │ │ └── V4L2_MEMORY_OVERLAY (叠加层) │ └── 控制接口 │ ├── v4l2_ioctl_ops操作表 │ │ ├── vidioc_querycap 查询设备能力 │ │ ├── vidioc_enum_fmt 枚举格式 │ │ ├── vidioc_s_fmt 设置格式 │ │ ├── vidioc_reqbufs 请求缓冲区 │ │ ├── vidioc_querybuf 查询缓冲区 │ │ ├── vidioc_qbuf 队列缓冲区 │ │ ├── vidioc_dqbuf 出队缓冲区 │ │ ├── vidioc_streamon 开始流 │ │ └── vidioc_streamoff 停止流 │ └── 控制子系统 │ ├── v4l2_ctrl_handler控制处理器 │ ├── 标准控制 (亮度/对比度/饱和度) │ └── 自定义控制 ├── 摄像头传感器驱动 │ ├── I2C子系统集成 │ │ ├── i2c_client结构体 │ │ ├── i2c_driver结构体 │ │ ├── i2c_transfer数据传输 │ │ └→ I2C总线通信 │ ├── 传感器配置 │ │ ├── 寄存器映射表 │ │ ├── 初始化序列 │ │ ├── 分辨率配置 │ │ ├── 帧率配置 │ │ └── 曝光控制 │ └── 数据接口 │ ├── MIPI CSI-2接口 │ │ ├→ CSI协议层 │ │ ├→ D-PHY物理层 │ │ └→ 数据包解析 │ └→ 并行接口 │ ├→ 数据线 │ ├→ 同步信号 │ └→ 时钟信号 ├── ISP图像处理驱动 │ ├── 图像处理流水线 │ │ ├→ 黑电平校正 │ │ ├→ 镜头阴影校正 │ │ ├→ 坏点校正 │ │ ├→ 去马赛克 │ │ ├→ 自动白平衡 │ │ ├→ 自动曝光 │ │ ├→ 自动对焦 │ │ ├→ 色彩校正矩阵 │ │ ├→ Gamma校正 │ │ ├→ 色彩空间转换 │ │ ├→ 噪声滤波 │ │ ├→ 边缘增强 │ │ └→ 图像缩放 │ └→ 统计信息收集 │ ├→ AE统计 (亮度直方图) │ ├→ AWB统计 (色彩统计) │ ├→ AF统计 (对比度检测) │ └→ 反馈控制 └── 视频输出驱动 ├→ 显示控制器 ├→ 帧缓冲设备 └→ HDMI/MIPI DSI输出
视频编码内核模块 ├── 硬件编码器驱动 │ ├── 设备驱动框架 │ │ ├── platform_driver平台驱动 │ │ ├── 设备树绑定 │ │ ├── 资源分配 (内存/I/O/中断) │ │ └── 电源管理 │ ├── 寄存器接口 │ │ ├→ 控制寄存器 │ │ ├→ 状态寄存器 │ │ ├→ 配置寄存器 │ │ └→ 中断寄存器 │ ├── DMA引擎 │ │ ├→ 描述符链 │ │ ├→ 地址映射 │ │ ├→ 传输控制 │ │ └→ 完成中断 │ └→ 编码算法硬件 │ ├→ 运动估计引擎 │ ├→ DCT/IDCT引擎 │ ├→ 量化引擎 │ ├→ 熵编码引擎 │ ├→ 码率控制 │ └→ 参考帧管理 ├── V4L2编码器接口 │ ├→ 编码器设备注册 │ ├→ 输出格式设置 │ ├→ 码率控制接口 │ ├→ GOP结构设置 │ ├→ 量化参数设置 │ ├→ 编码控制 │ └→ 状态查询 ├── 媒体控制器框架 │ ├→ media_device媒体设备 │ ├→ media_entity媒体实体 │ ├→ media_pad媒体焊盘 │ ├→ media_link媒体链接 │ └→ 拓扑结构管理 └→ 内存管理 ├→ CMA连续内存分配器 ├→ ion内存分配器 ├→ dma-buf缓冲区共享 ├→ 缓存一致性维护 └→ 零拷贝优化
文件系统内核层 ├── 虚拟文件系统 (VFS) │ ├── 统一文件模型 │ │ ├→ super_block超级块 │ │ ├→ inode索引节点 │ │ ├→ dentry目录项 │ │ ├→ file文件对象 │ │ └→ address_space地址空间 │ ├── 文件操作接口 │ │ ├→ file_operations文件操作表 │ │ │ ├→ open打开文件 │ │ │ ├→ release关闭文件 │ │ │ ├→ read读取文件 │ │ │ ├→ write写入文件 │ │ │ ├→ mmap内存映射 │ │ │ ├→ fsync同步文件 │ │ │ └→ lseek文件定位 │ │ └→ inode_operations索引节点操作 │ │ ├→ create创建文件 │ │ ├→ lookup查找文件 │ │ ├→ unlink删除文件 │ │ └→ rename重命名 │ └→ 路径名查找 │ ├→ path_lookup路径查找 │ ├→ 目录项缓存 (dcache) │ └→ 索引节点缓存 (icache) ├── 具体文件系统 │ ├→ EXT4文件系统 │ │ ├→ 日志机制 │ │ ├→ 扩展属性 │ │ ├→ 在线调整大小 │ │ ├→ 延迟分配 │ │ ├→ 多块分配 │ │ └→ 加密支持 │ ├→ F2FS闪存友好文件系统 │ │ ├→ 日志结构文件系统 │ │ ├→ 热冷数据分离 │ │ ├→ 垃圾回收 │ │ ├→ TRIM支持 │ │ └→ 压缩支持 │ └→ exFAT文件系统 │ ├→ FAT表管理 │ ├→ 簇分配 │ ├→ 时间戳 │ └→ 大文件支持 ├→ 块设备层 │ ├→ 块设备驱动 │ │ ├→ 请求队列 │ │ ├→ 电梯算法 │ │ ├→ 请求合并 │ │ ├→ 预读机制 │ │ └→ 写回缓存 │ ├→ 存储设备 │ │ ├→ eMMC/UFS │ │ ├→ SD卡 │ │ ├→ NVMe │ │ └→ SATA │ └→ 存储控制器 │ ├→ 闪存转换层 (FTL) │ ├→ 磨损均衡 │ ├→ 坏块管理 │ └→ 纠错编码 └→ 内存文件系统 ├→ tmpfs临时文件系统 ├→ ramdisk内存磁盘 └→ squashfs只读压缩文件系统
视频文件生成完整数据流向 ┌─────────────────────────────────────────────────────────────┐ │ 应用层 (GpsTrackerService) │ ├─────────────────────────────────────────────────────────────┤ │ 1. 事件触发 (碰撞/DMS/RFID) │ │ 2. 调用Utils.startToService()启动视频服务 │ │ 3. Intent封装参数传递给视频服务 │ │ ↓ (Binder IPC) │ ├─────────────────────────────────────────────────────────────┤ │ 视频服务进程 (独立进程) │ ├─────────────────────────────────────────────────────────────┤ │ 4. Service.onStartCommand()接收参数 │ │ 5. 初始化摄像头: Camera.open() │ │ 6. 配置摄像头参数: setParameters() │ │ 7. 设置预览窗口: setPreviewDisplay() │ │ 8. 开始预览: startPreview() │ │ 9. 开始录制: MediaRecorder.start() 或 拍照: takePicture() │ │ ↓ (JNI调用) │ ├─────────────────────────────────────────────────────────────┤ │ JNI层 (C/C++) │ ├─────────────────────────────────────────────────────────────┤ │10. 调用Camera HAL接口 │ │ ↓ (Binder IPC) │ ├─────────────────────────────────────────────────────────────┤ │ CameraService (system_server进程) │ ├─────────────────────────────────────────────────────────────┤ │11. Camera HAL调用摄像头驱动 │ │ ↓ (系统调用) │ ├─────────────────────────────────────────────────────────────┤ │ 内核层 │ ├─────────────────────────────────────────────────────────────┤ │12. V4L2驱动处理ioctl命令 │ │13. 传感器配置通过I2C总线 │ │14. 图像数据通过MIPI CSI-2接口传输 │ │15. ISP图像信号处理 │ │16. 编码器硬件编码 (H.264/H.265) │ │17. 编码数据写入文件系统 │ │ ↑ (系统调用返回) │ ├─────────────────────────────────────────────────────────────┤ │ 视频服务进程 (独立进程) │ ├─────────────────────────────────────────────────────────────┤ │18. 接收编码完成回调 │ │19. 发送广播通知文件生成完成 │ │ ↑ (Binder IPC) │ ├─────────────────────────────────────────────────────────────┤ │ 应用层 (GpsTrackerService) │ ├─────────────────────────────────────────────────────────────┤ │20. 接收广播通知 │ │21. 触发文件上传逻辑 │ │22. 调用startUploadFile()开始上传 │ └─────────────────────────────────────────────────────────────┘
视频文件上传完整数据流向 ┌─────────────────────────────────────────────────────────────┐ │ 应用层 (GpsTrackerService) │ ├─────────────────────────────────────────────────────────────┤ │ 1. startUploadFile()调用上传管理器 │ │ 2. UploadManager.startUploadFile() │ │ 3. 数据库记录插入 (DBHelper) │ │ 4. 文件分块读取 │ │ 5. 网络传输准备 │ │ ↓ (网络库调用) │ ├─────────────────────────────────────────────────────────────┤ │ 网络传输层 (Java Socket/HTTP) │ ├─────────────────────────────────────────────────────────────┤ │ 6. Socket连接建立 或 HTTP请求发送 │ │ ↓ (JNI调用) │ ├─────────────────────────────────────────────────────────────┤ │ JNI层 (C/C++) │ ├─────────────────────────────────────────────────────────────┤ │ 7. libc socket系统调用 │ │ ↓ (系统调用) │ ├─────────────────────────────────────────────────────────────┤ │ 内核层 │ ├─────────────────────────────────────────────────────────────┤ │ 8. TCP/IP协议栈处理 │ │ 9. 网络设备驱动传输 │ │10. 物理层网络传输 │ │11. 服务器接收处理 │ │ ↑ (网络响应) │ ├─────────────────────────────────────────────────────────────┤ │ 网络传输层 (Java Socket/HTTP) │ ├─────────────────────────────────────────────────────────────┤ │12. 接收服务器响应 │ │13. 解析响应状态 │ │ ↑ (回调处理) │ ├─────────────────────────────────────────────────────────────┤ │ 应用层 (GpsTrackerService) │ ├─────────────────────────────────────────────────────────────┤ │14. onUploadResponse()回调处理 │ │15. 成功: 删除数据库记录 │ │16. 失败: 触发重传机制 │ │17. 更新上传状态 │ └─────────────────────────────────────────────────────────────┘