MediaRecorder流程分析
目录
一、 java层
media recorder state machine:
1、java应用层
java应用层主要是一些接口的调用,它并没有具体功能代码的实现,java应用层的代码路径为:
android/packages/apps/SoundRecorder/src/com/android/soundrecorder/
该目录下有文件: SoundRecorder.java Recorder.java VUMeter.java
soundrecorder.java是程序的入口文件,我们在可以在里面设置文件输出编码格式的格式,现在系统默认支持两种格式amr和3gpp格式。设置代码如下:
mRequestedType =AUDIO_3GPP; //02 AUDIO_AMR;
接着运行mRecorder = new Recorder();创建一个Recorder类。Recorder类在Recorder.java中定义。
Recorder的startRecording方法启动了java层的录音。startRecording方法中首先创建一个Mediarecorder的类,然后调用Mediarecorder的方法完成设置audio源、设置输出文件格式、audio编码格式、设置输出文件,然后检查MediaRecorder是否准备好了。如果准备好就启动。如果没有准备好就抛出异常然后重新设置MediaRecorder和释放MediaRecorder。代码如下所示:
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(outputfileformat);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
// Handle IOException
try {
mRecorder.prepare();
} catch(IOException exception) {
setError(INTERNAL_ERROR);
mRecorder.reset();
mRecorder.release();
mRecorder = null;
return;
}
mRecorder.start();
2、JAVA Framework层
Java的framework层代码位于:
frameworks/base/media/java/android/media/MediaRecorder.java
它没有具体的实现只是一个接口而已。
3、JAVA本地调用部分(JNI):
frameworks/base/media/jni/android_media_MediaRecorder.cpp
jni层的只是实现了方法的注册,为java层调用C++程序提供一种注册。
这三给部分的程序会编译成一个libmedia_jni.so库,java层序的调用都是调用该库中的接口。具体的实现要要在我们的多媒体底层库。
二、 多媒体底层库
1、ImediaRecorder.cpp
Imediarecorder.cpp文件中实现了BP功能。BP和BN是通过binder来通信的。Bp主要是用来处理java层传下来的服务请求。然后通过transact将处理请求传给bn(通过binder)。其接口如下所示:
class BpMediaRecorder: public BpInterface
{
BpMediaRecorder(const sp& impl) : BpInterface(impl) {}
status_t setCamera(const sp& camera);
status_t setPreviewSurface(const sp& surface);
status_t init();
status_t setVideoSource(int vs);
status_t setAudioSource(int as);
status_t setOutputFormat(int of);
status_t setAudioEncoder(int ae);
status_t setOutputFile(const char* path);
status_t prepare();
status_t getMaxAmplitude(int* max);
…………………………
}
上面的每个函数中都用transact方法来向bn发出请求。然后调用return reply.readInt32();将从bn返回的数据传送个他们的调用函数。
2、Mediarecorder.cpp
Bn的实现是在Mediarecorder.cpp文件中。BN是用来处理bp的请求,当bn将数将处理完后将数据通过transact传给回bp(通过binder)。MediaRecorder.cpp文件的实现方法与ImediaRecorder,cpp对应,主要是用来接收ImediaRecorder发送过来的请求。
MediaRecorder::MediaRecorder()
{ LOGV("constructor");
sp sm = defaultServiceManager();
sp binder;
do {
binder = sm->getService(String16("media.player"));
if (binder != NULL) {
break;
}
usleep(500000); // 0.5 s
} while(true);
sp service = interface_cast(binder);
if (service != NULL) {
mMediaRecorder = service->createMediaRecorder(getpid());
}
if (mMediaRecorder != NULL) {
mCurrentState = MEDIA_RECORDER_IDLE;
}
doCleanUp();
}
该文件操作的方法是mMediaRecorder的方法,它主要是同过binder机制将请求传输送给mediarecorder的服务进程。
3、多媒体服务部分
mediaRecorder的服务文件是MediaRecorderClient.cpp,它主要调用的是PVMediaRecorder的实现方法,在此请求opencore的服务。
MediaRecorderClient::MediaRecorderClient(pid_t pid)
{
LOGV("Client constructor");
mPid = pid;
mRecorder = new PVMediaRecorder();
}