[Camera模块]day_01 openCamera


【又是完美的一天,用了好久的Camera2,才发现对于openCamera模块的流程不太熟悉,所以来记录一下最近的学习笔记。参考谷歌官网以及 简书大佬JeffMony的博客

Camera操作过程最重要的四个步骤:

  • CameraManager———> openCamera 打开相机
  • CameraDeviceImpl——> createCaptureSession 创建捕获会话
  • CameraCaptureSession——> setRepeatingRequest 设置预览界面
  • CameraDeviceImpl——> capture 开始捕获图片

下面来详细分析一下这个过程中重要的类以及方法。

1. Cameramanager

1.1 概念

官网定义:
  A system service manager for detecting, characterizing, and connecting to CameraDevice.一个用于检测、获取相机设备特征和连接相机设备的系统服务管理器。

使用:
获取方式:通过Context类的 getSystemService() 方法获取,传入参数 Context.CAMEARA_SERVICE 或者 CameraManager.class即可。
示例:

activity.getSystemService(Context.CAMERA_SERVICE);

1.2 内部类

Cameramanager 包含两个公有的内部类,Cameramanager.AvailabilityCallback、Cameramanager.TorchCallback。

1.2.1 Cameramanager.Availability~~Callback

        相机设备可用状态的回调。当相机设备可用状态改变时,回调这个类的onCameraAvailable(String cameraId)和onCameraUnavailable(String cameraId)方法。
  那怎样区分相机设备是否可用呢?当设备不再处于使用状态或一个新的可移动的相机~~ 设备被连接时,我们认为它处于可用状态。当有应用或者服务开始使用相机或者可移动相机断开连接,此时认为设备不可用。

1.2.2 Cameramanager.TorchCallback

        相机设备闪光灯的Torch模式可用状态的回调。

1.3 常用方法

1.3.1 CameraCharacteristics getCameraCharacteristics(String cameraId)

获取对应相机设备的特征。返回值为CameraCharacteristics,类似于Camera1中的Camera.Parameter类,里面封装了相机设备固有的所有属性功能。

1.3.2 String[] getCameraIdList()

        获取当前连接的相机设备id列表,包括其他camera API客户机可能在使用的摄像头。
  不可移动相机使用从0开始的整数作为其标识符,而可移动相机对每个单独的设备都有唯一的标识符,即使它们是相同的型号。此列表不包含只能作为逻辑多摄像头设备的一部分使用的物理摄像头。

1.3.3 openCamera

Cameramanager中有两个openCamera(…)。

public void openCamera(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)

public void openCamera(@NonNull String cameraId,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull final CameraDevice.StateCallback callback)

handler 是传入的一个执行耗时操作的handler
executor 操作线程池。

2. openCamera

openCamera的调用流程
在这里插入图片描述
openCamera(…)——>openCameraForUid(…)——>openCameraDeviceUserAsync(…)——>……

openCameraDeviceUserAsync函数

private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid)
            throws CameraAccessException {
      /***
      **function body.
      **/
        return device;
    }

返回值类型CameraDevice,是抽象类,CameraDeviceImpl是其实现类。我们需要获取的就是CameraDeviceImpl的实例对象。这个函数主要作用就是到底层获取相机设备的信息,并获取当前指定cameraId的设备实例。本函数的主要工作可以分为五个步骤:

  • 获取当前cameraId指定相机的设备信息
  • 利用获取的设备信息创建CameraDeviceImpl实例
  • 调用远程CameraService获取当前相机的远程服务
  • 将获取的远程服务设置到CameraDeviceImpl实例中
  • 返回CameraDeviceImpl实例

2.1 获取当前cameraId指定相机的设备信息

CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);

