千家信息网

android7相机拍照流程是怎样的

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,今天小编给大家分享一下android7相机拍照流程是怎样的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我
千家信息网最后更新 2026年11月03日android7相机拍照流程是怎样的

今天小编给大家分享一下android7相机拍照流程是怎样的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

在 Camera 流程中,还有一个重要的部分,即数据流。
Camera API 1 中,数据流主要是通过函数回调的方式,依照从下往上的方向,逐层 return 到 Applications 中。
由于数据流的部分相对来说比较简单,所以我就将其与 Camera 的控制流结合起来,从 takePicture() 方法切入,追踪一个比较完整的 Camera 流程。

位置:frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
setCallback():
设置 notify 回调,这用来通知数据已经更新。
设置 data 回调以及 dataTimestamp 回调,对应的是函数指针 mDataCb 与 mDataCvTimestamp 。
注意到,设置 mDevice->ops 对应回调函数时,传入的不是之前设置的函数指针,而是 __data_cb 这样的函数。在该文件中,实现了 __data_cb ,将回调函数做了一层封装。
/** Set the notification and data callbacks */
void setCallbacks(notify_callback notify_cb,
data_callback data_cb,
data_callback_timestamp data_cb_timestamp,
void* user)
{
mNotifyCb = notify_cb;
mDataCb = data_cb;
mDataCbTimestamp = data_cb_timestamp;
mCbUser = user;

ALOGV("%s(%s)", __FUNCTION__, mName.string());

if (mDevice->ops->set_callbacks) {
mDevice->ops->set_callbacks(mDevice,
__notify_cb,
__data_cb,
__data_cb_timestamp,
__get_memory,
this);
}
}

__data_cb():
对原 callback 函数简单封装,附加了一个防止数组越界判断。
static void __data_cb(int32_t msg_type,
const camera_memory_t *data, unsigned int index,
camera_frame_metadata_t *metadata,
void *user)
{
ALOGV("%s", __FUNCTION__);
CameraHardwareInterface *__this =
static_cast(user);
sp mem(static_cast(data->handle));
if (index >= mem->mNumBufs) {
ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
index, mem->mNumBufs);
return;
}
__this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
}
位置:frameworks/base/core/jni/android_hardware_Camera.cpp
takePicture():
获取已经打开的 camera 实例,调用其 takePicture() 接口。
注意,在这个函数中,对于 RAW_IMAGE 有一些附加操作:
如果设置了 RAW 的 callback ,则要检查上下文中,是否能找到对应 Buffer。
若无法找到 Buffer ,则将 CAMERA_MSG_RAW_IMAGE 的信息去掉,换成 CAMERA_MSG_RAW_IMAGE_NOTIFY。
替换后,就只会获得 notification 的消息,而没有对应的图像数据。

static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, jint msgType)
{
ALOGV("takePicture");
JNICameraContext* context;

//先前有分析,https://my.oschina.net/u/920274/blog/5034592
sp camera = get_native_camera(env, thiz, &context);
if (camera == 0) return;

/*
* When CAMERA_MSG_RAW_IMAGE is requested, if the raw image callback
* buffer is available, CAMERA_MSG_RAW_IMAGE is enabled to get the
* notification _and_ the data; otherwise, CAMERA_MSG_RAW_IMAGE_NOTIFY
* is enabled to receive the callback notification but no data.
*
* Note that CAMERA_MSG_RAW_IMAGE_NOTIFY is not exposed to the
* Java application.
*/
if (msgType & CAMERA_MSG_RAW_IMAGE) {
ALOGV("Enable raw image callback buffer");
if (!context->isRawImageCallbackBufferAvailable()) {
ALOGV("Enable raw image notification, since no callback buffer exists");
msgType &= ~CAMERA_MSG_RAW_IMAGE;
msgType |= CAMERA_MSG_RAW_IMAGE_NOTIFY;
}
}

if (camera->takePicture(msgType) != NO_ERROR) {
jniThrowRuntimeException(env, "takePicture failed");
return;
}
}

调用camera->takePicture(msgType)后,来到下面的地方。

位置:frameworks/av/camera/Camera.cpp
takePicture():
获取一个 ICamera,调用其 takePicture 接口。
这里直接用 return 的方式调用,比较简单。

// take a picture
status_t Camera::takePicture(int msgType)
{
ALOGV("takePicture: 0x%x", msgType);

//https://my.oschina.net/u/920274/blog/5034592 有分析
sp c = mCamera;
if (c == 0) return NO_INIT;
return c->takePicture(msgType);
}

然后跳转到

位置:frameworks/av/camera/ICamera.cpp
takePicture():
利用 Binder 机制发送相应指令到服务端。
实际调用到的是 CameraClient::takePicture() 函数。

