第一部分 MediaRecorder概述
Android
MediaRecorder包含了Audiovideo的记录功能,在Android的界面上,MusicVideo两个应用程序都是调用MediaRecorder实现的。
MediaRecorder
在底层是基于OpenCore(PacketVideo)的库实现的,为了构建一个MediaRecorder程序,上层还包含了进程间通讯等内容,这种进程间通讯的基础是Android基本库中的Binder机制。
以开源的Android为例MediaRecorder的代码主要在以下的目录中:
JAVA
程序的路径:
/packages/apps/SoundRecorder/src/com/android/soundrecorder/SoundRecorder.java

JAVA Framework
的路径:
frameworks/base/media/java/android/media/MediaRecorder.java

JAVA
本地调用部分(JNI):
frameworks/base/media/jni/android_media_MediaRecorder.cpp
这部分内容编译成为目标是libmedia_jni.so

主要的头文件在以下的目录中:
frameworks/base/include/media/

多媒体底层库在以下的目录中:
frameworks/base/media/libmedia/
这部分的内容被编译成库libmedia.so

多媒体服务部分:
frameworks/base/media/libmediaplayerservice/
MediaRecorder
MeidaPlayer使用相同的服务。

基于OpenCore部分

PVAuthor是基于OpenCoreAuthorEngineAndroid实现, 代码在以下路径中: external/opencore/android/author

这部分内容被编译成库libopencoreauthor.so

它实现的接口类是PVMediaRecorder.h,这个类基本上是一个封装,它需要处理三个方面的内容:

