如何在android framewrok dump camera data

實現dump 函數

實現1

void dumpBufferToFile(buffer_handle_t* buffer, int width, int height, int frameNum) {void* data = NULL;GraphicBufferMapper::getInstance().lock(*buffer, GRALLOC_USAGE_SW_READ_OFTEN, Rect(width, height), &data);char filename[128];sprintf(filename, "/data/vendor/camera/frame_%04d.yuv", frameNum);FILE* fp = fopen(filename, "wb");if (fp && data) {fwrite(data, 1, width * height * 3 / 2, fp); // 如果是 NV12/YUV420fclose(fp);}GraphicBufferMapper::getInstance().unlock(*buffer);
}

實現2

#include <stdio.h>
#include <fcntl.h>
#include <string>
#include <sys/mman.h>
#include <hardware/gralloc.h>
#include <ui/GraphicBufferMapper.h>
#include <cutils/native_handle.h>
#include <android/hardware_buffer.h>using namespace android;// Camera format types
#define CAMERA_FORMAT_RAW16   0x20
#define CAMERA_FORMAT_RAW10   0x25
#define CAMERA_FORMAT_RAW12   0x26
#define CAMERA_FORMAT_YUV_420_888 0x23
#define CAMERA_FORMAT_JPEG    0x100// Helper: Get format name
const char* getFormatSuffix(int format) {switch (format) {case HAL_PIXEL_FORMAT_YCbCr_420_888:return ".yuv";case HAL_PIXEL_FORMAT_BLOB:return ".jpg";case HAL_PIXEL_FORMAT_RAW16:return ".raw16";case HAL_PIXEL_FORMAT_RAW10:return ".raw10";case HAL_PIXEL_FORMAT_RAW12:return ".raw12";default:return ".bin";}
}void dumpBufferToFile(buffer_handle_t handle, int width, int height, int frameNum, int format) {void* data = nullptr;uint32_t size = 0;// Lock buffer for readingGraphicBufferMapper& mapper = GraphicBufferMapper::get();android_ycbcr ycbcr = {};int usage = GRALLOC_USAGE_SW_READ_OFTEN;if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {if (mapper.lockYCbCr(handle, usage, {0, 0, width, height}, &ycbcr) == OK) {data = ycbcr.y;size = width * height * 3 / 2;}} else {if (mapper.lock(handle, usage, {0, 0, width, height}, &data) == OK) {switch (format) {case HAL_PIXEL_FORMAT_RAW16:size = width * height * 2;break;case HAL_PIXEL_FORMAT_RAW10:size = width * height * 10 / 8;break;case HAL_PIXEL_FORMAT_RAW12:size = width * height * 12 / 8;break;case HAL_PIXEL_FORMAT_BLOB:// BLOB: Usually JPEG// You may need to get actual size from metadata, here we assume maxsize = width * height;break;default:size = width * height * 4; // assume RGBA fallback}}}if (data == nullptr || size == 0) {ALOGE("dumpBufferToFile: failed to lock buffer");return;}// Generate file pathchar path[256];snprintf(path, sizeof(path), "/data/vendor/camera/dump_%04d%s", frameNum, getFormatSuffix(format));// Dump to fileFILE* fp = fopen(path, "wb");if (fp) {fwrite(data, 1, size, fp);fclose(fp);ALOGI("dumpBufferToFile: dumped frame %d to %s", frameNum, path);} else {ALOGE("dumpBufferToFile: failed to open file %s", path);}// Unlock buffermapper.unlock(handle);
}

添加調用位置

推薦位置 1, Camera3OutputStream::queueBufferToConsumer()

此函數負責將 HAL 返回的 buffer 通過 ANativeWindow 傳給 Surface,因此非常適合 dump。
status_t Camera3OutputStream::queueBufferToConsumer(sp<GraphicBuffer>& buffer, ...)
{dumpBufferToFile(buffer->getNativeBuffer()->handle, mWidth, mHeight, mFrameNumber);// 原邏輯繼續res = mConsumer->queueBuffer(...);
}

推薦位置 2,Camera3Device::processCaptureResult()

HAL 返回一個 camera3_capture_result_t 結構,這里可以拿到 metadata 和 buffer。
    for (size_t i = 0; i < result->num_output_buffers; i++) {const camera3_stream_buffer_t &buffer = result->output_buffers[i];Camera3OutputStreamInterface* stream = static_cast<Camera3OutputStreamInterface*>(buffer.stream->priv);// 📌 拿到 buffer 后 dumpdumpBufferToFile(buffer.buffer, stream->getWidth(), stream->getHeight(), result->frame_number);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93304.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93304.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93304.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習中的可解釋性:深入理解SHAP值及其應用

機器學習可解釋性的重要性在人工智能技術快速發展的2025年&#xff0c;機器學習模型已經深度滲透到醫療診斷、金融風控、司法量刑等關鍵領域。然而&#xff0c;隨著模型復雜度的不斷提升&#xff0c;一個根本性矛盾日益凸顯&#xff1a;模型預測性能的提升往往以犧牲可解釋性為…

.NET9 使用 OData 協議項目實戰

.NET 中 ODate 協議介紹 OData(Open Data Protocol) 是一個開放的 Web 協議&#xff0c;用于查詢和更新數據。在 .NET 生態系統中&#xff0c;OData 被廣泛支持和使用。 主要特性 1. 統一的數據訪問方式 提供標準化的查詢語法支持 CRUD 操作支持元數據描述 2. 查詢能力 標…

Android 性能優化:提升應用啟動速度(GC抑制)

前言 在移動應用開發領域&#xff0c;啟動速度是用戶體驗的重要指標。對于Android應用而言&#xff0c;垃圾回收&#xff08;Garbage Collection, GC&#xff09;機制雖然是內存管理的核心&#xff0c;但在應用啟動期間頻繁觸發GC會顯著拖慢啟動速度。本文將深入探討如何通過GC…

做了一款小而美的本地校驗器

需求說明 前陣子收到一則讀者留言&#xff0c;指出&#xff1a;市面上AI核稿工具&#xff08;ProWritingAid&#xff0c;WPS AI Spell Check&#xff0c;Writer&#xff0c;QuillBot&#xff0c;Grammarly&#xff09;要么收費太高&#xff0c;要么讓人擔心文章泄露。 如下圖所…

uniapp + uview-plus 微信小程序二維碼生成和保存完整解決方案

uniapp + uview-plus 微信小程序二維碼生成和保存完整解決方案 ?? 項目背景 在開發微信小程序時,經常需要實現二維碼的生成和保存功能。本文檔提供了一個基于 uniapp + uview-plus 框架的完整解決方案,徹底解決了以下常見問題: ? Canvas API 兼容性問題 ? 微信小程序權…

Linux中應用程序的安裝于管理

Linux中應用程序的安裝于管理 一 . rpm安裝 1.掛載 光驅里面存放了很多rpm的軟件包 光驅在系統中使用時&#xff0c;需要掛載 mount /dev/cdrom /mnt/ cd /mnt[rootstw mnt]# ls CentOS_BuildTag GPL LiveOS RPM-GPG-KEY-CentOS-7 EFI images Packag…

mysql重置密碼

要區分 MySQL 是通過 systemd 還是傳統 service 管理&#xff0c;以及對應的密碼重置方案&#xff0c;可按以下步驟操作&#xff1a; 一、如何區分管理方式&#xff08;systemd 還是傳統 service&#xff09; 通過以下命令判斷系統默認的服務管理方式&#xff1a;檢查系統是否使…

C++ TAP(基于任務的異步編程模式)

&#x1f680; C TAP&#xff08;基于任務的異步編程模式&#xff09;1. 引言&#xff1a;走進異步編程新時代&#xff08;&#x1f680;&#xff09; 在當今高性能計算領域&#xff0c;同步編程模型的局限性日益凸顯。傳統的回調地獄和線程管理復雜性促使微軟提出了基于任務的…

利用C++手撕棧與隊列的基本功能(四)

棧和隊列詳細教程可以觀看 https://www.bilibili.com/video/BV1nJ411V7bd?spm_id_from333.788.videopod.episodes&vd_sourcedaed5b8a51d3ab7eb209efa9d0ff9a34&p48棧和隊列概念 棧和隊列是限定插入和刪除只能在表的端點進行的線性表在裝電池、裝彈夾、拿放盤子時都會出…

net8.0一鍵創建支持(Redis)

Necore項目生成器 - 在線創建Necore模板項目 | 一鍵下載 RedisController.cs using CSRedis; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using UnT.Template.Application.Responses; using UnT.Template.Domain;namespace UnT.Template.Controllers {…

Leetcode——42. 接雨水

還記得第一次見該題根本無從下手。其實&#xff0c;我們不妨把問題拆解&#xff0c;簡單化。不要怕自己寫的是暴力算法&#xff0c;有很多算法技巧其實就是在暴力算法的基礎上優化得來。題目目的是求所有可接雨水數量&#xff0c;我們可以求出每一個位置可接雨水數量&#xff0…

Go 語言-->指針

Go 語言–>指針 它允許你操作內存中的實際數據&#xff0c;而不僅僅是數據的副本。指針存儲的是另一個變量的內存地址&#xff0c;而不是變量的實際值。 1. 什么是指針 指針是存儲變量內存地址的變量&#xff0c;它指向另一個變量。通過指針&#xff0c;你可以間接地訪問和修…

軟工八將:軟件開發全流程核心角色體系解析

軟工八將&#xff1a;軟件開發全流程核心角色體系解析 作者注&#xff1a;本概念是由大學生董翔提出&#xff0c;具有一些影響意義。 在現代軟件開發領域&#xff0c;團隊角色的專業化分工是產品成功的核心保障。“軟工八將”作為一套系統梳理軟件開發全流程核心角色的術語&…

安全風險監測系統是什么?內容有哪些?

安全風險監測系統是基于物聯網感知網絡與智能分析技術的綜合管理平臺&#xff0c;通過實時采集、分析和評估各類安全風險指標&#xff0c;構建起覆蓋識別、預警、處置全流程的主動防御體系。作為現代安全管理的中樞神經系統&#xff0c;該系統實現了從被動響應到主動預防的范式…

車載診斷架構 ---面向售后的DTC應該怎么樣填寫?

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

墨者:SQL注入漏洞測試(寬字節)

墨者學院&#xff1a;SQL注入漏洞測試(寬字節)&#x1f680; 1. 寬字節注入原理? 1.1. 與普通注入對比? 特性普通注入寬字節注入適用場景無轉義處理使用addslashes()等轉義函數核心原理直接閉合引號利用GBK等編碼吞掉轉義符\關鍵字符 " -- #%df %5c防御難度易防御需調…

(二)Eshop(RabbitMQ手動)

文章目錄項目地址一、Rabbit MQ1.1 Pulibsher1. IRabbitMQPublisher接口2. RabbitMQPublisher接口實現3. 使用1.2 Consumer1. 消費接口2. 實現消費者接口項目地址 教程作者&#xff1a;教程地址&#xff1a; 代碼倉庫地址&#xff1a; 所用到的框架和插件&#xff1a; dbt a…

WPF高級學習(一)

文章目錄一、理解進程和線程1. 進程&#xff1a;就像一個獨立的“工廠”舉例&#xff1a;2. 線程&#xff1a;就像工廠里的“工人”舉例&#xff1a;總結&#xff1a;進程 vs 線程二、線程一、WPF 中的線程類型二、核心規則&#xff1a;線程親和性&#xff08;Thread Affinity&…

JAVA知識點(四):SpringBoot與分布式、微服務架構

文章目錄SpringBoot 使用 Validation 進行參數校驗并統一返回校驗異常引入相應的依賴Validation的基本校驗注解添加參數校驗在DTO的屬性上添加校驗在controller對應的DTO添加Valid或者Validated對于復雜String校驗我們可以使用正則來校驗&#xff0c;如下所示&#xff1a;自定義…

GPU 服務器ecc報錯處理

1. 常見原因分析內存硬件問題&#xff1a;DIMM 內存模塊損壞或接觸不良&#xff08;最常見原因&#xff09;。內存插槽氧化、松動或物理損壞。內存與主板兼容性問題&#xff08;尤其是非原廠內存&#xff09;。環境因素&#xff1a;服務器內部溫度過高&#xff0c;導致內存穩定…