CameraCharacteristics提供了CameraDevice的各种属性,可以通过getCameraCharacteristics函数查询。

    public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
            throws CameraAccessException {
        CameraCharacteristics characteristics = null;
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No cameras available on device");
        }
        synchronized (mLock) {
            ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
            if (cameraService == null) {
                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                        "Camera service is currently unavailable");
            }
            try {
                if (!supportsCamera2ApiLocked(cameraId)) {
                    int id = Integer.parseInt(cameraId);
                    String parameters = cameraService.getLegacyParameters(id);
                    CameraInfo info = cameraService.getCameraInfo(id);
                    characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info);
                } else {
                    CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
                    characteristics = new CameraCharacteristics(info);
                }
            } catch (ServiceSpecificException e) {
                throwAsPublicException(e);
            } catch (RemoteException e) {
                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                        "Camera service is currently unavailable", e);
            }
        }
        return characteristics;
    }

上述函数中有个函数——>supportsCamera2APILocked(cameraId),这个函数是判断当前camera服务是否支持camera2 api,支持返回true,不支持返回false。该方法调用了supportsCameraApiLocked(String cameraId, int apiVersion)。

private boolean supportsCamera2ApiLocked(String cameraId) {
        return supportsCameraApiLocked(cameraId, API_VERSION_2);
}

private boolean supportsCameraApiLocked(String cameraId, int apiVersion) {
        /*
         * Possible return values:
         * - NO_ERROR => CameraX API is supported
         * - CAMERA_DEPRECATED_HAL => CameraX API is *not* supported (thrown as an exception)
         * - Remote exception => If the camera service died
         *
         * Anything else is an unexpected error we don't want to recover from.
         */
        try {
            ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
            // If no camera service, no support
            if (cameraService == null) return false;

            return cameraService.supportsCameraApi(cameraId, apiVersion);
        } catch (RemoteException e) {
            // Camera service is now down, no support for any API level
        }
        return false;
    }

调用的CameraService对应的是偶ICameraService,aidl,对应的实现类在frameworks/av/services/camera/libcameraservice/CameraService.h。代码如下:

Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
        /*out*/ bool *isSupported) {
    ATRACE_CALL();

    const String8 id = String8(cameraId);

    ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());

    switch (apiVersion) {
        case API_VERSION_1:
        case API_VERSION_2:
            break;
        default:
            String8 msg = String8::format("Unknown API version %d", apiVersion);
            ALOGE("%s: %s", __FUNCTION__, msg.string());
            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
    }

    int deviceVersion = getDeviceVersion(id);
    switch(deviceVersion) {
        case CAMERA_DEVICE_API_VERSION_1_0:
        case CAMERA_DEVICE_API_VERSION_3_0:
        case CAMERA_DEVICE_API_VERSION_3_1:
            if (apiVersion == API_VERSION_2) {
                ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
                        __FUNCTION__, id.string(), deviceVersion);
                *isSupported = false;
            } else { // if (apiVersion == API_VERSION_1) {
                ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
                        __FUNCTION__, id.string());
                *isSupported = true;
            }
            break;
        case CAMERA_DEVICE_API_VERSION_3_2:
        case CAMERA_DEVICE_API_VERSION_3_3:
        case CAMERA_DEVICE_API_VERSION_3_4:
            ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
                    __FUNCTION__, id.string());
            *isSupported = true;
            break;
        case -1: {
            String8 msg = String8::format("Unknown camera ID %s", id.string());
            ALOGE("%s: %s", __FUNCTION__, msg.string());
            return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
        }
        default: {
            String8 msg = String8::format("Unknown device version %x for device %s",
                    deviceVersion, id.string());
            ALOGE("%s: %s", __FUNCTION__, msg.string());
            return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
        }
    }

    return Status::ok();
}

注意:

这里的API_VERSION_2不是api level 2,而是camera1还是camera2.

采用camera2 api来获取相机设备的信息。

CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
                    try {
                        info.setCameraId(Integer.parseInt(cameraId));
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Failed to parse camera Id " + cameraId + " to integer");
                    }
                    info.setDisplaySize(displaySize);

                    characteristics = new CameraCharacteristics(info);

camera整体调用流程:
在这里插入图片描述

2.2 利用获取相机的设备信息创建CameraDeviceImpl实例

android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                    new android.hardware.camera2.impl.CameraDeviceImpl(
                        cameraId,
                        callback,
                        executor,
                        characteristics,
                        mContext.getApplicationInfo().targetSdkVersion);

创建完CameraDeviceImpl实例,传入刚才获取的characteristics。

