1. 初始化8K HDR Camera会话
任务目标
在Qualcomm平台(如SM8550/SM8650)上,通过Camera HAL3接口配置并启动一个支持8K分辨率(7680×4320)与HDR(10-bit)输出的相机会话,并验证基本预览通路是否正常建立。本案例聚焦于会话初始化与预览流配置,不涉及拍照或录像。
环境依赖
- 硬件:Qualcomm 8K HDR平台设备(如SM8550 MTP/QRD)
- 系统:Android 13+(Camera HAL3已启用)
- NDK:android.hardware.camera2 NDK API(android.hardware.camera2包)
- 权限:
CAMERA权限已在AndroidManifest中声明
关键实现
以下代码使用Camera2 NDK API创建8K HDR预览会话。核心步骤包括:查询8K HDR能力、配置输出流、创建会话并启动预览请求。代码通过ACameraManager获取相机实例,使用ACaptureSessionOutputContainer管理输出流,并设置10-bit HDR像素格式。
// camera_8k_hdr_session.cpp
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraCaptureSession.h>
#include <camera/NdkCameraMetadata.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <android/hardware_buffer.h>
#include <vector>
#include <cstring>
// 8K HDR会话初始化类
class Camera8KHdrSession {
public:
bool initialize(ANativeWindow* previewWindow) {
// 1. 获取相机管理器
camera_manager_ = ACameraManager_create();
if (!camera_manager_) return false;
// 2. 选择后置相机(ID "0")
const char* camera_id = "0";
ACameraMetadata* metadata = nullptr;
if (ACameraManager_getCameraCharacteristics(camera_manager_, camera_id, &metadata) != ACAMERA_OK) {
return false;
}
// 3. 验证8K HDR能力
if (!check8KHdrCapability(metadata)) {
ACameraMetadata_free(metadata);
return false;
}
ACameraMetadata_free(metadata);
// 4. 打开相机设备
ACameraDevice_StateCallbacks device_callbacks = {};
device_callbacks.onDisconnected = [](void*, ACameraDevice*) {};
device_callbacks.onError = [](void*, ACameraDevice*, int) {};
if (ACameraManager_openCamera(camera_manager_, camera_id, &device_callbacks, &camera_device_) != ACAMERA_OK) {
return false;
}
// 5. 配置8K HDR输出流
if (!configureStreams(previewWindow)) {
return false;
}
// 6. 创建捕获会话
if (!createCaptureSession()) {
return false;
}
// 7. 启动预览请求
return startPreview();
}
void destroy() {
if (capture_session_) {
ACameraCaptureSession_stopRepeating(capture_session_);
ACameraCaptureSession_close(capture_session_);
}
if (camera_device_) {
ACameraDevice_close(camera_device_);
}
if (camera_manager_) {
ACameraManager_delete(camera_manager_);
}
}
private:
ACameraManager* camera_manager_ = nullptr;
ACameraDevice* camera_device_ = nullptr;
ACameraCaptureSession* capture_session_ = nullptr;
ACaptureSessionOutputContainer* output_container_ = nullptr;
ACaptureSessionOutput* session_output_ = nullptr;
ACameraOutputTarget* output_target_ = nullptr;
ANativeWindow* preview_window_ = nullptr;
AImageReader* image_reader_ = nullptr;
// 检查是否支持8K HDR(10-bit)输出
bool check8KHdrCapability(ACameraMetadata* metadata) {
// 查询流配置能力
ACameraMetadata_const_entry entry;
if (ACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry) != ACAMERA_OK) {
return false;
}
bool has_8k_hdr = false;
for (int i = 0; i < entry.count; i += 4) {
int32_t format = entry.data.i32[i];
int32_t width = entry.data.i32[i + 1];
int32_t height = entry.data.i32[i + 2];
int32_t direction = entry.data.i32[i + 3];
// 检查输出方向(1=输出)且为8K分辨率
if (direction == 1 && width == 7680 && height == 4320) {
// 检查是否为10-bit HDR格式(HAL_PIXEL_FORMAT_RGBA_1010102 = 43)
if (format == 43) { // RGBA_1010102
has_8k_hdr = true;
break;
}
}
}
return has_8k_hdr;
}
// 配置8K HDR输出流
bool configureStreams(ANativeWindow* previewWindow) {
preview_window_ = previewWindow;
// 创建ImageReader用于8K HDR帧获取(可选,用于验证)
media_status_t status = AImageReader_new(7680, 4320, AIMAGE_FORMAT_RGBA_1010102, 1, &image_reader_);
if (status != AMEDIA_OK) return false;
// 获取ImageReader的NativeWindow
ANativeWindow* reader_window = nullptr;
AImageReader_getWindow(image_reader_, &reader_window);
// 创建输出容器
if (ACaptureSessionOutputContainer_create(&output_container_) != ACAMERA_OK) {
return false;
}
// 添加预览窗口输出
if (ACaptureSessionOutput_create(preview_window_, &session_output_) != ACAMERA_OK) {
return false;
}
if (ACaptureSessionOutputContainer_add(output_container_, session_output_) != ACAMERA_OK) {
return false;
}
// 创建输出目标
if (ACameraOutputTarget_create(preview_window_, &output_target_) != ACAMERA_OK) {
return false;
}
return true;
}
// 创建捕获会话
bool createCaptureSession() {
ACameraCaptureSession_stateCallbacks session_callbacks = {};
session_callbacks.onReady = [](void*, ACameraCaptureSession*) {};
session_callbacks.onActive = [](void*, ACameraCaptureSession*) {};
// 创建会话
camera_status_t status = ACameraDevice_createCaptureSession(camera_device_, output_container_, &session_callbacks, &capture_session_);
return status == ACAMERA_OK;
}
// 启动预览请求
bool startPreview() {
// 创建捕获请求
ACameraCaptureRequest* request = nullptr;
if (ACameraDevice_createCaptureRequest(camera_device_, TEMPLATE_PREVIEW, &request) != ACAMERA_OK) {
return false;
}
// 添加输出目标
if (ACameraCaptureRequest_addTarget(request, output_target_) != ACAMERA_OK) {
ACameraCaptureRequest_free(request);
return false;
}
// 设置HDR相关参数(10-bit色调映射)
// 注意:实际HDR参数需根据具体传感器能力设置
// 此处设置基础参数确保会话可用
uint8_t tonemap_mode = ACAMERA_TONEMAP_MODE_HDR;
ACameraCaptureRequest_setEntryU8(request, ACAMERA_TONEMAP_MODE, &tonemap_mode, 1);
// 设置重复请求
int32_t sequence_id = 0;
camera_status_t status = ACameraCaptureSession_setRepeatingRequest(capture_session_, nullptr, 1, &request, &sequence_id);
ACameraCaptureRequest_free(request);
return status == ACAMERA_OK;
}
};
调用与验证
在Android应用层通过JNI调用上述类,传入SurfaceView的NativeWindow。验证步骤如下:
- 初始化调用:在
onSurfaceCreated回调中调用initialize(),传入Surface的NativeWindow。 - 观察预览:若会话成功,SurfaceView应显示实时相机预览画面。
- 日志验证:在
onReady回调中打印日志,确认会话状态为ACAMERA_CAPTURE_SESSION_READY。 - 分辨率确认:通过
adb shell dumpsys media.camera查看当前活跃会话的输出流配置,确认分辨率为7680×4320且格式为RGBA_1010102。
通过条件:预览画面正常显示且无错误回调;dumpsys输出显示8K HDR流已激活。
常见问题
- 会话创建失败:确认设备支持8K HDR输出,且SurfaceView尺寸与8K匹配(需在布局中设置固定尺寸)。
- 预览黑屏:检查是否设置了正确的HDR像素格式,部分设备需要显式设置
ACAMERA_CONTROL_ENABLE_ZSL为false。 - 性能不足:8K预览需要较高带宽,建议在真机测试而非模拟器。