Android Camera2 App

android 4.4 camera

Posted by LXG on December 4, 2021

camera-AOSP

SurfaceView, TextureView, SurfaceTexture等的区别

TextureView SurfaceTexture

surface_texture

Camera2 App

CameraActivity


public class CameraActivity extends Activity {

    // PhotoModule
    private CameraModule mCurrentModule;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);

        LayoutInflater inflater = getLayoutInflater();
        View rootLayout = inflater.inflate(R.layout.camera, null, false);
        mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);


        mCurrentModule.init(this, mCameraModuleRootView);

    }


    @Override
    public void onResume() {

        mCurrentModule.onResumeBeforeSuper();
        super.onResume();
        mCurrentModule.onResumeAfterSuper();

    }

}

PhotoModule


public class PhotoModule implements CameraModule, FocusOverlayManager.Listener {

    // copied from Camera hierarchy
    private CameraActivity mActivity;

    private CameraProxy mCameraDevice;

    private int mCameraId;

    private Parameters mParameters;

    private PhotoUI mUI;


    @Override
    public void init(CameraActivity activity, View parent) {
        mActivity = activity;
        mUI = new PhotoUI(activity, this, parent);

        mCameraId = getPreferredCameraId(mPreferences);



    }

    @Override
    public void onResumeAfterSuper() {

            onResumeTasks();

    }

    private void onResumeTasks() {

        if (!prepareCamera()) {
            // Camera failure.
            return;
        }

    }

    private boolean prepareCamera() {

        Log.v(TAG, "Open camera device.");
        mCameraDevice = CameraUtil.openCamera(
                mActivity, mCameraId, mHandler,
                mActivity.getCameraOpenErrorCallback());

        if (mCameraDevice == null) {
            Log.e(TAG, "Failed to open camera:" + mCameraId);
            return false;
        }
        mParameters = mCameraDevice.getParameters();

        setCameraParameters(UPDATE_PARAM_ALL);

        startPreview();

    }

    // We separate the parameters into several subsets, so we can update only
    // the subsets actually need updating. The PREFERENCE set needs extra
    // locking because the preference can be changed from GLThread as well.
    private void setCameraParameters(int updateSet) {

        mCameraDevice.setParameters(mParameters);

    }


    @Override
    public void onPreviewUIReady() {
        startPreview();
    }



    /** This can run on a background thread, post any view updates to MainHandler. */
    private void startPreview() {

         // Any decisions we make based on the surface texture state
         // need to be protected.
        SurfaceTexture st = mUI.getSurfaceTexture();
        if (st == null) {
            Log.w(TAG, "startPreview: surfaceTexture is not ready.");
            return;
        }

        setCameraParameters(UPDATE_PARAM_ALL);
        // Let UI set its expected aspect ratio
        mCameraDevice.setPreviewTexture(st);

        Log.v(TAG, "startPreview");
        mCameraDevice.startPreview();

    }


    @Override
    public void onShutterButtonClick() {

            mFocusManager.doSnap();
    }

    @Override
    public boolean capture() {

        mCameraDevice.takePicture(mHandler,
                new ShutterCallback(!animateBefore),
                mRawPictureCallback, mPostViewPictureCallback,
                new JpegPictureCallback(loc));

    }

    private final class PostViewPictureCallback
            implements CameraPictureCallback {
        @Override
        public void onPictureTaken(byte [] data, CameraProxy camera) {
            mPostViewPictureCallbackTime = System.currentTimeMillis();
            Log.v(TAG, "mShutterToPostViewCallbackTime = "
                    + (mPostViewPictureCallbackTime - mShutterCallbackTime)
                    + "ms");
        }
    }

    private final class RawPictureCallback
            implements CameraPictureCallback {
        @Override
        public void onPictureTaken(byte [] rawData, CameraProxy camera) {
            mRawPictureCallbackTime = System.currentTimeMillis();
            Log.v(TAG, "mShutterToRawCallbackTime = "
                    + (mRawPictureCallbackTime - mShutterCallbackTime) + "ms");
        }
    }

