Camera应用部分:

Packages/apps/camera/src/com/android/camera/camera.java

Camera本地框架:

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

Camera服务部分:

frameworks/base/services/camera/libcameraservice,这部分需要camera的硬件抽象层来实现上述的本地框架,会被编译成库Libcameraservice.so

Camera硬件接口层

frameworks/base/include/camera/CameraHardwareInterface.h

Camera HAL部分:

Devices/Samsung/proprietary/libcamera/
 

篇幅主要以take picture为例


点击(此处)折叠或打开

  1. 首先从上层讲解下来
  2. Packages/apps/camera/src/com/android/camera/camera.java
  3. private void capture() {
  4.             mCaptureOnlyData = null;
  5.             // See android.hardware.Camera.Parameters.setRotation for
  6.             mParameters.setRotation(rotation);
  7.           …….
  8.            mCameraDevice.setParameters(mParameters);
  9.                 //app 应用注册takepicture回调函数
  10.             mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback,
  11.                     mPostViewPictureCallback, new JpegPictureCallback(loc));
  12.             mPreviewing = false;
  13.         }
  14. 下面是关于四个回调函数的实现
  15. private final class ShutterCallback
  16.             implements android.hardware.Camera.ShutterCallback {
  17.         public void onShutter() {
  18.             mShutterCallbackTime = System.currentTimeMillis();
  19.             mShutterLag = mShutterCallbackTime - mCaptureStartTime;
  20.             Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
  21.             clearFocusState();
  22.         }
  23. }

  24.   private final class RawPictureCallback implements PictureCallback {
  25.         public void onPictureTaken(
  26.                 byte [] rawData, android.hardware.Camera camera) {
  27.             mRawPictureCallbackTime = System.currentTimeMillis();
  28.             Log.v(TAG, "mShutterToRawCallbackTime = "
  29.                     + (mRawPictureCallbackTime - mShutterCallbackTime) + "ms");
  30.         }
  31.     }

  32.     private final class PostViewPictureCallback implements PictureCallback {
  33.         public void onPictureTaken(
  34.                 byte [] data, android.hardware.Camera camera) {
  35.             mPostViewPictureCallbackTime = System.currentTimeMillis();
  36.             Log.v(TAG, "mShutterToPostViewCallbackTime = "
  37.                     + (mPostViewPictureCallbackTime - mShutterCallbackTime)
  38.                     + "ms");
  39.         }
  40.     }
  41.     private final class JpegPictureCallback implements PictureCallback {
  42.         Location mLocation;

  43.         public void onPictureTaken(
  44.                 final byte [] jpegData, final android.hardware.Camera camera) {
  45.             if (mPausing) {
  46.                 return;
  47.             }
  48.             mJpegPictureCallbackTime = System.currentTimeMillis();
  49.    
  50.            …………………..
  51.                 //这个函数等下做详解
  52.             mImageCapture.storeImage(jpegData, camera, mLocation);
  53.         }
  54.     }
  55. 2、上层注册好回调函数之后frameworks/base/core/java/android/hardware/camera.java注册回调函数
  56.   public final void takePicture(ShutterCallback shutter, PictureCallback raw,
  57.             PictureCallback postview, PictureCallback jpeg) {
  58.         mShutterCallback = shutter;
  59.         mRawImageCallback = raw;
  60.         mPostviewCallback = postview;
  61.         mJpegCallback = jpeg;
  62.      native_takePicture();
  63.     }

  64. frameworks/base/services/camera/libcameraservice
  65. // take a picture - image is returned in callback
  66. status_t CameraService::Client::takePicture() {
  67.     LOG1("takePicture (pid %d)", getCallingPid());
  68.     Mutex::Autolock lock(mLock);
  69.     status_t result = checkPidAndHardware();
  70.     if (result != NO_ERROR) return result;

  71.         //用于判断指定的msg所对应的callback是否可以回调
  72.     enableMsgType(CAMERA_MSG_SHUTTER |
  73.                   CAMERA_MSG_POSTVIEW_FRAME |
  74.                   CAMERA_MSG_RAW_IMAGE |
  75.                   CAMERA_MSG_COMPRESSED_IMAGE);

  76.     return mHardware->takePicture();//从这里就进入hal实现了,即上层提供操作设备驱动的接口
  77. }
  78. 3、HAL层的实现,接口被定义在cameraHardwareInterface.h文件中,所以hal层要做的就是实现其接口
  79. 其实写到这里,还是有很多不了解,如service中stub的概念,IPC的机制如何实现,功底还是太浅了,有空专门研究下这块
  80. 下面就仔细看下hal如何实现takepicture操作,同时向上层传递data
  81. status_t CameraHardwareSec::takePicture()
  82. {
  83.       stopPreview();
  84.     Mutex::Autolock lock(mStateLock);
  85.     if (mCaptureInProgress) {
  86.         LOGE("%s : capture already in progress", __func__);
  87.         return INVALID_OPERATION;
  88.     }
  89.     //启动PictureThread线程
  90.     if (mPictureThread->run("CameraPictureThread", PRIORITY_DEFAULT) != NO_ERROR) {
  91.         LOGE("%s : couldn't run picture thread", __func__);
  92.         return INVALID_OPERATION;
  93.     }
  94.     mCaptureInProgress = true;
  95.     return NO_ERROR;
  96. }
  97. int CameraHardwareSec::pictureThread()
  98. {
  99.     mRawHeap = new MemoryHeapBase(picture_size);
  100.     if (mRawHeap->getHeapID() < 0) {
  101.         LOGE("ERR(%s): Raw heap creation fail", __func__);
  102.         mRawHeap.clear();
  103.         return UNKNOWN_ERROR;
  104.     }

  105.     sp<MemoryHeapBase> JpegHeap;
  106.     sp<MemoryHeapBase> PostviewHeap;
  107.     sp<MemoryHeapBase> ThumbnailHeap;
  108.     sp<MemoryBase> buffer = new MemoryBase(mRawHeap, 0, picture_size + 8);

  109. //主要是将raw data照片原始数据通过encode成jpeg的格式
  110.     if ((mMsgEnabled & CAMERA_MSG_RAW_IMAGE)&&(mSecCamera->getJpegStreamPossible() != true)) {
  111.         LOG_TIME_DEFINE(1)
  112.         LOG_TIME_START(1)
  113.      JpegHeap = new MemoryHeapBase(jpeg_heap_size);
  114.          PostviewHeap = new MemoryHeapBase(picture_size);
  115.         ThumbnailHeap = new MemoryHeapBase(thumb_size);    
  116.         // Modified the shutter sound timing for Jpeg capture
  117.         mSecCamera->startSnapshot();
  118.         if (mMsgEnabled & CAMERA_MSG_SHUTTER) {
  119.             //回调shuttcallback的接口
  120.             mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
  121.         }
  122.         if(mSecCamera->getJpegStreamPossible() != true){
  123.             if (mSecCamera->getSnapshotAndJpeg((unsigned char*)PostviewHeap->base(),
  124.                     (unsigned char*)JpegHeap->base(), &jpeg_size) < 0) {
  125.                 LOGE("ERR(%s):Fail on SecCamera->getSnapshotAndJpeg()", __func__);
  126.                 mStateLock.lock();
  127.                 mCaptureInProgress = false;
  128.                 mStateLock.unlock();
  129.                 return UNKNOWN_ERROR;
  130.             }
  131.         }
  132.     }

  133.     int JpegImageSize = 10000, JpegExifSize;
  134.     bool isLSISensor = false;
  135.      JpegImageSize = static_cast<int>(jpeg_size);
  136.     CropScaleYUY2((char *)PostviewHeap->base(), picture_width, picture_height, 0, 0,
  137.                   (char *)ThumbnailHeap->base(), thumb_width, thumb_height);
  138.     memcpy(mRawHeap->base(),PostviewHeap->base(), picture_size);

  139. }
  140.     memcpy(static_cast<unsigned char*>(mPreviewHeap->base()) + offset + (previewWidth*previewHeight * 3 / 2),
  141.             overlay_header, mSizeOfADDRS);

  142.     ret = mOverlay->queueBuffer((void*)(static_cast<unsigned char *>(mPreviewHeap->base()) + offset +
  143.                                 (previewWidth * previewHeight * 3 / 2)));
  144.     if ((mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) &&(mSecCamera->getJpegStreamPossible() != true)) {
  145.         sp<MemoryHeapBase> ExifHeap = new MemoryHeapBase(EXIF_FILE_SIZE + picture_size);
  146.      if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE)    
  147.          mDataCb(CAMERA_MSG_RAW_IMAGE, buffer, mCallbackCookie);
  148.             JpegExifSize = mSecCamera->getExif((unsigned char *)ExifHeap->base(),
  149.                     (unsigned char *)ThumbnailHeap->base());

  150.         LOGW("JpegExifSize=%d", JpegExifSize);
  151.             unsigned char *ExifStart = (unsigned char *)JpegHeap->base() + 2;
  152.             unsigned char *ImageStart = ExifStart + JpegExifSize;

  153.             memmove(ImageStart, ExifStart, JpegImageSize - 2);
  154.             memcpy(ExifStart, ExifHeap->base(), JpegExifSize);
  155.         sp<MemoryBase> mem = new MemoryBase(JpegHeap, 0, JpegImageSize + JpegExifSize);
  156.         //压缩格式照片消息
  157.         mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
  158.     }
  159. }

  160. 现在我们来看下在hal定义的三个回调函数
  161. typedef void (*notify_callback)(int32_t msgType, //用于处理一些通知的消息,如快门
  162.                                 int32_t ext1,
  163.                                 int32_t ext2,
  164.                                 void* user);

  165. typedef void (*data_callback)(int32_t msgType, // 返回通过camera得到的raw data
  166.                               const sp<IMemory>& dataPtr,
  167.                               void* user);
  168. // 返回通过camera得到的raw data并且携带时间戳
  169. typedef void (*data_callback_timestamp)(nsecs_t timestamp,
  170.                                         int32_t msgType,
  171.                                         const sp<IMemory>& dataPtr,
  172.                                         void* user);
  173. 接口如下:
  174. /** Set the notification and data callbacks */
  175. virtual void setCallbacks(notify_callback notify_cb,
  176.                           data_callback data_cb,
  177.                           data_callback_timestamp data_cb_timestamp,
  178.                           void* user) = 0;
  179. 现在又返回到cameraService是如何处理hal发过来的消息
  180. void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1,
  181.         int32_t ext2, void* user) {
  182.     LOG2("notifyCallback(%d)", msgType);

  183.     sp<Client> client = getClientFromCookie(user);
  184.     if (client == 0) return;
  185.     if (!client->lockIfMessageWanted(msgType)) return;

  186.     switch (msgType) {//接收到的Hal层消息
  187.         case CAMERA_MSG_SHUTTER:
  188.             // ext1 is the dimension of the yuv picture.
  189.             client->handleShutter((image_rect_type *)ext1);
  190.             break;
  191.         default:
  192.             client->handleGenericNotify(msgType, ext1, ext2);
  193.             break;
  194.     }
  195. }

  196. void CameraService::Client::dataCallback(int32_t msgType,
  197.         const sp<IMemory>& dataPtr, void* user) {
  198.     LOG2("dataCallback(%d)", msgType);

  199.     sp<Client> client = getClientFromCookie(user);
  200.     if (client == 0) return;
  201.     if (!client->lockIfMessageWanted(msgType)) return;

  202.     if (dataPtr == 0) {
  203.         LOGE("Null data returned in data callback");
  204.         client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
  205.         return;
  206.     }

  207.     switch (msgType) {
  208.         case CAMERA_MSG_PREVIEW_FRAME:
  209.             client->handlePreviewData(dataPtr);
  210.             break;
  211.         case CAMERA_MSG_POSTVIEW_FRAME:
  212.             client->handlePostview(dataPtr);
  213.             break;
  214.         case CAMERA_MSG_RAW_IMAGE:
  215.             client->handleRawPicture(dataPtr);
  216.             break;
  217.         case CAMERA_MSG_COMPRESSED_IMAGE:
  218.             client->handleCompressedPicture(dataPtr);
  219.             break;
  220.         default:
  221.             client->handleGenericData(msgType, dataPtr);
  222.             break;
  223.     }
  224. }

  225. // picture callback - compressed picture ready
  226. void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
  227.     disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);

  228.     sp<ICameraClient> c = mCameraClient;
  229.     mLock.unlock();
  230. if (c != 0) {
  231. //回调函数
  232.         c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
  233.     }
  234. }
  235. 回到frameworks/base/core/java/android/hardware/camera.java 处理消息
  236. @Override
  237.         public void handleMessage(Message msg) {
  238.             switch(msg.what) {
  239.             case CAMERA_MSG_SHUTTER:
  240.                 if (mShutterCallback != null) {
  241.                     mShutterCallback.onShutter();
  242.                 }
  243.                 return;
  244.             ………………
  245.             case CAMERA_MSG_COMPRESSED_IMAGE:
  246.                 if (mJpegCallback != null) {
  247.                     //现在总算回到app时候注册的几个回调函数了
  248.                     mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
  249.                 }
  250.                 return;
  251.             default:
  252.                 Log.e(TAG, "Unknown message type " + msg.what);
  253.                 return;
  254.             }
  255.         }
  256. //这里就是存储数据的地方了,这里采用file的形式
  257. private int storeImage(byte[] data, Location loc) {
  258.             try {
  259.                 long dateTaken = System.currentTimeMillis();
  260.                 String title = createName(dateTaken);
  261.                 String filename = title + ".jpg";
  262.                 int[] degree = new int[1];
  263.                 mLastContentUri = ImageManager.addImage(
  264.                         mContentResolver,
  265.                         title,
  266.                         dateTaken,
  267.                         loc, // location from gps/network
  268.                         ImageManager.CAMERA_IMAGE_BUCKET_NAME, filename,
  269.                         null, data,
  270.                         degree);
  271.                 return degree[0];
  272.             } catch (Exception ex) {
  273.                 Log.e(TAG, "Exception while compressing image.", ex);
  274.                 return 0;
  275.             }
  276.         }

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android中的消息机制-个人心得
  4. Android(安卓)activity的生命周期
  5. Android应用程序组件Content Provider的启动过程源代码分析(3)
  6. Android应用程序组件Content Provider的启动过程源代码分析(5)
  7. android下usb框架系列文章---(3)Storage框架整理
  8. Android(安卓)activity的生命周期
  9. android 中调用接口发送短信

随机推荐

  1. Android FFmpeg 脚本编译静态库
  2. 简单几段代码实现窗口抖动
  3. gerrit 常用命令记录
  4. Android获取Theme的背景颜色
  5. android学习的网址
  6. android camera2 image 中获得的yuv数据
  7. android导航页制作appintro
  8. Android ADT安装
  9. Android Studio中添加自定义字体的方法
  10. Google 上载 Android(安卓)4.2.2 binarie