`
isiqi
  • 浏览: 16744682 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Android系统中视频电话中camera部分数据流分析

阅读更多

最近在研究如何移植Android的camera系统,对camera的应用场景做了一些分析。 Camera一般用于图像浏览、拍照和视频录制。图像浏览和拍照的数据流是比较清晰 的,这里就不做赘述了。视频录制应用于视频电话中。拨打视频电话时,既可以看 见对方的图像,又可以看见自己的图像;当然,对方也是如此。从camera获取的图 像数据,既需要在本地浏览,还需要video encoder编码后传输到对方手机。这样 的场景中,图像数据要同时做preview和record两种操作。 一、回调函数传递 首先需要将客户端的回调函数传递到底层,当底层获取完图像数据后,回调该函 数,通知上层,做相应的处理。 类AndroidCameraInput作为客户端,它有两个成员,分别为: sp mCamera; sp mListener; 类AndroidCameraInput就可以通过mCamera访问camera系统的对外接口。 类AndroidCameraInputListener继承于类CameraListener,它有三个成员函数,分 别为: virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2){} virtual void postData(int32_t msgType, const sp& dataPtr); virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp& dataPtr); 这里需要说明的是postDataTimestamp(),它是客户端实现的回调函数,其定义为: void AndroidCameraInputListener:: postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp& dataPtr){} 当camera HAL层捕获到一帧数据后,就会调用该回调函数,告诉客户端。客户端在 这个回调函数里先判断参数msgType是不是CAMERA_MSG_VIDEO_FRAME,如果是,即 表示要对该帧数据进行编码处理,编码结束后会调用mCamera的函数 releaseRecordingFrame(),其对应的HAL层的定义为: void QualcommCameraHardware::releaseRecordingFrame(const sp& mem_attibute_((unused))){} 在这个函数里,会调用函数LINK_camera_release_frame()告诉camera硬件,存放 当前帧的buffer可以被释放,用于下一帧使用。 回调函数postDataTimestamp()如何注册到HAL层,这里需要详细说明。 在客户端中,是通过mCamera的setListener()函数将mListener注册到mCamera中 的,既将几个回调函数注册给mCamera: mCamera->setListener(mListener); mCamera继承于类BnCameraClient,而BnCameraClient继承于类ICameraClient。类 ICameraClient有纯虚函数: virtual void dataCallbackTimstamp(nsecs_t timestamp, int32_t msgType, const sp& data) = 0; 类Camera中定义了虚函数dataCallbackTimstamp()并做了实现: virtual void dataCallbackTimstamp(nsecs_t timestamp, int32_t msgType, const sp& data); dataCallbackTimstamp()实现中,调用了类Camera的成员mListener的成员函数 postDataTimestamp()。 类CameraService有成员类Client,类Client有成员: sp mCameraClient; sp mHardware; 在类CameraService的成员类Client构造函数中: CameraService::Client::Client(const sp& cameraService, const sp& cameraClient, pid_t clientPid){} 其中调用了mHardware的函数setCallbacks(): mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, mCameraService.get()); 如下函数: bool QualcommCameraHardware::setCallbacks(preview_callback pcb, void *puser, recording_callback rcb, void *ruser){} 将recording_callback赋给了mHardware的成员mRecordingCallback,至此,已将 类AndroidCameraInput中的回调函数postDataTimestamp()传递给了camera的HAL层 的成员mRecordingCallback。 二、数据buffer分配 在提供的Android代码中,有一个camera HAL层的实例,即 QualcommCameraHardware。在类QualcommCameraHardware中,默认分配了6个 buffer,其中4个preview buffer,1个raw buffer,1个JPEG buffer。在视频电话 中,只用了preview buffer。 类QualcommCameraHardware在函数initPreview()中对preview buffer做了初始化。 bool QualcommCameraHardware::initPreview(){} 其中有code为: mPreviewHeap = new PreviewPmemPool(kRawFrameHeaderSize + mPreviewWidth * mPreviewHeight * 2, //worst kPreviewBufferCount, mPreviewFrameSize, kRawFrameHeaderSize, “preview”); QualcommCameraHardware::PreviewPmemPool::PreviewPmemPool( int buffer_size, int num_buffers, int frame_size, int frame_offset, const char *name) : QualcommCameraHardware::PmemPool("/dev/pmem_adsp", buffer_size, num_buffers, frame_size, frame_offset, name) { LOGV("constructing PreviewPmemPool"); if (initialized()) { LINK_camera_assoc_pmem(QDSP_MODULE_VFETASK, mFd, mHeap->base(), mAlignedSize, 0); // external } } QualcommCameraHardwares使用PMEM驱动对preview buffer进行了分配。Android PMEM是其专用的驱动,称为物理内存驱动。在HAL层分配完preview buffer后,通 过函数LINK_camera_assoc_pmem将分配信息传递给底层库。底层库中有对这4个 preview buffer的管理机制。 视频电话中,当camera捕获一帧数据后,存储该数据的buffer会被同时用于 preview和record。只用当客户端调用了函数releaseRecordingFrame()之后才能将 对应的buffer释放掉,用于其它帧使用。 三、视频录制调用 客户端类AndroidCameraInput启动record,通过下面的调用: mCamera->startRecording(); 其会调到函数: status_t CameraService::Client::startRecording(){} 此处为mHardware设置了message CAMERA_MSG_VIDEO_FRAME,并调用函数 startCameraMode()。其定义为: status_t CameraService::Client::startCameraMode(camera_mode mode){} 参数camera_mode为CAMERA_RECORDING_MODE,于是调了startRecordingMode。其定 义为: status_t CameraService::Client::startRecordingMode(){} 其中会先启动preview,如果它没有启动的话,调用了startPreviewMode,即: status_t CameraService::Client::startPreviewMode(){} 这里会处理preview的显示介质,如果使用Overlay显示,会设置相应的Overlay, 同时调用mHardware->startPreview()以启动preview;否则先调用 mHardware->startPreview()启动preview,然后设置buffer:调用函数 registerPreviewBuffers(),其定义为: status_t CameraService::Client::registerPreviewBuffers(){} 这里会调用mHardware->getPreviewHeap(),从HAL层获得preview的buffer,将其 设置给Surface去显示preview的结果。 类QualcommCameraHardware对startPreview的定义如下: status_t QualcommCameraHardware::startPreview(preview_callback pcb, void *puser){} 它调用了startPreviewInternal(),其定义为: status_t QualcommCameraHardware:startPreviewInternal(preview_callback pcb, void (puser, recording_callback rcb, void *ruser){} 函数里调用了setCallbacks(pcb, puser, rcb, ruser),更新了preview和record 的回调函数。另外调用函数LINK_camera_start_preview(camera_cb, this),向 driver层传递函数camera_cb。其定义为: void QualcommCameraHardware::camera_cb(camera_cb_type cb, const void *client_data, camera_func_type func, int32_t parm4){} 函数里,当mCameraState为QCS_PREVIEW_IN_PROGRESS时,preview成功,同时调用 函数receivePreviewFrame,其定义为: void QualcommCameraHardware::receivePreviewFrame(camera_frame_type *frame){} 它调用了回调函数mPreviewCallback和mRecordingCallback,这就回调了函数 postDataTimstamp(),告诉客户端一帧数据已经获取成功,其可以开始编码了。 前面已经讲过,当客户端对该帧数据的处理结束后,会告诉底层库释放该帧所占用 的buffer空间,以备其他帧使用。 如此,preview和record同时进行,即可实现视频电话功能。 四、Preview数据的显示 Preview数据可以通过Overlay和Surface两种介质去显示,下面分别作以介绍。 1、 使用Overlay显示 如果要使用Overlay,底层硬件必须支持Overlay。在CameraService::Client的构 造函数中,有相应的判断。 CameraService::Client::Client(const sp& cameraService, const sp& cameraClient, pid_t clientPid){} mUseOverlay = mHardware->useOverlay();如果返回值为true,则表示硬件支持 Overlay;否则只能使用Surface显示。 status_t CameraService::Client::startPreviewMode(){}中,判断如果Overlay 可用,就会调用函数setOverlay(),其定义为: status_t CameraService::Client::setOverlay(){} 其中会通过mSurface->createOverlay()创建Overlay,然后通过函数 mHardware->setOverlay(new Overlay(mOverlayRef));将其设置给mHardware。 Android系统中提供了Overlay的接口,其具体实现需要自己做。在TI的实例中,在 创建Overlay时,它就为Overlay申请了8个buffer。然后在HAL层,通过Overlay的 接口:void* getBufferAddress(overlay_buffer_t buffer),获得Overlay的 buffer地址。将该buffer传递给硬件,camera硬件将捕获的数据填充到该buffer 中。然后通过Overlay的接口:status_t queueBuffer(overlay_buffer_t buffer),将该buffer加入到Overlay的队列中。最后调用Overlay的接 口:status_t dequeueBuffer(overlay_buffer_t* buffer),将那个buffer从队列 中取出,此时即Overlay已经对其显示过了。dequeueBuffer()一般应该是一个阻塞 函数,当显示完成后这个函数才返回。 当然,Overlay的buffer也可以在HAL层申请,然后通过queueBuffer(),将buffer 加入到Overlay的队列中。 2、 使用Surface显示 在CameraService的函数:status_t CameraService::Client::startPreviewMode()中,如果使用Surface,会调用函数 registerPreviewBuffers()向Surface注册buffers。registerPreviewBuffers()的 定义为: status_t CameraService::Client::registerPreviewBuffers(){} 其中有: ISurface::BufferHeap buffers(w, h, w, h, PIXEL_FORMAT_YCbCr_420_SP, transform, 0, mHardware->getPreviewHeap()); status_t ret = mSurface->registerBuffers(buffers); 其将mHardware的preview heap传递给了Surface。 当Camera的底层库中获取到了preview数据,它会回调函数: void QualcommCameraHardware::camera_cb(camera_cb_type cb, const void *client_data, camera_func_type func, int32_t parm4){} 其中,在preview模式下,会调用函数: void QualcommCameraHardware::receivePreviewFrame(camera_frame_type *frame){} 它有代码如下: mPreviewCallback(mPreviewHeap->mBuffers[offset], mPreviewCallbackCookie); 这是回调了preview的回调函数。其定义为: void CameraService::Client::dataCallback(int32_t msgType, const sp& dataPtr, void* user){} 其中,preview模式下,会调用函数: void CameraService::Client::handlePreviewData(const sp& mem){} 其通过mSurface->postBuffer(offset),将存储当前捕获数据的buffer送给 Surface去显示。 函数CameraService::Client::stopPreview()中会调用函数: mSurface->unregisterBuffers(),以释放原来注册的buffers。 当回调了preview的回调函数mPreviewCallback之后,如果mRecordingCallback为 空,则直接调用LINK_camera_release_frame(),释放当前图像数据的buffer;否 则调用回调函数mRecordingCallback,进入录制的流程。 以上就是我对Android系统中,视频电话的Camera部分的数据流的一个简单分析。 如有问题,还望各位高手指点,谢谢。

分享到:
评论

相关推荐

    视频电话中camera部分数据流分析

    通过对视频电话中camera部分数据流的分析,我们可以看到,为了实现本地预览和远程传输的功能,Android的camera系统采用了复杂的回调机制和数据处理流程。客户端需要向HAL层注册回调函数,以便在获取图像数据后能够...

    Android中视频电话中camera部分数据流分析

    拨打对方电话可以看到自己的图像,也可以看到对方的图像,该文档介绍了如何从camera获取到图像数据,显示在本地,同时通过video encode编码将图像传递到对方手机中。

    Android 5.0 Camera系统源码分析4:Camera预览流程数据流.doc

    在Android 5.0 Camera系统中,预览流程数据流是一个关键部分,它涉及如何从Camera设备获取图像数据,并将其呈现在屏幕上。本篇主要分析了Camera预览流程中的两个核心组件:CamAdapter和DisplayClient。 1. ...

    android 原生人脸识别Camera和Camera2的示例

    4. **处理预览帧**:在预览回调中,获取到`byte[]`类型的预览帧数据,然后通过`FaceDetector`进行分析,找出人脸的位置和大小。 5. **处理检测结果**:`FaceDetector`会返回`Face`对象,其中包含了人脸的坐标和表情...

    android framework camera分析

    Android系统中的Camera模块是一个重要的组成部分,主要用于处理视频输入功能。该模块被设计为一个框架层(framework),旨在支持多种不同类型的硬件设备。通过这样的设计,开发人员可以利用Camera框架轻松地适配各种...

    Android camera2预览和取数据

    在Android平台上,Camera2 API是自Android 5.0(API级别21)引入的全新相机接口,旨在提供更高级别的控制和性能。这个API允许开发者深入到相机硬件的细节,实现专业级的拍照和视频录制功能。本文将详细介绍如何使用...

    Android系统 USBCamera使用案例

    在Android系统中,USB Camera(通用串行总线相机)是一种允许设备通过USB接口连接到Android设备并作为摄像头使用的功能。这种技术对于扩展Android设备的摄像头功能,例如在没有内置摄像头或者需要更高性能摄像头的...

    安卓利用CameraX 拍照获这张照片的exif信息

    在Android开发中,CameraX库是一个现代化的、易于使用的摄影API,它简化了与相机硬件的交互,使得开发者能够更高效地实现拍照、录像等功能。本篇将详细讲解如何使用CameraX库拍摄照片并获取其EXIF信息。 EXIF...

    Android USBCamera,UVCCamera开发通用库

    3. **UVCCamera库**:`UVCCamera`库是一个专门为Android设计的开源库,用于处理UVC设备的视频流。这个库提供了与USB摄像头交互的API,包括打开、关闭摄像头,设置分辨率、帧率等。 4. **SurfaceView集成**:为了...

    高通平台camera框架分析

    **Camera子系统**作为Android系统中的关键组成部分,不仅负责视频数据的获取与存储,还涉及图像处理、视频编解码等多项任务。从整体上看,Camera子系统主要由应用层、框架层、驱动层构成。 ##### **1. 应用层** ...

    Android 自带应用相机(Camera)源代码

    在Android系统中,相机应用是用户与设备物理摄像头交互的核心组件。通过分析Android自带应用相机的源代码,我们可以深入理解其工作原理,从而为自定义相机功能或优化现有相机应用提供宝贵参考。以下是对Android相机...

    Android 自定义相机Camera2源码下载

    在Android平台上,自定义相机开发是一项常见的任务,Camera2 API是Google为了提供更高级、更灵活的相机控制而引入的接口。本教程将深入探讨如何使用Camera2 API创建一个自定义相机应用,通过分析提供的OneSelfCamera...

    安卓Android源码——camera,修改过可以在4.0系统上运行。.zip

    这份“安卓Android源码——camera,修改过可以在4.0系统上运行”的压缩包,提供了Android 4.0(Ice Cream Sandwich, ICS)系统下相机功能的源代码,经过修改后兼容该版本的操作系统。这里我们将深入探讨Android 4.0...

    android camera v4l2测试代码

    在这个“android camera v4l2测试代码”中,我们主要探讨的是如何在HAL(Hardware Abstraction Layer,硬件抽象层)上利用V4L2进行相机驱动的测试,以及这对于理解Android相机数据流Buffer的工作原理的价值。...

    Android_Camera分析

    ### Android_Camera分析:深入理解Android相机模块架构与工作流程 #### 概述 在现代移动设备中,相机功能已成为不可或缺的一部分。Android系统以其强大的可扩展性和开放性,为开发者提供了丰富的相机API,使得应用...

    Android Studio Camera2的录像功能

    Android Studio提供了强大的集成开发环境,而Camera2 API则是Android系统提供给开发者用于访问和控制摄像头的高级接口。本篇将详细介绍如何利用MediaRecorder和Camera2框架来实现一个基本的录像功能。 1. **Camera2...

    android的hal层下的camera的实现

    HAL层对于camera的实现是Android相机功能的核心部分,这部分代码通常被视为内部实现,不对外公开,以保护系统的稳定性和安全性。 1. **HAL层简介** - HAL层的主要任务是为Android系统提供一种标准接口,使得上层...

    高通平台camera HAL3添加raw12数据流传输

    此patch为将raw12数据流传输给上层,高通平台默认支持raw10和raw16,按照基础框架将raw12添加进camera HAL3代码中即可。

    Android 5.0 Camera系统源码分析3:Camera预览流程控制流.doc

    在Android 5.0 Camera系统中,预览流程控制流是整个相机功能的关键部分,它涉及到从用户界面到硬件驱动的多个层次交互。本篇分析将深入探讨如何启动相机预览,以及预览数据如何在不同层之间传递。 首先,预览流程在...

    android camera2 google官方demo

    在Android平台上,摄像头功能是应用程序开发中的重要组成部分。随着技术的发展,从早期的`Camera` API到后来推出的`Camera2` API,Google为开发者提供了更强大、更灵活的相机控制能力。`Camera2` API自Android 5.0...

Global site tag (gtag.js) - Google Analytics