    private final class JpegPictureCallback
            implements CameraPictureCallback {

        @Override
        public void onPictureTaken(final byte [] jpegData, CameraProxy camera) {

        }

    }

}

PhotoUI


public class PhotoUI implements TextureView.SurfaceTextureListener {

    private PhotoController mController;

    private SurfaceTexture mSurfaceTexture;

    private TextureView mTextureView;

    public PhotoUI(CameraActivity activity, PhotoController controller, View parent) {
        mController = controller;

        mActivity.getLayoutInflater().inflate(R.layout.photo_module,
                (ViewGroup) mRootView, true);

        // display the view
        mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
        mTextureView.setSurfaceTextureListener(this);

    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            Log.v(TAG, "SurfaceTexture ready.");
            mSurfaceTexture = surface;
            mController.onPreviewUIReady();
    }

}

CameraHolder


public class CameraHolder {

    private CameraProxy mCameraDevice;

    public synchronized CameraProxy open(
            Handler handler, int cameraId,
            CameraManager.CameraOpenErrorCallback cb) {

            Log.v(TAG, "open camera " + cameraId);
                mCameraDevice = CameraManagerFactory
                        .getAndroidCameraManager().cameraOpen(handler, cameraId, cb);
    }

}

AndroidCameraManagerImpl


class AndroidCameraManagerImpl implements CameraManager {

    /* Messages used in CameraHandler. */
    // Camera initialization/finalization
    private static final int OPEN_CAMERA = 1;
    private static final int RELEASE =     2;
    private static final int RECONNECT =   3;
    private static final int UNLOCK =      4;
    private static final int LOCK =        5;
    // Preview
    private static final int SET_PREVIEW_TEXTURE_ASYNC =        101;
    private static final int START_PREVIEW_ASYNC =              102;
    private static final int STOP_PREVIEW =                     103;
    private static final int SET_PREVIEW_CALLBACK_WITH_BUFFER = 104;
    private static final int ADD_CALLBACK_BUFFER =              105;
    private static final int SET_PREVIEW_DISPLAY_ASYNC =        106;
    private static final int SET_PREVIEW_CALLBACK =             107;
    // Parameters
    private static final int SET_PARAMETERS =     201;
    private static final int GET_PARAMETERS =     202;
    private static final int REFRESH_PARAMETERS = 203;
    // Focus, Zoom
    private static final int AUTO_FOCUS =                   301;
    private static final int CANCEL_AUTO_FOCUS =            302;
    private static final int SET_AUTO_FOCUS_MOVE_CALLBACK = 303;
    private static final int SET_ZOOM_CHANGE_LISTENER =     304;
    // Face detection
    private static final int SET_FACE_DETECTION_LISTENER = 461;
    private static final int START_FACE_DETECTION =        462;
    private static final int STOP_FACE_DETECTION =         463;
    private static final int SET_ERROR_CALLBACK =          464;
    // Presentation
    private static final int ENABLE_SHUTTER_SOUND =    501;
    private static final int SET_DISPLAY_ORIENTATION = 502;

    private CameraHandler mCameraHandler;
    private android.hardware.Camera mCamera;

    // Used to retain a copy of Parameters for setting parameters.
    private Parameters mParamsToSet;

    AndroidCameraManagerImpl() {
        HandlerThread ht = new HandlerThread("Camera Handler Thread");
        ht.start();
        mCameraHandler = new CameraHandler(ht.getLooper());
    }

    private class CameraHandler extends Handler {

        public void requestTakePicture(
                final ShutterCallback shutter,
                final PictureCallback raw,
                final PictureCallback postView,
                final PictureCallback jpeg) {
            post(new Runnable() {
                @Override
                public void run() {
                    try {
                        mCamera.takePicture(shutter, raw, postView, jpeg);
                    } catch (RuntimeException e) {
                        // TODO: output camera state and focus state for debugging.
                        Log.e(TAG, "take picture failed.");
                        throw e;
                    }
                }
            });
        }


