Camera 的硬件抽象层的在 UI 库的头文件 CameraHardwareInterface.h 文件定义。
在这个接口中,包含了控制通道和数据通道
,控制通道用于处理预览和视频获取的开始 / 停 止、拍摄照片、自动对焦等功能,数据通道通过 回调函数来获得预览、视频录制、自动对焦等数 据。
Camera 的硬件抽象层中还可以使用 Overlay 来实现预览功能。
第五部分 Camera 的硬件抽象层
CameraHardwareInterface.h 文件的定义:
/** Callback for startPreview() */
typedef void (*preview_callback)(const sp<IMemory>& mem, void* user);
/** Callback for startRecord() */
typedef void (*recording_callback)(const sp<IMemory>& mem, void* user);
/** Callback for takePicture() */
typedef void (*shutter_callback)(void* user);
/** Callback for takePicture() */
typedef void (*raw_callback)(const sp<IMemory>& mem, void* user);
/** Callback for takePicture() */
typedef void (*jpeg_callback)(const sp<IMemory>& mem, void* user);
/** Callback for autoFocus() */
typedef void (*autofocus_callback)(bool focused, void* user);
第五部分 Camera 的硬件抽象层
CameraHardwareInterface.h 文件的定义:
class CameraHardwareInterface : public virtual RefBase { public:
virtual ~CameraHardwareInterface() { }
virtual sp<IMemoryHeap> getPreviewHeap() const = 0;
virtual sp<IMemoryHeap> getRawHeap() const = 0;
virtual status_t startPreview(preview_callback cb, void* user) = 0;
virtual bool useOverlay() {return false;}
virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}
virtual void stopPreview() = 0;
virtual bool previewEnabled() = 0;
virtual status_t startRecording(recording_callback cb, void* user) = 0;
virtual void stopRecording() = 0;
virtual bool recordingEnabled() = 0;
virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
virtual status_t autoFocus(autofocus_callback, void* user) = 0;
virtual status_t takePicture(shutter_callback, raw_callback, jpeg_callback, void* user) = 0;
virtual status_t cancelPicture(bool cancel_shutter, bool cancel_raw, bool cancel_jpeg) = 0;
virtual status_t setParameters(const CameraParameters& params) = 0;
第五部分 Camera 的硬件抽象层
Android 的 Éclair 版本中 :
CameraHardwareInterface.h 文件的定义:
typedef void (*notify_callback)(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
typedef void (*data_callback)(int32_t msgType,
const sp<IMemory>& dataPtr, void* user);
typedef void (*data_callback_timestamp)(nsecs_t timestamp, int32_t msgType,
const sp<IMemory>& dataPtr, void* user);
第五部分 Camera 的硬件抽象层
class CameraHardwareInterface : public virtual RefBase { public:
virtual ~CameraHardwareInterface() { }
virtual sp<IMemoryHeap> getPreviewHeap() const = 0;
virtual sp<IMemoryHeap> getRawHeap() const = 0;
virtual void setCallbacks(notify_callback notify_cb, data_callback data_cb,
virtual status_t setOverlay(const sp<Overlay> &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 releaseRecordingFrame(const sp<IMemory>& 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 setParameters(const CameraParameters& params) = 0;
第五部分 Camera 的硬件抽象层
在 CameraService 中,实现了一个
CameraHardwareInterface 的“桩”,它们在文 件 CameraHardwareStub.cpp 和
FakeCamera.cpp 中实现。
当编译宏
USE_CAMERA_STUB
打开的时 候, CameraService 将使用这个桩,这样整个 Camera 模块可以在没有硬件的情况下编译通过 并可以假装运行。第五部分 Camera 的硬件抽象层
取景器预览的主要步骤如下所示:
在初始化的过程中,建立预览数据的内存队列(多种方式)
;
在 startPreview() 的实现中,保存预览回调函数,建立预览 线程;
在预览线程的循环中,等待视频数据的到达;
视频帧到达后调用预览回调函数,将视频帧送出。
如果使用 Overlay 实现取景器,则需要有以下两个变化:
在 setOverlay() 函数中,从 ISurface 接口中取得 Overlay 类
;
在预览线程的循环中,不需要使用预览回调函数,直接将视 频数据输入到 Overlay 上。
第五部分 Camera 的硬件抽象层
对于 Linux 系统而言,摄像头驱动部分大多使用 Video for Linux 2 ( V4L2 )驱动程序,在此处主要的处 理流程可以如下所示:
如果使用映射内核内存的方式
( V4L2_MEMORY_MMAP ),构建预览的内存
MemoryHeapBase 需要从 V4L2 驱动程序中得到内存指 针;
如果使用用户空间内存的方式
( V4L2_MEMORY_USERPTR ), MemoryHeapBase 中开辟的内存是在用户空间建立的;
在预览的线程中,使用 VIDIOC_DQBUF 调用阻塞等 待视频帧的到来,处理完成后 使用 VIDIOC_QBUF 调用 将帧内存再次压入队列,等待下一帧的到来。
第五部分 Camera 的硬件抽象层
录制视频的主要步骤如下所示:
在 startRecording() 的实现(或者在 setCallbacks )中
,保存录制视频回调函数;
录制视频可以使用自己的线程,也可以使用预览线程;
通过录制回调函数将视频帧送出;
releaseRecordingFrame() 被调用后,表示上层通知
Camera 硬件抽象层,这一帧的内存已经用完,可以进行下 一次的处理。
如果在 V4L2 驱动程序中使用原始数据( RAW ),则视频录 制的数据和取景器预览的数据为同一数
据。 releaseRecordingFrame() 被调用时,通常表示编码器 已经完成了对当前视频帧的编码,对这块内存进行释放。在 这个函数的实现中,可以设置标志位,标记帧内存可以再次