一、命令流程
1.APP
packages/apps/Camera/src/com/android/camera/PhotoModule.java
private void startPreview() {
mCameraDevice.setPreviewDisplayAsync(mCameraSurfaceHolder);
mCameraDevice.startPreviewAsync();
}
packages/apps/Camera/src/com/android/camera/CameraManager.java
public void setPreviewDisplayAsync(final SurfaceHolder surfaceHolder) {
mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder).sendToTarget();
}
public void startPreviewAsync() {
mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
}
public void handleMessage(final Message msg) {
switch (msg.what) {
case SET_PREVIEW_DISPLAY_ASYNC:
try {
mCamera.setPreviewDisplay((SurfaceHolder) msg.obj);
} catch(IOException e) {
throw new RuntimeException(e);
}
return; // no need to call mSig.open()
case START_PREVIEW_ASYNC:
mCamera.startPreview();
return; // no need to call mSig.open()
}
}
2.frameworks
frameworks/base/core/java/android/hardware/Camera.java
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
setPreviewDisplay(holder.getSurface());
}
public native final void startPreview();
frameworks/base/core/jni/android_hardware_Camera.cpp
static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface){
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
}
}
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz){
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera->startPreview() != NO_ERROR) {
jniThrowRuntimeException(env, "startPreview failed");
return;
}
}
frameworks/av/camera/Camera.cpp
status_t Camera::setPreviewDisplay(const sp<Surface>& surface){
sp <ICamera> c = mCamera;
return c->setPreviewDisplay(surface);
}
status_t Camera::startPreview(){
sp <ICamera> c = mCamera;
return c->startPreview();
}
Binder调用
frameworks/av/services/camera/libcameraservice/CameraClient.cpp
status_t CameraClient::setPreviewDisplay(const sp<Surface>& surface) {
return setPreviewWindow(binder, window);
}
status_t CameraClient::startPreview() {
return startCameraMode(CAMERA_PREVIEW_MODE);
}
status_t CameraClient::startCameraMode(camera_mode mode) {
switch(mode) {
case CAMERA_PREVIEW_MODE:
return startPreviewMode();
}
}
status_t CameraClient::startPreviewMode() {
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
}
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
status_t setPreviewWindow(const sp<ANativeWindow>& buf){
mPreviewWindow = buf;
/*
#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
static ANativeWindow *__to_anw(void *user){
CameraHardwareInterface *__this =
reinterpret_cast<CameraHardwareInterface *>(user);
return __this->mPreviewWindow.get();
}
*/
return mDevice->ops->set_preview_window(mDevice,
buf.get() ? &mHalPreviewWindow.nw : 0);
/*
void initHalPreviewWindow(){
mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer;
mHalPreviewWindow.nw.lock_buffer = __lock_buffer;
mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer;
mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer;
mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count;
mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry;
mHalPreviewWindow.nw.set_crop = __set_crop;
mHalPreviewWindow.nw.set_timestamp = __set_timestamp;
mHalPreviewWindow.nw.set_usage = __set_usage;
mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval;
mHalPreviewWindow.nw.get_min_undequeued_buffer_count =
__get_min_undequeued_buffer_count;
}
*/
}
status_t startPreview(){
return mDevice->ops->start_preview(mDevice);
}
3.HAL
hardware/amlogic/camera/CameraHal_Module.cpp
int camera_set_preview_window(struct camera_device * device,
struct preview_stream_ops *window){
rv = gCameraHals[aml_dev->cameraid]->setPreviewWindow(window);
}
int camera_start_preview(struct camera_device * device){
rv = gCameraHals[aml_dev->cameraid]->startPreview();
}
hardware/amlogic/camera/CameraHal.cpp
status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window){
mDisplayAdapter = new ANativeWindowDisplayAdapter();
mDisplayAdapter->setFrameProvider(mCameraAdapter); //将frameCallbackRelay设置为BaseCameraAdapter的回调函数
mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get()); //设置BaseCameraAdapter错误处理函数
ret = mDisplayAdapter->setPreviewWindow(window);//设置post的Surface
/*
hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp
int ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window){
mANativeWindow = window;
}
*/
}
status_t CameraHal::startPreview(){
//hardware/amlogic/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
//#define DEFAULT_PREVIEW_PIXEL_FORMAT V4L2_PIX_FMT_NV21
ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers);
/*
status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat,
unsigned int buffercount, unsigned int &max_queueable){
mPreviewBufs = (int32_t *) mDisplayAdapter->allocateBuffer(width, height,
previewFormat,
mPreviewLength,
buffercount);
}
hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp
void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs){
err = mANativeWindow->set_buffers_geometry(
mANativeWindow,
width,
height,
mNativeWindowPixelFormat); //NV21
}
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
static int __set_buffers_geometry(struct preview_stream_ops* w,
int width, int height, int format){
ANativeWindow *a = anw(w);
//#define anw(n) __to_anw(((struct camera_preview_window *)n)->user)
//__this->mPreviewWindow.get();
return native_window_set_buffers_geometry(a,
width, height, format);
}
*/
}
二、数据流程
hardware/amlogic/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
int V4LCameraAdapter::previewThread(){
yuyv422_to_nv21(src,dest,width,height);
frame.mFrameMask |= CameraFrame::PREVIEW_FRAME_SYNC;
frame.mPixelFmt = mPixelFormat;
ret = sendFrameToSubscribers(&frame);
}
hardware/amlogic/camera/BaseCameraAdapter.cpp
status_t BaseCameraAdapter::sendFrameToSubscribers(CameraFrame *frame){
ret = __sendFrameToSubscribers(frame, &mFrameSubscribers, CameraFrame::PREVIEW_FRAME_SYNC);
}
status_t BaseCameraAdapter::__sendFrameToSubscribers(CameraFrame* frame,
KeyedVector<int, frame_callback> *subscribers,
CameraFrame::FrameType frameType){
callback = (frame_callback) subscribers->valueAt(k);
callback(frame);
}
hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp
void ANativeWindowDisplayAdapter::frameCallbackRelay(CameraFrame* caFrame){
ANativeWindowDisplayAdapter *da = (ANativeWindowDisplayAdapter*) caFrame->mCookie;
da->frameCallback(caFrame);
}
void ANativeWindowDisplayAdapter::frameCallback(CameraFrame* caFrame){
PostFrame(df);
}
status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame){
mANativeWindow->set_crop(mANativeWindow, xOff/bytesPerPixel, yOff,
(xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight);
ret = mANativeWindow->enqueue_buffer(mANativeWindow, mBufferHandleMap[i]);
}
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
static int __set_crop(struct preview_stream_ops *w,
int left, int top, int right, int bottom){
ANativeWindow *a = anw(w);
return native_window_set_crop(a, &crop);
}
static int __enqueue_buffer(struct preview_stream_ops* w,
buffer_handle_t* buffer){
ANativeWindow *a = anw(w);
return a->queueBuffer(a,
container_of(buffer, ANativeWindowBuffer, handle), -1);
}