        @Override
        public void handleMessage(final Message msg) {
                switch (msg.what) {
                    case OPEN_CAMERA:
                        mCamera = android.hardware.Camera.open(msg.arg1);
                        return;
                    case START_PREVIEW_ASYNC:
                        mCamera.startPreview();
                        return;
                }
        }
    }

    public class AndroidCameraProxyImpl implements CameraManager.CameraProxy {


        @Override
        public void setPreviewTexture(SurfaceTexture surfaceTexture) {
            mCameraHandler.obtainMessage(SET_PREVIEW_TEXTURE_ASYNC, surfaceTexture).sendToTarget();
        }

        @Override
        public void startPreview() {
            mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC);
        }

        @Override
        public void takePicture(
                Handler handler,
                CameraShutterCallback shutter,
                CameraPictureCallback raw,
                CameraPictureCallback post,
                CameraPictureCallback jpeg) {
            mCameraHandler.requestTakePicture(
                    ShutterCallbackForward.getNewInstance(handler, this, shutter),
                    PictureCallbackForward.getNewInstance(handler, this, raw),
                    PictureCallbackForward.getNewInstance(handler, this, post),
                    PictureCallbackForward.getNewInstance(handler, this, jpeg));
        }

    }


    private static class PreviewCallbackForward implements PreviewCallback {

        private final Handler mHandler;
        private final CameraPreviewDataCallback mCallback;
        private final CameraProxy mCamera;

        /**
         * Returns a new instance of {@link PreviewCallbackForward}.
         *
         * @param handler The handler in which the callback will be invoked in.
         * @param camera  The {@link CameraProxy} which the callback is from.
         * @param cb      The callback to be invoked.
         * @return        The instance of the {@link PreviewCallbackForward},
         *                or null if any parameters is null.
         */
        public static PreviewCallbackForward getNewInstance(
                Handler handler, CameraProxy camera, CameraPreviewDataCallback cb) {
            if (handler == null || camera == null || cb == null) return null;
            return new PreviewCallbackForward(handler, camera, cb);
        }

        private PreviewCallbackForward(
                Handler h, CameraProxy camera, CameraPreviewDataCallback cb) {
            mHandler = h;
            mCamera = camera;
            mCallback = cb;
        }

        @Override
        public void onPreviewFrame(
                final byte[] data, android.hardware.Camera camera) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mCallback.onPreviewFrame(data, mCamera);
                }
            });
        }

    }

}

FocusOverlayManager


public class FocusOverlayManager {

    public void doSnap() {

            capture();

    }

    private void capture() {
        if (mListener.capture()) {
            mState = STATE_IDLE;
            mHandler.removeMessages(RESET_TOUCH_FOCUS);
        }
    }

}

Framework

Camera

frameworks/base/core/java/android/hardware/Camera.java


public class Camera {

    public static Camera open(int cameraId) {
        return new Camera(cameraId);
    }

    Camera(int cameraId) {
        mShutterCallback = null;
        mRawImageCallback = null;
        mJpegCallback = null;
        mPreviewCallback = null;
        mPostviewCallback = null;
        mUsingPreviewAllocation = false;
        mZoomListener = null;

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        String packageName = ActivityThread.currentPackageName();

        native_setup(new WeakReference<Camera>(this), cameraId, packageName);
    }

    private native final void native_setup(Object camera_this, int cameraId,
                                           String packageName);

    private native static void _getCameraInfo(int cameraId, CameraInfo cameraInfo);

    public native final void setPreviewTexture(SurfaceTexture surfaceTexture) throws IOException;

    public native final void startPreview();


    public interface PreviewCallback
    {
        /**
         * Called as preview frames are displayed.  This callback is invoked
         * on the event thread {@link #open(int)} was called from.
         *
         * <p>If using the {@link android.graphics.ImageFormat#YV12} format,
         * refer to the equations in {@link Camera.Parameters#setPreviewFormat}
         * for the arrangement of the pixel data in the preview callback
         * buffers.
         *
         * @param data the contents of the preview frame in the format defined
         *  by {@link android.graphics.ImageFormat}, which can be queried
         *  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.
         *  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}
         *             is never called, the default will be the YCbCr_420_SP
         *             (NV21) format.
         * @param camera the Camera service object.
         */
        void onPreviewFrame(byte[] data, Camera camera);
    };

