b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

stagefrightrecorder_voice recorder安卓_stagefright漏洞修复

电脑杂谈  发布时间:2017-05-31 01:03:30  来源:网络整理

在Android中录制音频有两种方式,MediaRecorder和AudioRecord。两者的区别如下:

(1)MediaRecorder

简单方便,不需要理会中间录制过程,结束录制后可以直接得到音频文件进行播放;录制的音频文件是经过压缩的,需要设置编码器;录制的音频文件可以用系统自带的播放器播放。

(2)AudioRecorder

在声音录制过程中,可以处理采集的声音数据,如降噪、合成等。过程为一段一段进行录制然后得到数据分别进行处理。录制的是PCM式的音频文件,需要用AudioTrack来播放,AudioTrack更接近底层。

本文主要详解MediaRecorder架构,从上层调到StagefrightRecorder的流程以及应用层录音接口调用的流程。(注:本次分析基于android4.4.2源码)

2.应用层录音接口调用流程

(1)调用new MediaRecorder()构造函数得到实例。

(2)调用setOutputFormat()设定媒体文件的输出式。

(3)调用setAudioSource()设定音频的录入源以及调用setAudioEncoder()设定音频的编码方式。

(4)调用setOutputFile()设定记录的媒体文件保存的路径。

(5)调用prepare()准备录制。

(6)调用start()开始录制。

(7)记录完成后,调用stop()停止录制。

3.应用层调到StagefrightRecorder的流程

如图1所示,MediaRecorder在运行时,可以分成Client和Server两个部分,它们分别在两个进程中运行,它们之间使用Binder机制实现IPC通讯。stagefrightrecorder

图1 录音从Java层调到StagefrightRecorder的流程图

(1)手机启动时会启动进程/system/bin/mediaserver。该进程会把media相关服务注册到ServiceManager中,如MediaPlayerService。

(/frameworks/av/media/mediaserver/main_mediaserver.cpp)

(/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp)

204<spanstyle="white-space:pre"></span>voidMediaPlayerService::instantiate(){

205<spanstyle="white-space:pre"></span>defaultServiceManager()->addService(

206<spanstyle="white-space:pre"></span>String16("media.player"),newMediaPlayerService());

207<spanstyle="white-space:pre"></span>}

(2)应用层创建MediaRecorder实例:mMediaRecorder = new MediaRecorder(); 调用SDK中MediaRecorder.java

(frameworks\base\media\java\android\media\MediaRecorder.java)

98publicMediaRecorder(){

99

100Looperlooper;

101if((looper=Looper.myLooper())!=null){

102mEventHandler=newEventHandler(this,looper);

103}elseif((looper=Looper.getMainLooper())!=null){

104mEventHandler=newEventHandler(this,looper);

105}else{

106mEventHandler=null;

107}

108

109StringpackageName=ActivityThread.currentPackageName();

110/*Nativesetuprequiresaweakreferencetoourobject.

111*It'seasiertocreateitherethaninC.

112*/

113native_setup(newWeakReference<MediaRecorder>(this),packageName);

114}

通过JNI方式调用到framework层android_media_MediaRecorder.cpp。

(\frameworks\base\media\jni\android_media_MediaRecorder.cpp)

418staticvoid

419android_media_MediaRecorder_native_setup(JNIEnv*env,jobjectthiz,jobjectweak_this,

420jstringpackageName)

421{

422ALOGV("setup");

423

424sp<MediaRecorder>mr=newMediaRecorder();

425if(mr==NULL){

426jniThrowException(env,"java/lang/RuntimeException","Outofmemory");

427return;

428}

429if(mr->initCheck()!=NO_ERROR){

430jniThrowException(env,"java/lang/RuntimeException","Unabletoinitializemediarecorder");

431return;

432}

433

434//createnewlistenerandgiveittoMediaRecorder

435sp<JNIMediaRecorderListener>listener=newJNIMediaRecorderListener(env,thiz,weak_this);

436mr->setListener(listener);

437

438//ConvertclientnamejstringtoString16

439constchar16_t*rawClientName=env->GetStringChars(packageName,NULL);

440jsizerawClientNameLen=env->GetStringLength(packageName);

441String16clientName(rawClientName,rawClientNameLen);

442env->ReleaseStringChars(packageName,rawClientName);

443

444//passclientpackagenameforpermissionstracking

445mr->setClientName(clientName);

446

447setMediaRecorder(env,thiz,mr);

448}

(3)继而调用mediarecorder.cpp的构造函数,它首先会从ServiceManager中获得MediaPlayerService服务,然后通过服务来创建recorder。这个recorder就是录音的真实实例。

(frameworks\av\media\libmedia\mediarecorder.cpp)

617MediaRecorder::MediaRecorder():mSuceMediaSource(NULL)

618{

619ALOGV("constructor");

620

621constsp<IMediaPlayerService>&service(getMediaPlayerService());

622if(service!=NULL){

623mMediaRecorder=service->createMediaRecorder();

624}

625if(mMediaRecorder!=NULL){

626mCurrentState=MEDIA_RECORDER_IDLE;

627}

628

629

630doCleanUp();

631}

