【Android源码 栏目提醒】:网学会员为需要Android源码 的朋友们搜集整理了【Android系统原理与开发要点详解】08_Android的Video_输入输出系统 - 开发文档相关资料,希望对各位网友有所帮助!
第一部分 Video输入输出系统的综述 第二部分 Overlay系统第三部分 Overlay的硬件抽象层第四部分 Camera系统与上层接口 第五部分 Camera的硬件抽象层 在
Android系统中视频的输入、输出具有特定的架构。
视频输入输出的两个部分是 视频输入Camera系统 既作为视频输入的接口也作为照相机应用的下层实现。
视频输出Overlay系统 一般作为视频输出的单独层次在硬件支持中实现。
Android的Overlay系统结构Overlay HAL实现Video Output DriverOverlay HardwareInterface内核空间C框架Overlay APIlibui.soOverlaySurfaceFlinger OverlayOverlay框架部分的头文件和源文件frameworks/base/include/ui/frameworks/base/libs/ui/主要为类是IOverlay和Overlay源代码被编译成库libui.so。
与Overlay相关的SurfaceFlingerframework/base/libs/surfaceflinger/主要的类是LayerBuffer。
Overlay的硬件抽象层的接口:hardware/libhardware/include/hardware/overlay.h
Android的Camera系统结构Camera HAL实现Camera ServiceCamera DriverCamera HardwareInterface内核空间C框架Camera APICamera JNIJava Camera Classandroid.hardware.cameralibui.soCameraJava 框架IPC CameraCamera框架部分的头文件和源文件frameworks/base/include/ui/frameworks/base/libs/ui/这部分的内容被编译成库libui.so。
Camera服务部分frameworks/base/camera/libcameraservice/ 这部分内容被编译成库libcameraservice.so。
Camera的JAVA本地调用部分JNIframeworks/base/core/jni/
android_hardware_Camera.cpp Camera的JAVA类frameworks/base/core/java/
android/hardware/Camera.javaCamera的硬件抽象层的定义frameworks/base/include/ui/目录之中的CameraHardwareInterface.h 在
Android中Overlay系统提供overlay接口这个接口的含义是叠加在主的显示层上的另外一个显示层这个叠加的显示层通常作为视频的输出或者照相机取景器的预览界面来使用。
Overlay通过ISurface接口来使用这个Overlay的使用与ISurface中的registerBufferspostBufferunregisterBuffers几个接口是并立的使用Overlay接口将和SurfaceFlinger中的显示等功能无关。
标题标题 ISurface接口的定义class ISurface : public IInterfacepublic: DECLARE_META_INTERFACESurface/ ... ... / virtual status_t registerBuffersconst BufferHeap buffers 0 virtual void postBufferssize_t offset 0 // one-way virtual void unregisterBuffers 0 virtual sp createOverlay uint32_t w uint32_t h int32_t format 0 Overlay接口虽然通过SurfaceFlinger的LayerBuffer来实现但是Overlay是一个独立接口和SurfaceFlinger的其他部分没有依赖关系。
在文件Overlay.h中 定义了两个类OverlayRef和Overlay。
class Overlay : public virtual RefBasepublic: Overlayconst sp overlayRef void destroy status_t dequeueBufferoverlay_buffer_t buffer status_t queueBufferoverlay_buffer_t buffer void getBufferAddressoverlay_buffer_t buffer/ ... .../ 类Overlay中的几个接口用于视频数据的输出可以用队列也可以直接使用地址。
不使用Overlay和使用Overlay的对比ISurfacePreview DataSurfaceFlinger/ 2D GraphicsFramebufferDriverVideo Output DataOverlay HALVideo Output Data ISurfaceSurfaceFlinger/ 2D GraphicsFramebufferDriverOverlayV4l2outputGet OverlayFbdriverVideo Out DevicePreview Data Overlay与其他系统不同它没有主动被
Android系统所使用因此如果移植了Overlay系统的硬件抽象层。
还需要增加使用Overlay的部分。
Overlay的使用场景主要有两个 视频播放器的输出PVPlayer Preview的输出CameraHal Overlay的硬件抽象层的接口在以下头文件中定义hardware/libhardware/include/hardware/overlay.h 在这个头文件中主要定义了两个类overlay_control_device_t和overlay_data_device_t它们分别继承了hw_device_t common通过这两个类实现Overlay的硬件抽象层。
实现一个Overlay的硬件抽象层使用的是
Android硬件模块的标准方法通过类overlay_module_t来完成。
openhw_module_t common .methodOVERLAY_HARDWARE_CONTROLOVERLAY_HARDWARE_DATAgetcreateOverlaydestroyOverlaysetPositiongetPositionsetParameterhw_device_t initializedequeueBufferqueueBuffergetBufferAddresshw_device_t w hformatw_stride h_stridereserved3getHandleRefreserved_procs7overlay_module_t overlay_control_device_t overlay_data_device_t overlay_t int numFds int fds4 int numInts int data0overlay_handle_t Overlay硬件抽象层的一个实现示例在以下中实现hardware/libhardware/modules/overlay/overlay.cpp static struct hw_module_methods_t overlay_module_methods open: overlay_device_openconst struct overlay_module_t HAL_MODULE_INFO_SYM common: tag: HARDWARE_MODULE_TAG version_major: 1 version_minor: 0 id: OVERLAY_HARDWARE_MODULE_ID name: Sample Overlay module author: The
Android Open Source Project methods: overlay_module_methods Overlay的使用过程overlay_control_open → overlay_module_thw_module_t common :: open → overlay_control_device_t hw_device_t common → overlay_module_thw_module_t common :: open → overlay_data_device_t hw_device_t commonoverlay_control_device_t :: createOverlay → overlay_t :: getHandleRef → overlay_handle_toverlay_data_device_t :: initializeoverlay_handle_toverlay_data_device_t :: dequeueBufferoverlay_data_device_t :: queueBufferoverlay_data_device_t :: getBufferAddress Overlay硬件抽象层需要基于一个视频显示的驱动来实现。
Overlay的硬件抽象层通常基于两个驱动 framerbuffer驱动程序 Video for Linux 2中的视频输出驱动。
基于framerbuffer驱动程序的实现通常实现获得内存地址的接口即可。
基于v4l2的实现可以提供流方式的接口获得更好的性能其中又分成使用内核内存和使用用户空间内存两种方式。
4.1 Camera框架和CameraService4.2 Camera的JNI和JAVA 在
Android 系统中
Android的Camera包含取景器viewfinder、视频数据获取Recording和拍摄照片的功能。
Camera部分的主要头的框架部分包含在ui库的中而Camera中间层的实现是CameraServiceCameraService通过调用下层的Camera硬件抽象层来实现功能。
Camera主要的头文件有以下几个 ICameraClient.h Camera.h ICamera.h ICameraService.h ICameraService.h、ICameraClient.h和ICamera.h三个类定义了Camera的接口和架构ICameraService.cpp和Camera.cpp两个文件用于Camera架构的实现Camera的具体功能在下层调用硬件相关的接口来实现。
Camera.h是Camera系统对上层的接口。
ICameraClientBnCameraClientCameraICameraBnCameraandroid_hardware_CameraJAVAICameraServiceBnCameraServiceCameraServiceCameraService::ClientCameraServiceCameraHardwareInterfaceICameraCameraICameraClientICameraServiceCameraHardwareInterfaceIPCHardwareCamera libNative Code Camera.h是Camera系统对上层的接口ICameraService.h、ICameraClient.h和ICamera.h三个类定义了Camera中间层实现的框架。
它们接口的形式不同但是具有Camera系统共同的几个方面 预览功能Preview 视频获取功能Recording 拍照照片takePicture 参数设置 Camera.h中定义Camera对上层的接口。
// Typical use casesdefine FRAME_CALLBACK_FLAG_NOOP 0x00define FRAME_CALLBACK_FLAG_CAMCORDER 0x01define FRAME_CALLBACK_FLAG_CAMERA 0x05define FRAME_CALLBACK_FLAG_BARCODE_SCANNER 0x07// msgType in notifyCallback and dataCallback functionsenum CAMERA_MSG_ERROR 0x001 CAMERA_MSG_SHUTTER 0x002 CAMERA_MSG_FOCUS 0x004 CAMERA_MSG_ZOOM 0x008 CAMERA_MSG_PREVIEW_FRAME 0x010 CAMERA_MSG_VIDEO_FRAME 0x020 CAMERA_MSG_POSTVIEW_FRAME 0x040 CAMERA_MSG_RAW_IMAGE 0x080 CAMERA_MSG_COMPRESSED_IMAGE 0x100 CAMERA_MSG_ALL_MSGS 0x1FF// ref-counted object for callbacksclass CameraListener: virtual public RefBasepublic: virtual void notifyint32_t msgType int32_t ext1 int32_t ext2 0 virtual void postDataint32_t msgType const sp dataPtr 0 virtual void postDataTimestampnsecs_t timestamp int32_t msgType const sp dataPtr 0 CameraService是继承BnCameraService 的实现在这个类的内部又定义了类ClientCameraService::Client继承了BnCamera。
在运作的过程中CameraService::connect函数用于得到一个CameraService::Client在使用过程中主要是通过调用这个类的接口来实现完成Camera的功能由于CameraService::Client本身继承了BnCamera类而BnCamera类是继承了ICamera因此这个类是可以被当成ICamera来使用的。
照相机有三种实现ViewFinderPreview的方式1.在CameraHAL中直接送给Overlay2.在CameraService中调用ISurface的postBuffer接口送出数据。
3.Camera类通过Callback送给上层由上层处理 在
Android照相机/摄像机应用程序中使用的是2和3这两种方法具体是2还是3由CameraService读取CameraHAL的useOverlay接口来实现。
Camera ServiceCamera本地类SurfaceSetCamera Hardware InterfaceISurfaceSetCaptureDriverUser Spacekernel SpaceOverlayVideo Out DeviceGet1.To Overlay2.To ISurface3.Callback to High levelCamera JNICamera JAVAPostEventFromNativepost_eventPreview dataCamera DataPreview的三种方式的数据流 拍照时的数据流Camera ServiceCamera本地类SurfaceSetCamera HalISurfaceSetCaptureDriverUser Spacekernel SpaceOverlayVideo Out DeviceGetCamera JNICamera JAVAPostEventFromNativepost_eventPreview dataCamera DataCaptureImage DataRaw / JPEG 录制视频时的数据流Recording ClientPVAuthorCamera ServiceCamera Native ClassSurfaceSetCamera HalISurfaceSetCaptureDriverUser Spacekernel SpaceOverlayVideo Out DeviceGetRecordingdatamemmemmemSend to Encoder byRecordingCallbackStart /ReleaseFrameMapCamera Data
Android的Camera使用JNI为向上层JAVA提供了接口。
Camera在JAVA中的类是
android.hardware.Camera。
Camera的JAVA本地调用部分JNIframeworks/base/core/jni/
android_hardware_Camera.cpp Camera的JAVA类frameworks/base/core/java/
android/hardware/Camera.java Camera的硬件抽象层的在UI库的头文件CameraHardwareInterface.h文件定义。
在这个接口中包含了控制通道和数据通道控制通道用于处理预览和视频获取的开始/停止、拍摄照片、自动对焦等功能数据通道通过回调函数来获得预览、视频录制、自动对焦等数据。
Camera的硬件抽象层中还可以使用Overlay来实现预览功能。
CameraHardwareInterface.h文件的定义/ Callback for startPreview /typedef void preview_callbackconst sp mem void user/ Callback for startRecord /typedef void recording_callbackconst sp mem void user/ Callback for takePicture /typedef void shutter_callbackvoid user/ Callback for takePicture /typedef void raw_callbackconst sp mem void user/ Callback for takePicture /typedef void jpeg_callbackconst sp mem void user/ Callback for autoFocus /typedef void autofocus_callbackbool focused void user CameraHardwareInterface.h文件的定义class CameraHardwareInterface : public virtual RefBase public: virtual CameraHardwareInterface virtual sp getPreviewHeap const 0 virtual sp getRawHeap const 0 virtual status_t startPreviewpreview_callback cb void user 0 virtual bool useOverlay return false virtual status_t setOverlayconst sp overlay return BAD_VALUE virtual void stopPreview 0 virtual bool previewEnabled 0 virtual status_t startRecordingrecording_callback cb void user 0 virtual void stopRecording 0 virtual bool recordingEnabled 0 virtual void releaseRecordingFrameconst sp mem 0 virtual status_t autoFocusautofocus_callback void user 0 virtual status_t takePictureshutter_callback raw_callback jpeg_callback void user 0 virtual status_t cancelPicturebool cancel_shutter bool cancel_raw bool cancel_jpeg 0 virtual status_t setParametersconst CameraParameters params 0 virtual CameraParameters getParameters const 0 virtual void release 0 virtual status_t dumpint fd const Vector args const 0
Android的??clair版本中:CameraHardwareInterface.h文件的定义typedef void notify_callbackint32_t msgType int32_t ext1 int32_t ext2 void usertypedef void data_callbackint32_t msgType const sp dataPtr void usertypedef void data_callback_timestampnsecs_t timestamp int32_t msgType const sp dataPtr void user class CameraHardwareInterface : public virtual RefBase public: virtual CameraHardwareInterface virtual sp getPreviewHeap const 0 virtual sp getRawHeap const 0 virtual void setCallbacksnotify_callback notify_cb data_callback data_cb data_callback_timestamp data_cb_timestamp void user 0 virtual void enableMsgTypeint32_t msgType 0 virtual void disableMsgTypeint32_t msgType 0 virtual bool msgTypeEnabledint32_t msgType 0 virtual status_t startPreview 0 virtual bool useOverlay return false virtual status_t setOverlayconst sp overlay return BAD_VALUE virtual void stopPreview 0 virtual bool previewEnabled 0 virtual status_t startRecording 0 virtual void stopRecording 0 virtual bool recordingEnabled 0 virtual void releaseRecordingFrameconst sp mem 0 virtual status_t autoFocus 0 virtual status_t cancelAutoFocus 0 virtual status_t takePicture 0 virtual status_t cancelPicture 0 virtual status_t setParametersconst CameraParameters params 0 virtual CameraParameters getParameters const 0 virtual status_t sendCommandint32_t cmd int32_t arg1 int32_t arg2 0 virtual void release 0 virtual status_t dumpint fd const Vector args const 0 在CameraService中实现了一个CameraHardwareInterface的“桩”它们在文件CameraHardwareStub.cpp和FakeCamera.cpp中实现。
当编译宏USE_CAMERA_STUB打开的时候CameraService将使用这个桩这样整个Camera模块可以在没有硬件的情况下编译通过并可以假装运行。
取景器预览的主要步骤如下所示 在初始化的过程中建立预览数据的内存队列多种方式 在startPreview的实现中保存预览回调函数建立预览线程 在预览线程的循环中等待视频数据的到达 视频帧到达后调用预览回调函数将视频帧送出。
如果使用Overlay实现取景器则需要有以下两个变化 在setOverlay函数中从ISurface接口中取得Overlay类 在预览线程的循环中不需要使用预览回调函数直接将视频数据输入到Overlay上。
对于Linux系统而言摄像头驱动部分大多使用Video for Linux 2V4L2驱动程序在此处主要的处理流程可以如下所示 如果使用映射内核内存的方式V4L2_MEMORY_MMAP构建预览的内存MemoryHeapBase需要从V4L2驱动程序中得到内存指针 如果使用用户空间内存的方式V4L2_MEMORY_USERPTRMemoryHeapBase中开辟的内存是在用户空间建立的 在预览的线程中使用VIDIOC_DQBUF调用阻塞等待视频帧的到来处理完成后 使用VIDIOC_QBUF调用将帧内存再次压入队列等待下一帧的到来。
录制视频的主要步骤如下所示 在startRecording的实现或者在setCallbacks中保存录制视频回调函数 录制视频可以使用自己的线程也可以使用预览线程 通过录制回调函数将视频帧送出 releaseRecordingFrame被调用后表示上层通知Camera硬件抽象层这一帧的内存已经用完可以进行下一次的处理。
如果在V4L2驱动程序中使用原始数据RAW则视频录制的数据和取景器预览的数据为同一数据。
releaseRecordingFrame被调用时通常表示编码器已经完成了对当前视频帧的编码对这块内存进行释放。
在这个函数的实现中可以设置标志位标记帧内存可以再次使用。