    public final void takePicture(ShutterCallback shutter, PictureCallback raw,
            PictureCallback postview, PictureCallback jpeg) {
        mShutterCallback = shutter;
        mRawImageCallback = raw;
        mPostviewCallback = postview;
        mJpegCallback = jpeg;

        // If callback is not set, do not send me callbacks.
        int msgType = 0;
        if (mShutterCallback != null) {
            msgType |= CAMERA_MSG_SHUTTER;
        }
        if (mRawImageCallback != null) {
            msgType |= CAMERA_MSG_RAW_IMAGE;
        }
        if (mPostviewCallback != null) {
            msgType |= CAMERA_MSG_POSTVIEW_FRAME;
        }
        if (mJpegCallback != null) {
            msgType |= CAMERA_MSG_COMPRESSED_IMAGE;
        }

        native_takePicture(msgType);
        mFaceDetectionRunning = false;
    }

    /**
     * Callback interface used to supply image data from a photo capture.
     *
     * @see #takePicture(ShutterCallback, PictureCallback, PictureCallback, PictureCallback)
     */
    public interface PictureCallback {
        /**
         * Called when image data is available after a picture is taken.
         * The format of the data depends on the context of the callback
         * and {@link Camera.Parameters} settings.
         *
         * @param data   a byte array of the picture data
         * @param camera the Camera service object
         */
        void onPictureTaken(byte[] data, Camera camera);
    };

}

android_hardware_Camera.cpp

frameworks/base/core/jni/android_hardware_Camera.cpp

system/lib/libandroid_runtime.so


// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jstring clientPackageName)
{

    sp<Camera> camera = Camera::connect(cameraId, clientName,
            Camera::USE_CALLING_UID);

    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);

}


static void android_hardware_Camera_setPreviewTexture(JNIEnv *env,
        jobject thiz, jobject jSurfaceTexture)
{
    ALOGV("setPreviewTexture");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

    sp<IGraphicBufferProducer> producer = NULL;
    if (jSurfaceTexture != NULL) {
        producer = SurfaceTexture_getProducer(env, jSurfaceTexture);
        if (producer == NULL) {
            jniThrowException(env, "java/lang/IllegalArgumentException",
                    "SurfaceTexture already released in setPreviewTexture");
            return;
        }

    }

    if (camera->setPreviewTarget(producer) != NO_ERROR) {
        jniThrowException(env, "java/io/IOException",
                "setPreviewTexture failed");
    }
}

static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)
{
    ALOGV("startPreview");
    sp<Camera> camera = get_native_camera(env, thiz, NULL);
    if (camera == 0) return;

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

Camera.cpp

frameworks/av/camera/Camera.cpp

system/lib/libcamera_client.so


namespace android {

Camera::Camera(int cameraId)
    : CameraBase(cameraId)
{
}

CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
        &ICameraService::connect;

sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid)
{
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}

// pass the buffered IGraphicBufferProducer to the camera service
status_t Camera::setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)
{
    ALOGV("setPreviewTarget(%p)", bufferProducer.get());
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    ALOGD_IF(bufferProducer == 0, "app passed NULL surface");
    return c->setPreviewTarget(bufferProducer);
}

// start preview mode
status_t Camera::startPreview()
{
    ALOGV("startPreview");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startPreview();
}

}

CameraBase.cpp

frameworks/av/camera/CameraBase.cpp


// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()
{
    Mutex::Autolock _l(gLock);
    if (gCameraService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16(kCameraServiceName));
            if (binder != 0) {
                break;
            }
            ALOGW("CameraService not published, waiting...");
            usleep(kCameraServicePollDelay);
        } while(true);
        if (gDeathNotifier == NULL) {
            gDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(gDeathNotifier);
        gCameraService = interface_cast<ICameraService>(binder);
    }
    ALOGE_IF(gCameraService == 0, "no CameraService!?");
    return gCameraService;
}