(4)通过getMediaPlayerService得到的service其实是BpMediaPlayerService,它和mediaserver进程中的BnMediaPlayerService是相对应的,共同负责进程间binder通信。BpMediaPlayerService中的createMediaRecorder其实是通过binder机制将CREATE_MEDIA_RECORDER消息发送出去。

(/frameworks/av/media/libmedia/IMediaPlayerService.cpp)

81virtualsp<IMediaRecorder>createMediaRecorder()

82{

8arceldata,reply;

84data.writeInteceToken(IMediaPlayerService::getInteceDescriptor());

85remote()->transact(CREATE_MEDIA_RECORDER,data,&reply);

86returnintece_cast<IMediaRecorder>(reply.readStrongBinder());

87}

(5)在BnMediaPlayerService中,通过onTransact()来处理接收到的消息,并返回结果。当接收消息中的code为CREATE_MEDIA_RECORDER时,调用MediaPlayerService 中的createMediaRecorder函数。在该函数中创建了一个MediaRecorderClient的实例,也就是说MediaPlayerService会为每个client应用进程创建一个相应的MediaRecorderClient的实例,来提供服务。

(/frameworks/av/media/libmedia/IMediaPlayerService.cpp)

210status_tBnMediaPlayerService::onTransact(

211uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)

212{

213switch(code){

214caseCREATE:{

stagefrightrecorder_voice recorder安卓_stagefright漏洞修复

215CHECK_INTERFACE(IMediaPlayerService,data,reply);

216sp<IMediaPlayerClient>client=

217intece_cast<IMediaPlayerClient>(data.readStrongBinder());

218intaudioSessionId=data.readInt32();

219sp<IMediaPlayer>player=create(client,audioSessionId);

220reply->writeStrongBinder(player->asBinder());

221returnNO_ERROR;

222}break;

262caseCREATE_MEDIA_RECORDER:{

263CHECK_INTERFACE(IMediaPlayerService,data,reply);

264sp<IMediaRecorder>recorder=createMediaRecorder();

265reply->writeStrongBinder(recorder->asBinder());

266returnNO_ERROR;

267}break;

337default:

338returnBBinder::onTransact(code,data,reply,flags);

339}

340}

(/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp)

231sp<IMediaRecorder> MediaPlayerService::createMediaRecorder()232{233 pid_t pid = IPCThreadState::self()->getCallingPid();234 sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);235 wp<MediaRecorderClient> w = recorder;236 Mutex::Autolock lock(mLock);237 mMediaRecorderClients.add(w);238 ALOGV("Create new media recorder client from pid %d", pid);239 return recorder;240}

(6)如此MediaRecorder.cpp就得到了一个recorder的实例,对它来说这个实例和本地的其他类的实例没什么用法上的区别,但其实这个实例是运行在另外一个进程中。实现这种假象的就是binder机制。在MediaRecorderClient的构造函数中,才会真正的创建StagefrightRecorder的具体实例,即真正的录制对象,使用的StageFright多媒体框架。在android 4.0以后只有StagefrightRecorder一个录制框架。stagefrightrecorder在2.2、2.3中还存在另外一个录制对象PVMediaRecorder,使用的是OpenCore框架实现录音或录像。

(/frameworks/av/media/libmediaplayerservice/MediaRecorderClient.cpp)

303MediaRecorderClient::MediaRecorderClient(constsp<MediaPlayerService>&service,pid_tpid)

304{

305ALOGV("Clientconstructor");

306mPid=pid;

307mRecorder=newStagefrightRecorder;

308mMediaPlayerService=service;

309}

图2是录音创建实例的时序图

图2 录音创建实例的时序图

4.Application Framework层与libraries层录音函数对应关系

mMediaRecorder = new MediaRecorder();

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

mMediaRecorder.setOutputFile(recordFile.getAbsolutePath());

mMediaRecorder.prepare();

mMediaRecorder.start();

mMediaRecorder.stop();

mMediaRecorder.release();

sp<MediaRecorder> mr = newMediaRecorder();

mr->setAudioSource(1); //MIC = 1

mr->setOutputFormat(0); //DEFAULT = 0;

mr->setAudioEncoder(0);//DEFAULT = 0;

mr->setOutputFile(fos.getFD(), 0, 0);

mr->prepare();

mr->start();

mr->stop();

mr->release();

5.总结

通过对androidmediarecorder架构的详解,了解各模块调用的流程,不仅可以实现在应用层调用录音接口进行录音,还能直接调用libraries层录音接口函数进行C层录音。同时,若需要监控录音,则可以Hook系统进程/system/bin/mediaserver的ioctl函数,从而拦截该进程的binder通信过程,通过解析binder通信数据包,就可以监控到手机中所有录音软件的录音行为。

6.参考资料


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-50207-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...