2.3 调用远程CameraService获取当前相机的远程服务

// Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
if (cameraService == null) {
		throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED,
		  "Camera service is currently unavailable");
}
cameraUser = cameraService.connectDevice(callbacks, cameraId, mContext.getOpPackageName(), uid);

这个方法主要目的是连接当前的cameraDevice设备。调用到CameraService::connectDevice中。

2.4 将获取的远程服务设置到CameraDeviceImpl实例中

deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;

此处cameraUser就是cameraService端设置的connectDevice方法返回的对象(ICameraDeviceUser.Stub对象)。

    public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
        synchronized(mInterfaceLock) {
            // TODO: Move from decorator to direct binder-mediated exceptions
            // If setRemoteFailure already called, do nothing
            if (mInError) return;

            mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);

            IBinder remoteDeviceBinder = remoteDevice.asBinder();
            // For legacy camera device, remoteDevice is in the same process, and
            // asBinder returns NULL.
            if (remoteDeviceBinder != null) {
                try {
                    remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
                } catch (RemoteException e) {
                    CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);

                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "The camera device has encountered a serious error");
                }
            }

            mDeviceExecutor.execute(mCallOnOpened);
            mDeviceExecutor.execute(mCallOnUnconfigured);
        }
    }

这个mRemoteDevice是应用程序进程和android camera service 端之间链接的桥梁,上层操作camera的方法会通过调用mRemoteDevice来调用到camera service端来实现操作底层camera驱动的目的。

3. Camera状态的回调

3.1 openCameraDeviceUserAsync中的StateCallback

openCamera调用到openCameraDeviceUserAsync(…),同时也把它的StateCallback参数传入。这个参数和获取到的CameraCharacteristics一起传入CameraDeviceImpl的构造函数中。但传入CameraService的回调参数不是这个回调,而是CameraDeviceImpl实例中的参数,使用deviceImpl.getCallbacks()获得。在CameraDeviceImpl的构造函数中传入StateCallback,然后赋值给CameraDeviceCallbacks类型的mDeviceCallback。而CameraDeviceCallbacks继承自ICameraDeviceCallbacks.Stub。ICameraDeviceCallbacks.Stub是可以在Binder IPC中传输的对象,这个才是应用程序与CameraService通信的回调,在这个回调中的执行方法标识当前的camera的执行状态。

3.2 CameraDeviceCallback回调

ICameraDeviceCallbacks.aidl自动生成的android/handware/camera2/ICameraDeviceCallbacks.h文件。
这个回调函数是从CameraService中调上来的。下面的回调包含了Camera执行过程中的各种状态:

  • onDeviceError
  • onDeviceIdle
  • onCaptureStarted
  • onResultReceived
  • onPrepared
  • onRepeatingRequestError
  • onRequestQueueEmpty

3.3 StateCallback回调

StateCallback是openCamera传入的3个参数中的一个,这是一个标识当前camera连接状态的回调。

    public static abstract class StateCallback {
        public static final int ERROR_CAMERA_IN_USE = 1;
        public static final int ERROR_MAX_CAMERAS_IN_USE = 2;
        public static final int ERROR_CAMERA_DISABLED = 3;
        public static final int ERROR_CAMERA_DEVICE = 4;
        public static final int ERROR_CAMERA_SERVICE = 5;

        /** @hide */
        @Retention(RetentionPolicy.SOURCE)
        @IntDef(prefix = {"ERROR_"}, value =
            {ERROR_CAMERA_IN_USE,
             ERROR_MAX_CAMERAS_IN_USE,
             ERROR_CAMERA_DISABLED,
             ERROR_CAMERA_DEVICE,
             ERROR_CAMERA_SERVICE })
        public @interface ErrorCode {};
        public abstract void onOpened(@NonNull CameraDevice camera); // Must implement
        public void onClosed(@NonNull CameraDevice camera) {
            // Default empty implementation
        }
        public abstract void onDisconnected(@NonNull CameraDevice camera); // Must implement
        public abstract void onError(@NonNull CameraDevice camera,
                @ErrorCode int error); // Must implement
    }
  • onOpened回调
    当前cameraDevice已经被打开时会触发这个回调。指明camera的状态是opened了,这时可以开始createCaptureSession、开始使用camera捕捉图片或者视频。