template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                               const String16& clientPackageName,
                                               int clientUid)
{

    sp<TCam> c = new TCam(cameraId);
    const sp<ICameraService>& cs = getCameraService();

    //ICameraService::connect
    if (cs != 0) {
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        // Binder call media.server
        status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                             /*out*/ c->mCamera);
    }

    return c;  // return Camera object
}

mediaserver

/system/bin/mediaserver

frameworks/av/media/mediaserver/main_mediaserver.cpp

main_mediaserver.cpp


int main(int argc, char** argv)
{

        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        MediaPlayerService::instantiate();
        CameraService::instantiate();
        AudioPolicyService::instantiate();
        registerExtensions();
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();

}

BinderService.h

frameworks/native/include/binder/BinderService.h


class BinderService
{
public:
    static status_t publish(bool allowIsolated = false) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);
    }

    static void instantiate() { publish(); }

}

CameraService.cpp

frameworks/av/services/camera/libcameraservice/CameraService.cpp

system/lib/libcameraservice


CameraService::CameraService()
    :mSoundRef(0), mModule(0)
{
    ALOGI("CameraService started (pid=%d)", getpid());
    gCameraService = this;

    for (size_t i = 0; i < MAX_CAMERAS; ++i) {
        mStatusList[i] = ICameraServiceListener::STATUS_PRESENT;
    }

    this->camera_device_status_change = android::camera_device_status_change;
}

void CameraService::onFirstRef()
{
    LOG1("CameraService::onFirstRef");

    BnCameraService::onFirstRef();

    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
                (const hw_module_t **)&mModule) < 0) {
        ALOGE("Could not load camera HAL module");
        mNumberOfCameras = 0;
    }
    else {
        ALOGI("Loaded \"%s\" camera module", mModule->common.name);

        // 这个函数很重要,对于framework层来说只是拿到了camera的个数,但对于HAL层和drivers层来说camera的上电和初始化流程都是从这里开始
        mNumberOfCameras = mModule->get_number_of_cameras();
        if (mNumberOfCameras > MAX_CAMERAS) {
            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
                    mNumberOfCameras, MAX_CAMERAS);
            mNumberOfCameras = MAX_CAMERAS;
        }
        for (int i = 0; i < mNumberOfCameras; i++) {
            setCameraFree(i);
        }

        if (mModule->common.module_api_version >=
                CAMERA_MODULE_API_VERSION_2_1) {
            mModule->set_callbacks(this);
        }

        CameraDeviceFactory::registerService(this);
    }

}

HAL-A33-4.4

运行在/system/bin/mediaserver进程

HALCameraFactory.cpp

device/softwinner/polaris-common/hardware/camera/HALCameraFactory.cpp

system/lib/hw/camera.polaris.so


HALCameraFactory::HALCameraFactory()
        : mHardwareCameras(NULL),
          mAttachedCamerasNum(0),
          mRemovableCamerasNum(0),
          mConstructedOK(false)
{

	LOGD("camera hal version: %s", CAMERA_HAL_VERSION);

        /* Create the cameras */
	for (int id = 0; id < MAX_NUM_OF_CAMERAS; id++)
	{
		// camera config information
		mCameraConfig[id] = new CCameraConfig(id);
		if(mCameraConfig[id] == 0)
		{
			LOGW("create CCameraConfig failed");
		}
		else
		{
			mCameraConfig[id]->initParameters();
			mCameraConfig[id]->dumpParameters();
		}
	
		mHardwareCameras[id] = new CameraHardware(&HAL_MODULE_INFO_SYM.common, mCameraConfig[id])

	    }
	}

}

int HALCameraFactory::getCameraHardwareNum()
{

}

int HALCameraFactory::get_number_of_cameras(void)
{
    return gEmulatedCameraFactory.getCameraHardwareNum();
}

/* Entry point for camera HAL API. */
struct hw_module_methods_t HALCameraFactory::mCameraModuleMethods = {
    open: HALCameraFactory::device_open
};

