Android Camera 数据流

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.         }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值