staticvoid android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, jint msgType)
{ALOGV("takePicture");JNICameraContext* context;sp<Camera> 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;}
}
2.3 C/C++ Libraries
2.3.1 Camera.cpp
位置:frameworks/av/camera/Camera.cpp
takePicture():
獲取一個(gè) ICamera,調(diào)用其 takePicture 接口。
這里直接用 return 的方式調(diào)用,比較簡(jiǎn)單。
// take a picture
status_t Camera::takePicture(int msgType)
{ALOGV("takePicture: 0x%x", msgType);sp <::android::hardware::ICamera> c = mCamera;if (c == 0) return NO_INIT;return c->takePicture(msgType);
}
// 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();
}
// callback from camera service when frame or image is readyvoid Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,camera_frame_metadata_t *metadata)
{sp<CameraListener> listener;{Mutex::Autolock _l(mLock);listener = mListener;}if (listener != NULL) {listener->postData(msgType, dataPtr, metadata);}
}
void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr,camera_frame_metadata_t *metadata)
{// VM pointer will be NULL if object is releasedMutex::Autolock _l(mLock);JNIEnv *env = AndroidRuntime::getJNIEnv();if (mCameraJObjectWeak == NULL) {ALOGW("callback on dead camera object");return;}int32_t dataMsgType = msgType & ~CAMERA_MSG_PREVIEW_METADATA;// return data based on callback typeswitch (dataMsgType) {case CAMERA_MSG_VIDEO_FRAME:// should never happenbreak;// For backward-compatibility purpose, if there is no callback// buffer for raw image, the callback returns null.case CAMERA_MSG_RAW_IMAGE:ALOGV("rawCallback");if (mRawImageCallbackBuffers.isEmpty()) {env->CallStaticVoidMethod(mCameraJClass, fields.post_event,mCameraJObjectWeak, dataMsgType, 0, 0, NULL);} else {copyAndPost(env, dataPtr, dataMsgType);}break;// There is no data.case0:break;default:ALOGV("dataCallback(%d, %p)", dataMsgType, dataPtr.get());copyAndPost(env, dataPtr, dataMsgType);break;}// post frame metadata to Javaif (metadata && (msgType & CAMERA_MSG_PREVIEW_METADATA)) {postMetadata(env, CAMERA_MSG_PREVIEW_METADATA, metadata);}
}
如果要自定義一個(gè)對(duì)數(shù)據(jù)進(jìn)行處理的 C++ 功能庫,并將其加入相機(jī)中,我們可以通過對(duì) HAL 層進(jìn)行一些修改,將 RAW 圖像流向我們的處理過程,再將處理后的 RAW 圖像傳回 HAL 層(需要在 HAL 層對(duì) RAW 格式進(jìn)行一些處理才能把圖像上傳),最后通過正常的回調(diào)流程把圖像傳到頂層應(yīng)用中,就可以實(shí)現(xiàn)我們的自定義功能了。
至此,對(duì)于整個(gè) Camera 的框架,及其運(yùn)作方式,我們就已經(jīng)有了比較清晰的了解了。
在 Android 5.0 版本后,Camera 推出了 Camera API 2,它有著全新的流程(但總體架構(gòu)是不會(huì)有大變化的)。接下來我會(huì)找空余的時(shí)間去學(xué)習(xí)學(xué)習(xí)這個(gè)新的東西,到時(shí)候再另開一系列的學(xué)習(xí)筆記吧。