camera_module_t HAL_MODULE_INFO_SYM = {
    common: {
         tag:           		HARDWARE_MODULE_TAG,
		 module_api_version:	CAMERA_DEVICE_API_VERSION_1_0,
		 hal_api_version:	 	HARDWARE_HAL_API_VERSION,
         id:            		CAMERA_HARDWARE_MODULE_ID,
         name:          		"V4L2Camera Module",
         author:        		"XSJ",
         methods:       		&android::HALCameraFactory::mCameraModuleMethods,
         dso:           		NULL,
         reserved:      		{0},
    },
    get_number_of_cameras:  	android::HALCameraFactory::get_number_of_cameras,
    get_camera_info:        	android::HALCameraFactory::get_camera_info,
};

CCameraConfig.h

./device/softwinner/astar-dvk3/configs/camera.cfg

./device/softwinner/polaris-common/hardware/camera/CCameraConfig.h


#define CAMERA_KEY_CONFIG_PATH	"/system/etc/camera.cfg"

CameraHardware2.cpp

./device/softwinner/polaris-common/hardware/camera/CameraHardware2.cpp


CameraHardware::CameraHardware(struct hw_module_t* module, CCameraConfig* pCameraCfg)
        : mPreviewWindow(),
          mCallbackNotifier(),
          mCameraConfig(pCameraCfg),
          mIsCameraIdle(true),
          mFirstSetParameters(true),
          mFullSizeWidth(0),
          mFullSizeHeight(0),
          mCaptureWidth(0),
          mCaptureHeight(0),
          mVideoCaptureWidth(0),
          mVideoCaptureHeight(0),
          mUseHwEncoder(false),
          mFaceDetection(NULL),
          mFocusStatus(FOCUS_STATUS_IDLE),
          mIsSingleFocus(false),
          mOriention(0),
          mAutoFocusThreadExit(true),
          mIsImageCaptureIntent(false),
          mIsSupportFocus(false),
          mIsSupportEffect(false),
          mIsSupportFlash(false),
          mIsSupportScene(false),
          mIsSupportWhiteBlance(false),
          mIsSupportExposure(false),
          mZoomRatio(100)
{
	// instance V4L2CameraDevice object
	mV4L2CameraDevice = new V4L2CameraDevice(this, &mPreviewWindow, &mCallbackNotifier);
	if (mV4L2CameraDevice == NULL)
	{
		LOGE("Failed to create V4L2Camera instance");
		return ;
	}
}

V4L2CameraDevice2.cpp


V4L2CameraDevice::V4L2CameraDevice(CameraHardware* camera_hal,
								   PreviewWindow * preview_window, 
    							   CallbackNotifier * cb)
    : mCameraHardware(camera_hal),
      mPreviewWindow(preview_window),
      mCallbackNotifier(cb),
      mCameraDeviceState(STATE_CONSTRUCTED),
      mCaptureThreadState(CAPTURE_STATE_NULL),
      mCameraFd(0),
      mIsUsbCamera(false),
      mTakePictureState(TAKE_PICTURE_NULL),
      mIsPicCopy(false),
      mFrameWidth(0),
      mFrameHeight(0),
      mThumbWidth(0),
      mThumbHeight(0),
      mCurFrameTimestamp(0),
      mBufferCnt(NB_BUFFER),
      mUseHwEncoder(false),
	  mNewZoom(0),
	  mLastZoom(-1),
	  mMaxZoom(0xffffffff),
	  mCaptureFormat(V4L2_PIX_FMT_NV21),
	  mVideoFormat(V4L2_PIX_FMT_NV21)
#ifdef USE_MP_CONVERT
	  ,mG2DHandle(0)