音频的输入环节(Audio Input

视频的输入(Camera

视频的预览(使用ISurface

其中实现PVMediaRecorder.h的类是PVMediaRecorder.cppauthordriver.hauthordriver.cpp是具体实现,android_audio_input.*android_camera_input.*是两个PvmiMIOControl的实现PvmiMIOControl最终会构建成一个Node.。它们是Active Source类型的Node,因此它们需要实现PvmiMediaTransfer::writeComplete()函数。

android_audio_input.*是作为音频输入的实现,它基于AndroidAudio系统构建,主要使用media/AudioRecord.h接口àAudioRecord.cpp

第二部分 MediaRecorder的接口与架构

MediaRecorder的各个可以用下图的表示:

MediaRecorder部分的头文件在frameworks/base/include/media/目录中,这个目录是和libmedia.so库源文件的目录frameworks/base/media/libmedia/相对应的。主要的头文件有以下几个:

■mediarecorder.h mediarecorder的上层接口

■IMediaRecorder.hMediaRecorder的服务部分实现接口

■PVMediaRecorder.h MediaRecorder的下层接口,由OpenCore实现

在这些头文件MediaRecorder.h提供了对上层的接口,而其他的几个头文件都是提供一些接口类(即包含了纯虚函数的类),这些接口类必须被实现类继承才能够使用。

整个MediaRecorder库和调用的关系如下图所示: 整个MediaRecorder在运行的时候,可以大致上分成ClientServer两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现IPC通讯。注意MediaRecorder中不需要使用callback,这点和MediaPlayer的架构有一定的区别,因此并不需要一个MediaRecorderClient的类。

MediaRecorder C语言上层的接口在mediarecorder.h 中,定义一个MediaRecorder类:

复制代码

1. class MediaRecorder

2. {

3. public:

4. MediaRecorder();

5. ~MediaRecorder();

6. status_tinitCheck();

7. status_tsetCamera(const sp<ICamera>& camera);

8. status_tsetPreviewSurface(const sp<Surface>& surface);

9. status_tsetVideoSource(int vs);

10. status_tsetAudioSource(int as);

11. status_tsetOutputFormat(int of);

12. status_tsetVideoEncoder(int ve);

13. status_tsetAudioEncoder(int ae);

14. status_tsetOutputFile(const char* path);

15. status_tsetVideoSize(int width, int height);

16. status_tsetVideoFrameRate(int frames_per_second);

17. status_tprepare();

18. status_tgetMaxAmplitude(int* max);

19. status_tstart();

20. status_tstop();

21. status_treset();

22. status_tinit();

23. status_tclose();

24. status_trelease();

25. };

meidarecorder的上层接口中,基本不涉及数据流的处理,但是需要设置两个重要的部分,一个是输入的设备ICamera,另一个是ICamera的预览(previewSurface

复制代码

1. status_tsetCamera(const sp<ICamera>& camera);

2. status_tsetPreviewSurface(const sp<Surface>& surface);

这两个类需要通过上层的接口设置,其中设置的Surface在下层的处理中也会被设置到ICamera的接口中,ICamera则作为这种meidarecorder视频输入的设备,在meidarecorder底层的实现中,通过这个Icamera获取视频流。
prepare()
start()stop()reset()等几个函数用于设置控制媒体记录的运行。
另外的几个接口用于设置音频、视频的输入和格式,输出的格式。

第三部分 PVAuthor的架构

PVAuthor是基于OpenCoreAuthorEngineAndroid实现, 代码在以下路径中:
external/opencore/android/author/
它实现的接口类是PVMediaRecorder.h,这个类基本上是一个封装,它需要处理三个方面的内容:
音频的输入环节(Audio Input
视频的输入(Camera
视频的预览(使用ISurface


其中实现PVMediaRecorder.h的类是PVMediaRecorder.cppauthordriver.hauthordriver.cpp是具体实现,android_audio_input.*android_camera_input.*是两个PvmiMIOControl的实现,PvmiMIOControl最终会构建成一个Node.。它们是Active Source类型的Node,因此它们需要实现PvmiMediaTransfer::writeComplete()函数。
AndroidCameraInput内部会建立一个Camera(可以不使用从外部得到的方式);AndroidCameraInput::SetPreviewSurface的函数用于得到一个外部的ISurface,这个Surface将被设置到Camera中,作为Camera的预览。
android_audio_input.*
是作为音频输入的实现,它基于AndroidAudio系统构建,主要使用media/AudioRecord.h接口。

第四部分 Android MediaRecorderCamera的关系

从功能的角度MediaRecorder一般包含音频,视频记录,视频预览的功能,Camera包含了取景区预览,静态图像捕获的功能。
Android中,应用程序自上而下分成JAVA应用,JAVA框架,JNIC框架,具体实现几个部分。多媒体方面的程序尤其是这样。
MediaRecorder
CameraAndroid中都有自上而下的架构,它们在顶层JAVA应用层,共用一个应用程序Camera(其中的程序也是独立的),在JAVA框架和JNI层是独立的,主要的联系在于CamerC框架以下的内容被MediaRecorder实现(也就是PVAuthor)所调用,作为MediaRecorder实现的视频输入设备,它的作用是负责传输视频数据和提供显示预览。本身Camera C框架以下的代码基本提供了取景器预览(Preview)、视频数据流获取、静止图像获取三方面的功能,MediaRecorder实现使用其取景器预览和视频数据流获取的功能,而CameraJNI使用其取景器预览和静止图像获取两方面的功能。

3.4 Camera服务libcameraservice.so

frameworks/base/camera/libcameraservice/ 用于实现一个Camera的服务,这个服务是继承ICameraService的具体实现。
在这里的Android.mk文件中,使用宏USE_CAMERA_STUB决定是否使用真的Camera,如果宏为真,则使用CameraHardwareStub.cppFakeCamera.cpp构造一个假的Camera,如果为假则使用CameraService.cpp构造一个实际上的Camera服务。
CameraService.cpp
是继承BnCameraService 的实现,在这个类的内部又定义了类ClientCameraService::Client继承了BnCamera。在运作的过程中CameraService::connect()函数用于得到一个CameraService::Client,在使用过程中,主要是通过调用这个类的接口来实现完成Camera的功能,由于CameraService::Client本身继承了BnCamera类,而BnCamera类是继承了ICamera,因此这个类是可以被当成ICamera来使用的。
CameraService
CameraService::Client两个类的结果如下所示:

复制代码

1. class CameraService : public BnCameraService

2. {

3. class Client : public BnCamera {};

4. wp<Client>mClient;

5. }


CameraService中的一个静态函数instantiate()用于初始化一个Camera服务,函数如下所示:

复制代码

1. void CameraService::instantiate() {

2. defaultServiceManager()->addService(

3. String16("media.camera"), new CameraService());

4. }


事实上,CameraService::instantiate()这个函数注册了一个名称为"media.camera"的服务,这个服务和Camera.cpp中调用的名称相对应。
Camera
整个运作机制是:在Camera.cpp中可以调用ICameraService的接口,这时实际上调用的是BpCameraService,而BpCameraService又通过Binder机制和BnCameraService实现两个进程的通讯。而BpCameraService的实现就是这里的CameraService。因此,Camera.cpp虽然是在另外一个进程中运行,但是调用ICameraService的接口就像直接调用一样,从connect()中可以得到一个ICamera类型的指针,真个指针的实现实际上是CameraService::Client
而这些Camera功能的具体实现,就是CameraService::Client所实现的了,其构造函数如下所示:

复制代码

1. CameraService::Client::Client(const sp<CameraService>& cameraService,

2. const sp<ICameraClient>& cameraClient) :

3. mCameraService(cameraService), mCameraClient(cameraClient), mHardware(0)

4. {

5. mHardware = openCameraHardware();

6. mHasFrameCallback = false;

7. }


构造函数中,调用openCameraHardware()得到一个CameraHardwareInterface类型的指针,并作为其成员mHardware。以后对实际的Camera的操作都通过对这个指针进行。这是一个简单的直接调用关系。
事实上,真正的Camera功能己通过实现CameraHardwareInterface类来完成。在这个库当中CameraHardwareStub.hCameraHardwareStub.cpp两个文件定义了一个桩模块的接口,在没有Camera硬件的情况下使用,例如在仿真器的情况下使用的文件就是CameraHardwareStub.cpp和它依赖的文件FakeCamera.cpp
CameraHardwareStub
类的结构如下所示:

复制代码

1. class CameraHardwareStub : public CameraHardwareInterface {

2. class PreviewThread : public Thread {

3. };

4. };


在类CameraHardwareStub当中,包含一个线程类PreviewThread,这个线程用于处理PreView,即负责刷新取景器的内容。实际的Camera硬件接口通常可以通过对v4l2 捕获驱动的调用来实现,同时还需要一个JPEG编码程序将从驱动中取出的数据编码成JPEG文件。

更多相关文章

  1. Android sql数据库的Android包里面的函数介绍
  2. Android:Serializable接口和Parcelable接口
  3. Android中调用C++函数的一个简单Demo
  4. 使用android中drawline函数无法绘制水平线的解决办法
  5. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第二
  6. 【Android】利用Fiddler进行抓包详解教程。抓取接口以及数据,可以
  7. AIDL --- Android中的远程接口
  8. Android中Parcelable和Serializable接口用法

随机推荐

  1. ionic android app 签名处理
  2. Android(安卓)打电话,发短信,调用系统浏览
  3. android中的getResource以及获取额外的资
  4. My Android(安卓)Camera Notes
  5. Android(安卓)浏览器打开APP中的Activity
  6. Android(安卓)4.0 分页指示器 Android(安
  7. android 项目 分享图片到微信
  8. 【翻译】(10)Import Module
  9. Android(安卓)里面的android_secret_code
  10. Android(安卓)Studio +Cordova +ionic 环