前言:
最近在做一个有关于HDMI IN的需求,需要找到传入数据的buffer地址,方便以后如果有修改数据的需求的话,可以快速实现,参考了很多人的博客,在此记录一下寻找的过程,一点愚见,希望大家多多指教。
手上平台使用的是HAL1。
参考:
android Camera API1+HAL1 open camera流程 & Android M_徐而思齐的博客-CSDN博客
android camera mmap,Android Camera 流程学习记录(四)—— Camera.startPreview() flow_Robby Robby的博客-CSDN博客
【Camera专题】HAL层-深入浅出startPreview - 简书
Camera HAL(Camera Preview)_honghong96的博客-CSDN博客_camera preview
Android4.4 Camera callback注册和回调过程分析_哇小明的博客-CSDN博客_callback接口
高通camera框架之如何打通App-Hardware经络_简一商业的博客-CSDN博客
分析:
硬件上是通过一个ic芯片将HDMI IN数据流转换成MIPI CSI,再一步步传输给上层;所以对于camera HAL来说,它在获取HDMI IN的数据和摄像头的数据所经历的过程是一样的。
由于HDMI IN的功能是通过打开应用camera预览来进行显示的,这里从camera的预览作为切入点:
追踪 Camera.startPreview() 方法:
以下为摘抄内容:
1. Frameworks
1.1 Camera.java位置:frameworks/base/core/java/android/hardware/Camera.java
startPreview():
给上层 application 提供一个接口。
进入 Runtime 层。
2. Android Runtime
2.1 android_hardware_Camera.cpp
位置:frameworks/base/core/jni/android_hardware_Camera.cpp
android_hardware_Camera_startPreview():
调用 get_native_camera() 函数获取一个 Camera 实例。
调用 Camera::startPreview()。
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
ALOGV("startPreview");
sp camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
if (camera->startPreview() != NO_ERROR) {
jniThrowRuntimeException(env, "startPreview failed");
return;
}
}
3.1 Camera.cpp
位置:frameworks/av/camera/Camera.cpp
startPreview():
mCamera 便是在 connect 过程当中返回的 CameraClient,它具体实现了 startPreview() 接口。
调用 CameraClient::startPreview()。
// start preview mode
status_t Camera::startPreview()
{
ALOGV("startPreview");
sp <::android::hardware::icamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->startPreview();
}
3.2 CameraClient.cpp
位置:frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp
startPreview():
经过 startCameraMode 函数进入具体的实现逻辑。
// start preview mode
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
经过 startCameraMode 函数进入具体的实现逻辑。
// start preview or recording
status_t CameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
switch(mode) {
case CAMERA_PREVIEW_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
LOG1("mSurface is not set yet.");
// still able to start preview in this case.
}
return startPreviewMode();
case CAMERA_RECORDING_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
根据传入的参数 CAMERA_PREVIEW_MODE 肯定进入的分支。
调用 startPreviewMode() 。
status_t CameraClient::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// if preview has been enabled, nothing needs to be done
if (mHardware->previewEnabled()) {
return NO_ERROR;
}
if (mPreviewWindow != 0) {
mHardware->setPreviewScalingMode(
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
mHardware->setPreviewTransform(mOrientation);
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
if (result == NO_ERROR) {
sCameraService->updateProxyDeviceState(
hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
mCameraIdStr, mCameraFacing, mClientPackageName,
hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
}
return result;
}
若是预览已经存在,则直接返回成功信息。
若是未存在,则继续往下走。