触发onOPened回调的地方在setRemoteDevice(…),这个函数在connectDevice(…)成功之后执行,表名当前的cameraDevice已经连接成功了,出发camera能够打开的回调。

  • onClosed回调:
    camera device已经被关闭,这个回调被触发。一般是终端开发者closeCamera的时候会释放当前持有的camera device。

  • onDisconnected回调:
    camera device不可再用,打开camera device失败了,一般是因为权限或者安全策略问题导致camera device打不开。一旦连接camera device出现ERROR_CAMERA_DISCONNECTED问题,这时函数就会被回调,表示当前camera device处于断开的状态。

  • onError回调:
    调用camera device的时候出现了严重的问题。执行CameraService–>connectDevice 出现异常了。

deviceImpl.setRemoteFailure(e);是执行onError回调的函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
全志R16的parrotv1.1的系统调通摄像头hm1375 2017/8/24 14:04 版本:V1.1 开发板:SC3817R OS:parrotv1.1(Android4.4.2) 1、 R:\wyb\hm1375_parrotv1.1\android\device\softwinner\astar-evb30\configs\camera.cfg ;------------------------------------------------------------------------------- ; 用于camera的配置 ; ; 采用格式: ; key = key_value ; 注意: 每个key需要顶格写; ; key_value紧跟着key后面的等号后面, 位于同一行中; ; key_value限制大小为256字节以内; ; ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; exif information of "make" and "model" ;------------------------------------------------------------------------------- key_camera_exif_make = MAKE_A31S key_camera_exif_model = MODEL_A31ST ;------------------------------------------------------------------------------- ; 1 for single camera, 2 for double camera ;------------------------------------------------------------------------------- number_of_camera = 1 ;------------------------------------------------------------------------------- ; CAMERA_FACING_BACK ; gc0307 hm1375 ;------------------------------------------------------------------------------- camera_id = 0 ;------------------------------------------------------------------------------- ; 1 for CAMERA_FACING_FRONT ; 0 for CAMERA_FACING_BACK ;------------------------------------------------------------------------------- camera_facing = 0 ;------------------------------------------------------------------------------- ; 1 for camera without isp(using built-in isp of Axx) ; 0 for camera with isp ;------------------------------------------------------------------------------- use_builtin_isp = 0 ;------------------------------------------------------------------------------- ; camera orientation (0, 90, 180, 270) ;------------------------------------------------------------------------------- camera_orientation = 90 ;------------------------------------------------------------------------------- ; driver device name ;------------------------------------------------------------------------------- camera_device = /dev/video0 ;------------------------------------------------------------------------------- ; device id ; for two camera devices with one CSI ;------------------------------------------------------------------------------- device_id = 0 used_preview_size = 1 key_support_preview_size = 1280x1024, 1280x960, 1280x720, 640x480 key_default_preview_size = 640x480 used_picture_size = 1 key_support_picture_size = 1280x1024, 1280x960, 1280x720, 640x480 key_default_picture_size = 640x480 used_flash_mode = 0 key_support_flash_mode = on,off,auto key_default_flash_mode = on used_color_effect=0 key_support_color_effect = none,mono,negative,sepia,aqua key_default_color_effect = none used_frame_rate = 1 key_support_frame_rate = 10 key_default_frame_rate = 10 used_focus_mode = 0 key_support_focus_mode = auto,infinity,macro,fixed,continuous-video,continuous-picture key_default_focus_mode = auto used_scene_mode = 0 key_support_scene_mode = auto,portrait,landscape,night,night-portrait,theatre,beach,snow,sunset,steadyphoto,fireworks,sports,party,candlelight,barcode key_default_scene_mode = auto used_white_balance = 0 key_support_white_balance = auto,incandescent,fluorescent,warm-fluorescent,daylight,cloudy-daylight key_default_white_balance = auto used_exposure_compensation = 1 key_max_exposure_compensation = 3 key_min_exposure_compensation = -3 key_step_exposure_compensation = 1 key_default_exposure_compensation = 0 2、录像的时候需要干掉对1080p分辨率的支持(HM1375最大支持720p): R:\wyb\hm1375_parrotv1.1\android\device\softwinner\astar-evb30\configs\media_profiles.xml <!DOCTYPE MediaSettings [ ]> 3、 R:\wyb\hm1375_parrotv1.1\android\device\softwinner\astar-evb30\init.sun8i.rc #csi module insmod /system/vendor/modules/videobuf-core.ko insmod /system/vendor/modules/videobuf-dma-contig.ko insmod /system/vendor/modules/cam_detect.ko #insmod /system/vendor/modules/actuator.ko #insmod /system/vendor/modules/ad5820_act.ko insmod /system/vendor/modules/cci.ko insmod /system/vendor/modules/vfe_os.ko insmod /system/vendor/modules/vfe_subdev.ko #insmod /system/vendor/modules/gc0307.ko #insmod /system/vendor/modules/ov2035.ko #insmod /system/vendor/modules/ov2640.ko #insmod /system/vendor/modules/ov5640.ko insmod /system/vendor/modules/hm1375.ko insmod /system/vendor/modules/vfe_v4l2.ko 4、可选修改: R:\wyb\hm1375_parrotv1.1\android\device\softwinner\astar-evb30\ueventd.sun8i.rc /dev/video0 0666 media media #/dev/video1 0666 media media 5、可选修改: R:\wyb\hm1375_parrotv1.1\android\frameworks\base\packages\SettingsProvider\res\values\defaults.xml 60000 false 修改为: 1800000 true 6、 R:\wyb\hm1375_parrotv1.1\android\frameworks\base\services\java\com\android\server\BatteryService.java public final class BatteryService extends Binder { private static final String TAG = BatteryService.class.getSimpleName(); // private static final boolean DEBUG = false; private static final boolean DEBUG = true; private static final int BATTERY_SCALE = 100; // battery capacity is a percentage // Used locally for determining when to make a last ditch effort to log // discharge stats before the device dies. private int mCriticalBatteryLevel; …… private void sendIntentLocked() { // Pack up the values and broadcast them to everyone final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING); int icon = getIconLocked(mBatteryProps.batteryLevel); intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryProps.batteryStatus); intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryProps.batteryHealth); intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryProps.batteryPresent); //intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryProps.batteryLevel); intent.putExtra(BatteryManager.EXTRA_LEVEL, 100); intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE); intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon); intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType); //intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryProps.batteryVoltage); intent.putExtra(BatteryManager.EXTRA_VOLTAGE, 4200); intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryProps.batteryTemperature); intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryProps.batteryTechnology); intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger); if (DEBUG) { Slog.d(TAG, "2016/12/05 10:41 wenyuanbo **** Sending ACTION_BATTERY_CHANGED. level:" + mBatteryProps.batteryLevel + ", scale:" + BATTERY_SCALE + ", status:" + mBatteryProps.batteryStatus + ", health:" + mBatteryProps.batteryHealth + ", present:" + mBatteryProps.batteryPresent + ", voltage: " + mBatteryProps.batteryVoltage + ", temperature: " + mBatteryProps.batteryTemperature + ", technology: " + mBatteryProps.batteryTechnology + ", AC powered:" + mBatteryProps.chargerAcOnline + ", USB powered:" + mBatteryProps.chargerUsbOnline + ", Wireless powered:" + mBatteryProps.chargerWirelessOnline + ", icon:" + icon + ", invalid charger:" + mInvalidCharger); } mHandler.post(new Runnable() { @Override public void run() { ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); } }); } …… } 7、低电量的时候摄像头会被关闭: R:\wyb\hm1375_parrotv1.1\android\packages\apps\Camera2\src\com\android\camera\CameraActivity.java import static com.android.camera.CameraManager.CameraOpenErrorCallback; public class CameraActivity extends Activity implements ModuleSwitcher.ModuleSwitchListener, ActionBar.OnMenuVisibilityListener, ShareActionProvider.OnShareTargetSelectedListener { private static final String TAG = "CAM_Activity"; private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = "android.media.action.STILL_IMAGE_CAMERA_SECURE"; public static final String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE"; public static final String ACTION_TRIM_VIDEO = "com.android.camera.action.TRIM"; public static final String MEDIA_ITEM_PATH = "media-item-path"; …… private Intent mVideoShareIntent; private Intent mImageShareIntent; private AlertDialog mLocationDialog; private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { int Level = intent.getIntExtra("level", 0); int Scale = intent.getIntExtra("scale", 100); Log.w(TAG, "2016/11/29 19:54 &&&& wenyuanbo battery Level" + Level); /* *Logic: *1.the battery level is lower then 5%. *2.if in camera, make sure that not in the snapshot progress. *3.if in videocamera, make sure that not in the videorecording progress. *4.everytime starting the camera activity, the battery level is broadcasted, * if meeting the conditions above, give a dialog, press it and finish the activity. *5.if the conditions are not satisfied when started, play for a moment, in the camera acitvity * or video camera activity, the conditiosn are satisfied, also give a dialog for finishing the activity. * *by fuqiang. */ if(Level < 5) { Runnable runnable_close_camera = new Runnable() { @Override public void run() { //close the camera. // CameraActivity.this.finish(); } }; Log.w(TAG, "2016/11/29 18:20 **** wenyuanbo battery Level" + Level); showLocationDialog(); } /* *Logic: *1.the battery level is lhigher then 5% and lower than 15%. *2.if in camera, make sure that not in the snapshot progress. *3.if in videocamera, make sure that not in the videorecording progress. *4.whether in camera or in videocamera, make sure that the flash mode is supported. *5.everytime starting the camera activity, the battery level is broadcasted, * if meeting the conditions above, forbidden the flash(gray icon), give a dialog to notise user. *6.if the conditions are not satisfied when started, play for a moment, in the camera acitvity * or video camera activity, the conditiosn are satisfied, forbidden the flash and give a notice dialog. *7.the dialog is only given once for each camera activity starting. * *by fuqiang. */ else if(Level < 16) { //close the flash mode. /* if (mIsLowBatteryDialogShown == false) { mRotateDialog.showAlertDialog( getString(R.string.warning), getString(R.string.low_battery_15), null, null, getString(R.string.close), null); mIsLowBatteryDialogShown = true; } */ } } } }; …… } 8、HM1375的驱动程序请直接联系HiMax原厂或者代理商: R:\wyb\hm1375_parrotv1.1\lichee\linux-3.4\drivers\media\video\sunxi-vfe\device\hm1375.c R:\wyb\hm1375_parrotv1.1\lichee\linux-3.4\drivers\media\video\sunxi-vfe\device\Makefile obj-m += ov5640.o obj-m += hm1375.o obj-m += hm5065.o obj-m += ov2640.o obj-m += ov7736.o #obj-m += s5k4ec.o #obj-m += s5k4ec_mipi.o #obj-m += gc2035.o #obj-m += gt2005.o #obj-m += gc0307.o obj-m += gc0308.o #obj-m += gc0309.o #obj-m += gc0328.o #obj-m += gc0329.o #obj-m += gc0311.o #obj-m += hi253.o #obj-m += sp2518.o #obj-m += sp2519.o #obj-m += sp0718.o #obj-m += sp0838.o #obj-m += ov16825.o #obj-m += ov5650.o #obj-m += ov5647.o #obj-m += ov5647_mipi.o #obj-m += t8et5.o #obj-m += s5k4e1.o #obj-m += s5k4e1_mipi.o #obj-m += sp2518.o #obj-m += sp0718.o #obj-m += gc5004.o #obj-m += gc5004_mipi.o #obj-m += ov5648.o #obj-m += ar0330.o #obj-m += ov5648.o #obj-m += sp5408.o #obj-m += ov12830.o #obj-m += ov8825.o #obj-m += ov8850.o #obj-m += gc2155.o #obj-m += ov8858.o #obj-m += ov13850.o #obj-m += ov8858_4lane.o 9、hm1375项请参照ov2640填写: R:\wyb\hm1375_parrotv1.1\lichee\linux-3.4\drivers\media\video\sunxi-vfe\sensor_info.c struct sensor_item sensor_list_t[] = { // name i2c_addr sensor type sensor size sensor max pclk //{ "gc2145" , 0x78, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "hm1375" , 0x48, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "hm5065" , 0x3e, SENSOR_YUV , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov2640" , 0x60, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "ov5640" , 0x78, SENSOR_YUV , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov5647" , 0x6c, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov5647_mipi" , 0x6c, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov5650" , 0x50, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov5648" , 0x6c, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ov8825" , 0x6c, SENSOR_RAW , PIXEL_NUM_8M , CORE_CLK_RATE_FOR_8M}, { "ov8850" , 0x20, SENSOR_RAW , PIXEL_NUM_8M , CORE_CLK_RATE_FOR_8M}, { "ov12830" , 0x6c, SENSOR_RAW , PIXEL_NUM_12M , CORE_CLK_RATE_FOR_16M}, { "ov16825" , 0x6c, SENSOR_RAW , PIXEL_NUM_16M , CORE_CLK_RATE_FOR_16M}, { "gc0329" , 0x62, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc0309" , 0x42, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc0307" , 0x42, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc0308" , 0x42, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc2035" , 0x78, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "gt2005" , 0x78, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "gc2015" , 0x60, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "gc2235" , 0x78, SENSOR_RAW , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "sp0838" , 0x30, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "sp0718" , 0x6c, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "sp2518" , 0x6c, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "hi253" , 0x40, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "hi257" , 0x40, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "s5k4ec" , 0x5a, SENSOR_YUV , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "s5k4ec_mipi" , 0x5a, SENSOR_YUV , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "s5k4e1" , 0x20, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "s5k4e1_mipi" , 0x20, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "t4k05" , 0x6c, SENSOR_RAW , PIXEL_NUM_8M , CORE_CLK_RATE_FOR_8M}, { "t8et5" , 0x78, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "ar0330" , 0x20, SENSOR_RAW , PIXEL_NUM_3M , CORE_CLK_RATE_FOR_3M}, { "bf3a03" , 0xDC, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc0311" , 0x66, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc0311" , 0x66, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, { "gc5004" , 0x6c, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "gc5004_mipi" , 0x6c, SENSOR_RAW , PIXEL_NUM_5M , CORE_CLK_RATE_FOR_5M}, { "nt99252" , 0x6c, SENSOR_YUV , PIXEL_NUM_2M , CORE_CLK_RATE_FOR_2M}, { "ov7736" , 0x42, SENSOR_YUV , PIXEL_NUM_0_3M , CORE_CLK_RATE_FOR_2M}, }; 10、 R:\wyb\hm1375_parrotv1.1\lichee\tools\pack\chips\sun8iw5p1\configs\default\env.cfg bootdelay=3 #default bootcmd, will change at runtime according to key press bootcmd=run setargs_nand boot_normal#default nand boot #kernel command arguments console=ttyS0,115200 nand_root=/dev/nandd mmc_root=/dev/mmcblk0p7 init=/init loglevel=8 #set kernel cmdline if boot.img or recovery.img has no cmdline we will use this setargs_nand=setenv bootargs console=${console} root=${nand_root} init=${init} ion_cma_512m=120m ion_cma_1g=176m ion_carveout_512m=96m ion_carveout_1g=150m coherent_pool=4m loglevel=${loglevel} partitions=${partitions} setargs_mmc=setenv bootargs console=${console} root=${mmc_root} init=${init} ion_cma_512m=120m ion_cma_1g=176m ion_carveout_512m=96m ion_carveout_1g=150m coherent_pool=4m loglevel=${loglevel} partitions=${partitions} #nand command syntax: sunxi_flash read address partition_name read_bytes #0x40007800 = 0x40008000(kernel entry) - 0x800(boot.img header 2k) boot_normal=sunxi_flash read 40007800 boot;boota 40007800 boot_recovery=sunxi_flash read 40007800 recovery;boota 40007800 boot_fastboot=fastboot #recovery key recovery_key_value_max=0x13 recovery_key_value_min=0x10 #fastboot key fastboot_key_value_max=0x8 fastboot_key_value_min=0x2 11、 R:\wyb\hm1375_parrotv1.1\lichee\tools\pack\chips\sun8iw5p1\configs\evb-30\sys_config.fex ;---------------------------------------------------------------------------------- ;dcdc1_vol ---set dcdc1 voltage,mV,1600-3400,100mV/step ;dcdc2_vol ---set dcdc2 voltage,mV,600-1540,20mV/step ;dcdc3_vol ---set dcdc3 voltage,mV,600-1860,20mV/step ;dcdc4_vol ---set dcdc4 voltage,mV,600-1540,20mV/step ;dcdc5_vol ---set dcdc5 voltage,mV,1000-2550,50mV/step ;aldo2_vol ---set aldo2 voltage,mV,700-3300,100mV/step ;aldo3_vol ---set aldo3 voltage,mV,700-3300,100mV/step ;---------------------------------------------------------------------------------- [power_sply] dcdc1_vol = 3000 dcdc2_vol = 1100 dcdc3_vol = 1200 dcdc4_vol = 0 dcdc5_vol = 1500 aldo2_vol = 2500 aldo3_vol = 3000 dldo3_vol = 2800 ;gpio0_vol = 2800 ldoio0_vol = 2800 ;-------------------------------------------------------------------------------- ;vip (video input port) configuration ;vip_used: 0:disable 1:enable ;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer ;vip_dev_qty: The quantity of devices linked to capture bus ; ;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and ; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! ; ;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1,vip_dev(x)_pos must be configured! ; ;vip_dev(x)_isp_used 0:not use isp 1:use isp ;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb ;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby ;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable ;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable ;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply ;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply ;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply ;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply ;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply ;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply ;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply ;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply ;x indicates the index of the devices which are linked to the same capture bus ;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 ;fill handle string as below: ;axp22_eldo3 ;axp22_dldo4 ;axp22_eldo2 ;fill handle string "" when not using any pmu power supply ;-------------------------------------------------------------------------------- [csi0] vip_used = 1 vip_mode = 0 vip_dev_qty = 1 vip_define_sensor_list = 0 vip_csi_pck = port:PE00 vip_csi_mck = port:PE01 vip_csi_hsync = port:PE02 vip_csi_vsync = port:PE03 vip_csi_d0 = port:PE04 vip_csi_d1 = port:PE05 vip_csi_d2 = port:PE06 vip_csi_d3 = port:PE07 vip_csi_d4 = port:PE08 vip_csi_d5 = port:PE09 vip_csi_d6 = port:PE10 vip_csi_d7 = port:PE11 vip_csi_sck = port:PE12 vip_csi_sda = port:PE13 ;vip_dev0_mname = "ov5640" vip_dev0_mname = "hm1375" ;vip_dev0_mname = "hm5065" vip_dev0_pos = "rear" vip_dev0_lane = 1 vip_dev0_twi_id = 2 ;vip_dev0_twi_addr = 0x78 vip_dev0_twi_addr = 0x48 ;vip_dev0_twi_addr = 0x3e vip_dev0_isp_used = 0 vip_dev0_fmt = 0 (在调试的时候请置0:) vip_dev0_stby_mode = 0 vip_dev0_vflip = 0 vip_dev0_hflip = 0 ;vip_dev0_iovdd = "axp22_dldo3" vip_dev0_iovdd = "" vip_dev0_iovdd_vol = 2800000 vip_dev0_avdd = "axp22_ldoio0" vip_dev0_avdd_vol = 2800000 vip_dev0_dvdd = "" vip_dev0_dvdd_vol = 1800000 vip_dev0_afvdd = "" vip_dev0_afvdd_vol = 2800000 vip_dev0_power_en = vip_dev0_reset = port:PE14 vip_dev0_pwdn = port:PE15 vip_dev0_flash_en = vip_dev0_flash_mode = vip_dev0_af_pwdn = power_start = 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值