#endif
	  ,mCurrentV4l2buf(NULL)
	  ,mCanBeDisconnected(false)
	  ,mContinuousPictureStarted(false)
	  ,mContinuousPictureCnt(0)
	  ,mContinuousPictureMax(0)
	  ,mContinuousPictureStartTime(0)
	  ,mContinuousPictureLast(0)
	  ,mContinuousPictureAfter(0)
	  ,mFaceDectectLast(0)
	  ,mFaceDectectAfter(0)
	  ,mVideoHint(false)
	  ,mIsThumbUsedForVideo(false)
	  ,mVideoWidth(640)
	  ,mVideoHeight(480)
	  ,mFrameRate(30)
{
	LOGV("V4L2CameraDevice construct");
	memset(&mMapMem,0,sizeof(mMapMem));
	memset(&mVideoBuffer,0,sizeof(mVideoBuffer));

	memset(&mHalCameraInfo, 0, sizeof(mHalCameraInfo));
	memset(&mRectCrop, 0, sizeof(Rect));

	// init preview buffer queue
	OSAL_QueueCreate(&mQueueBufferPreview, NB_BUFFER);
	OSAL_QueueCreate(&mQueueBufferPicture, 2);
	
	pthread_mutex_init(&mConnectMutex, NULL);
	pthread_cond_init(&mConnectCond, NULL);

	// init capture thread
	mCaptureThread = new DoCaptureThread(this);
	pthread_mutex_init(&mCaptureMutex, NULL);
	pthread_cond_init(&mCaptureCond, NULL);
	mCaptureThreadState = CAPTURE_STATE_PAUSED;
	mCaptureThread->startThread();

	// init preview thread
	mPreviewThread = new DoPreviewThread(this);
	pthread_mutex_init(&mPreviewMutex, NULL);
	pthread_cond_init(&mPreviewCond, NULL);
	mPreviewThread->startThread();

	// init picture thread
	mPictureThread = new DoPictureThread(this);
	pthread_mutex_init(&mPictureMutex, NULL);
	pthread_cond_init(&mPictureCond, NULL);
	mPictureThread->startThread();
	
	// init continuous picture thread
	mContinuousPictureThread = new DoContinuousPictureThread(this);
	pthread_mutex_init(&mContinuousPictureMutex, NULL);
	pthread_cond_init(&mContinuousPictureCond, NULL);
	mContinuousPictureThread->startThread();

}

bool V4L2CameraDevice::previewThread()
{
	V4L2BUF_t * pbuf = (V4L2BUF_t *)OSAL_Dequeue(&mQueueBufferPreview);
	if (pbuf == NULL)
	{
		// LOGV("picture queue no buffer, sleep...");
		pthread_mutex_lock(&mPreviewMutex);
		pthread_cond_wait(&mPreviewCond, &mPreviewMutex);
		pthread_mutex_unlock(&mPreviewMutex);
		return true;
	}

	Mutex::Autolock locker(&mObjectLock);
	if (mMapMem.mem[pbuf->index] == NULL
		|| pbuf->addrPhyY == 0)
	{
		LOGV("preview buffer have been released...");
		return true;
	}

	// callback
	mCallbackNotifier->onNextFrameAvailable((void*)pbuf, mUseHwEncoder);

	// preview
	mPreviewWindow->onNextFrameAvailable((void*)pbuf);

	// LOGD("preview id : %d", pbuf->index);

	releasePreviewFrame(pbuf->index);

	return true;
}

// singal picture
bool V4L2CameraDevice::pictureThread()
{
	V4L2BUF_t * pbuf = (V4L2BUF_t *)OSAL_Dequeue(&mQueueBufferPicture);
	if (pbuf == NULL)
	{
		LOGV("picture queue no buffer, sleep...");
		pthread_mutex_lock(&mPictureMutex);
		pthread_cond_wait(&mPictureCond, &mPictureMutex);
		pthread_mutex_unlock(&mPictureMutex);
		return true;
	}

	DBG_TIME_BEGIN("taking picture", 0);

	// notify picture cb
	mCameraHardware->notifyPictureMsg((void*)pbuf);

	DBG_TIME_DIFF("notifyPictureMsg");

	mCallbackNotifier->takePicture((void*)pbuf);
	
	char str[128];
	sprintf(str, "hw picture size: %dx%d", pbuf->width, pbuf->height);
	DBG_TIME_DIFF(str);
	
	if (!mIsPicCopy)
	{
		releasePreviewFrame(pbuf->index);
	}

	DBG_TIME_END("Take picture", 0);

	return true;
}