// take a picture - returns an IMemory (ref-counted mmap)
status_t takePicture(int msgType)
{
ALOGV("takePicture: 0x%x", msgType);
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(msgType);

//后面会分析这个地方的调用
remote()->transact(TAKE_PICTURE, data, &reply);
status_t ret = reply.readInt32();
return ret;
}

remote()->transact(TAKE_PICTURE, data, &reply);

binder调用到文件的CameraService.cpp的CameraService::onTransact方法

status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {

const int pid = getCallingPid();
const int selfPid = getpid();

// Permission checks
switch (code) {
case BnCameraService::CONNECT:
case BnCameraService::CONNECT_DEVICE:
case BnCameraService::CONNECT_LEGACY: {
if (pid != selfPid) {
// we're called from a different process, do the real check
if (!checkCallingPermission(
String16("android.permission.CAMERA"))) {
const int uid = getCallingUid();
ALOGE("Permission Denial: "
"can't use the camera pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
}
}
break;
}
case BnCameraService::NOTIFY_SYSTEM_EVENT: {
if (pid != selfPid) {
// Ensure we're being called by system_server, or similar process with
// permissions to notify the camera service about system events
if (!checkCallingPermission(
String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
const int uid = getCallingUid();
ALOGE("Permission Denial: cannot send updates to camera service about system"
" events from pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
}
}
break;
}
}

return BnCameraService::onTransact(code, data, reply, flags); //然后会调用到这来
}

继续往下到文件ICameraService.cpp


status_t BnCameraService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
。。。
。。。
default:
return BBinder::onTransact(code, data, reply, flags);
}
}

继续会调用到文件ICamera.cpp


status_t BnCamera::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {

case TAKE_PICTURE: {
ALOGV("TAKE_PICTURE");
CHECK_INTERFACE(ICamera, data, reply);
int msgType = data.readInt32();
reply->writeInt32(takePicture(msgType));
return NO_ERROR;
} break;

default:
return BBinder::onTransact(code, data, reply, flags);
}
}

会调用到文件CameraClient.cpp下的takePicture(),是因为CameraClient继承 BnCamera

继续往下看文件 CameraClient.cpp

// take a picture - image is returned in callback
status_t CameraClient::takePicture(int msgType) {
LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);

Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;

if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
(msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
" cannot be both enabled");
return BAD_VALUE;
}

// We only accept picture related message types
// and ignore other types of messages for takePicture().
int picMsgType = msgType
& (CAMERA_MSG_SHUTTER |
CAMERA_MSG_POSTVIEW_FRAME |
CAMERA_MSG_RAW_IMAGE |
CAMERA_MSG_RAW_IMAGE_NOTIFY |
CAMERA_MSG_COMPRESSED_IMAGE);

enableMsgType(picMsgType);

return mHardware->takePicture();
}

位置:frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h
takePicture():
通过 mDevice 中设置的函数指针,调用 HAL 层中具体平台对应的 takePicture 操作的实现逻辑。
接下来就是与具体的平台相关的流程了,这部分内容对我并非主要,而且在上一篇笔记中已经有比较深入的探索,所以在这里就不继续向下挖掘了。
控制流程到了 HAL 层后,再向 Linux Drivers 发送控制指令,从而使具体的 Camera 设备执行指令,并获取数据。
/**
* Take a picture.
*/
status_t takePicture()
{
ALOGV("%s(%s)", __FUNCTION__, mName.string());
if (mDevice->ops->take_picture)
return mDevice->ops->take_picture(mDevice);
return INVALID_OPERATION;
}

后面就是 数据流
由于数据流是通过 callback 函数实现的,所以探究其流程的时候我是从底层向上层进行分析的。

以上就是"android7相机拍照流程是怎样的"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

函数 数据 流程 文件 位置 数据流 知识 篇文章 分析 内容 就是 指令 指针 控制 相机 地方 平台 接口 方式 方法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 湖北九亚互联网络科技有限公司 广州淘业互联网络科技 中关村互联网科技集团 科技互联网产品 喔噻互联网科技 互联网与未来科技 唐信互联网科技 壕鑫互联网络科技 赫美联合互联网科技 亿人帮互联网科技 科技类的互联网平台 互联网科技公司招聘 北京大学互联网科技怎么样 中国的互联网科技企业的崛起 承德科技产业互联网发展 南平创想时代互联网科技有限公司 苏州五指互联网络科技有限 天津腾达互联网科技有限公司 长沙茂晟互联网科技有限公司 互联网高科技行业有哪些企业 猪兼强互联网科技 极限挑战互联网科技 互联网科技股午盘股票涨跌 汽车互联网创新科技园 互联网科技公司实习生 沐思想互联网科技有限公司 产业互联网科技服务公司 浙南科技城互联网大厦招聘 上海万顺科技互联网有限公司招聘 互联网科技职业技能培训学校
0