四 android_hardware_Camera_setPreviewDisplay(JNI)
這個接口函數的作用是爲Preview分配內存。
static void
android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface)
{
LOGV("setPreviewDisplay");
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
sp<Surface> surface = NULL;
if (jSurface != NULL) {
surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
}
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
}
}
在camera.cpp中;
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
{
LOGV("setPreviewDisplay");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
if (surface != 0) {
return c->setPreviewDisplay(surface->getISurface());
} else {
LOGD("app passed NULL surface");
return c->setPreviewDisplay(0);
}
}
這裏跳到cameraservice.cpp 中。
status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
{
LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
result = NO_ERROR;
// return if no change in surface.
// asBinder() is safe on NULL (returns NULL)
if (surface->asBinder() == mSurface->asBinder()) {
return result;
}
if (mSurface != 0) {
LOG1("clearing old preview surface %p", mSurface.get());
if (mUseOverlay) {
// Force the destruction of any previous overlay
sp<Overlay> dummy;
mHardware->setOverlay(dummy);
mOverlayRef = 0;
} else {
mSurface->unregisterBuffers();
}
}
mSurface = surface;
mOverlayRef = 0;
// If preview has been already started, set overlay or register preview
// buffers now.
if (mHardware->previewEnabled() || mUseOverlay) {
if (mUseOverlay) {
if( mSurface != NULL)
result = setOverlay(); //創建、初始化overlay
//在實際中對這些Surface 進行merge 可以採用兩種方式,一種就是採用軟件的形式來merge
,還一種就是採用硬件的方式,軟件的方式就是我們的SurfaceFlinger ,而硬件的方式就是Overlay
} else if (mSurface != 0) {
result = registerPreviewBuffers(); //註冊preview buffer
}
}
return result;
}