HAL-RK3288-7.1

RK3399-camera

hardware/rockchip/camera/CameraHal/CameraHal_Module.cpp

hardware/rockchip/camera/Config/cam_board_rk3288.xml 文件用于配置dvp mipi接口的sensor


#define CAMERAS_SUPPORT_MAX             8

rk_cam_info_t gCamInfos[CAMERAS_SUPPORT_MAX];

camera_module_t HAL_MODULE_INFO_SYM = {
    common: {
         tag: HARDWARE_MODULE_TAG,
         version_major: ((CONFIG_CAMERAHAL_VERSION&0xffff00)>>16),
         version_minor: CONFIG_CAMERAHAL_VERSION&0xff,
         id: CAMERA_HARDWARE_MODULE_ID,
         name: CAMERA_MODULE_NAME,
         author: "RockChip",
         methods: &camera_module_methods,
         dso: NULL, /* remove compilation warnings */
         reserved: {0}, /* remove compilation warnings */
    },
    get_number_of_cameras: camera_get_number_of_cameras,
    get_camera_info: camera_get_camera_info,
    set_callbacks:NULL,
    get_vendor_tag_ops:NULL,
#if (defined(ANDROID_5_X) || defined(ANDROID_6_X) || defined(ANDROID_7_X))
    open_legacy:NULL,
#endif
#if (defined(ANDROID_6_X) || defined(ANDROID_7_X))
    set_torch_mode:NULL,
    init:NULL,
#endif
    reserved: {0}
};

int camera_device_open(const hw_module_t* module, const char* name,
                hw_device_t** device)
{

        camera = new android::CameraHal(cameraid);

}


int camera_get_number_of_cameras(void)
{

    profiles = camera_board_profiles::getInstance();
    nCamDev = profiles->mDevieVector.size();
    LOGE("board profiles cam num %d\n", nCamDev);

    if(cam_cnt<CAMERAS_SUPPORT_MAX){
        for (i=0; i<10; i++) {
            cam_path[0] = 0x00;
			unsigned int pix_format_tmp = V4L2_PIX_FMT_NV12;
            strcat(cam_path, CAMERA_DEVICE_NAME);
            sprintf(cam_num, "%d", i);
            strcat(cam_path,cam_num);
            fd = open(cam_path, O_RDONLY);
            if (fd < 0) {
                LOGE("Open %s failed! strr: %s",cam_path,strerror(errno));
                continue;
            } 
            LOGD("Open %s success!",cam_path);
            memset(&capability, 0, sizeof(struct v4l2_capability));

        }
    }

}

int camera_set_preview_window(struct camera_device * device,
        struct preview_stream_ops *window)
{
    int rv = -EINVAL;
    rk_camera_device_t* rk_dev = NULL;

    LOGV("%s", __FUNCTION__);

    if(!device)
        return rv;

    rk_dev = (rk_camera_device_t*) device;

    rv = gCameraHals[rk_dev->cameraid]->setPreviewWindow(window);

    return rv;
}

hardware/rockchip/camera/CameraHal/CameraHal.cpp


extern rk_cam_info_t gCamInfos[CAMERAS_SUPPORT_MAX];

CameraHal::CameraHal(int cameraId)
          :commandThreadCommandQ("commandCmdQ")
{

	    if((strcmp(gCamInfos[cameraId].driver,"uvcvideo") == 0)) {
	        LOGD("it is a uvc camera!");
	        mCameraAdapter = new CameraUSBAdapter(cameraId);
	    }

}

hardware/rockchip/camera/CameraHal/CameraUSBAdapter.cpp


void CameraUSBAdapter::initDefaultParameters(int camFd)
{

    /*preview format setting*/
    params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, "yuv420sp,yuv420p");
    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,CameraParameters::PIXEL_FORMAT_YUV420SP);
    params.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
    params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,CameraParameters::PIXEL_FORMAT_YUV420SP);

    /*picture format setting*/
    params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, CameraParameters::PIXEL_FORMAT_JPEG);
    params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
}