Android Camera fw学习(四)-recording流程分析

Android Camera fw学习(四)-recording流程分析 
备注:备注:本文是Android5.1学习笔记。博文按照软件启动流程分析。 
  且行且惜,一步一个脚印,这次学习camera Video.虽然标题是recording流程分析,但这里很多和preview是相似的(包含更新,创建Stream,创建Request),这里主要分析MediaRecorder对象创建、video帧监听对象注册、帧可用事件以及一系列callback流程分析。

一、认识video(mediaRecorder)状态机

 

Android Camera fw学习(四)-recording流程分析

 

Used to record audio and video. The recording control is based on a 
simple state machine (see below).状态机请看上面源码中给的流程图。 
A common case of using MediaRecorder to record audio works as follows: 
1.MediaRecorder recorder = new MediaRecorder(); 
2.recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
3.recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
4.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
5.recorder.setOutputFile(PATH_NAME); 
6.recorder.prepare(); 
7.recorder.start(); // Recording is now started 
8…. 
9.recorder.stop(); 
10.recorder.reset(); // You can reuse the object by going back to setAudioSource() step 
recorder.release(); // Now the object cannot be reused 
Applications may want to register for informational and error 
events in order to be informed of some internal update and possible 
runtime errors during recording. Registration for such events is 
done by setting the appropriate listeners (via calls 
(to {@link #setOnInfoListener(OnInfoListener)}setOnInfoListener and/or 
{@link #setOnErrorListener(OnErrorListener)}setOnErrorListener). 
In order to receive the respective callback associated with these listeners, 
applications are required to create MediaRecorder objects on threads with a 
Looper running (the main UI thread by default already has a Looper running).

上面是googole工程师加的注释,最权威的资料。大概意思就是说“使用mediaRecorder记录音视频,需要一个简单的状态机来控制”。上面的1,2,3…就是在操作时需要准守的步骤。算了吧,翻译水平有限,重点还是放到camera这边吧。

二、Camera app如何启动录像

可以看到应用启动录像功能是是符合状态机流程的。在应用开发中,也要这样来做。

  • 1.创建mediaRecorderjava对象,mRecorder = new MediaRecorder();
  • 2.设置camera java对象到mediaRecorder中,mRecorder.setCamera(mCamera);
  • 3.将preview surface对象设置给mediaRecorder,mRecorder.setPreviewDisplay(mPreviewHolder.getSurface());
  • 4.设置音频源,mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
  • 5.设置视频源,mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  • 6.设置录像帧大小和帧率,以及setOutputFile
  • 8.准备工作,mRecorder.prepare();
  • 9.启动mdiaRecorder,mRecorder.start();

三、与MediaPlayerService相关的类接口之间的关系简介

1.mediaRecorder何时与MediaPlayerService发送关系

 

Android Camera fw学习(四)-recording流程分析

 

  在jni中创建mediaRecorder对象时,其实在构造函数中偷偷的链接了mediaPlayerService,这也是Android习惯用的方法。获取到MediaPlayerService代理对象后,通过匿名binder获取mediaRecorder代理对象。 
frameworks/base/media/java/android/media/MediaRecorder.java

2.mediaPlayerService类和接口之间关系

 

Android Camera fw学习(四)-recording流程分析

 

接口简单介绍-都是通过mediaPlayerService代理对象获取匿名mediaRecorder和mediaPlayer

接口类型 接口说明
virtual sp createMediaRecorder() = 0; 创建mediaRecorder录视频服务对象的接口
virtual sp create(const sp& client, int audioSessionId = 0) = 0; 创建mediaPlayer播放音乐服务对象的接口,播放音乐都是通过mediaPlayer对象播放的
virtual status_t decode() = 0; 音频解码器
   

3.MediaRecorder类和接口之间关系

 

Android Camera fw学习(四)-recording流程分析

 

mediaRecorder功能就是来录像的。其中MediaRecorder类中,包含了BpMediaRecorder代理对象引用。MediaRecorderClient本地对象驻留在mediaPlayService中。它的接口比较多,这里就列出我们今天关注的几个接口。其它接口查看源码吧 
详细介绍可以参考源码:frameworks/av/include/media/IMediaRecorder.h

接口类型 接口说明
virtual status_t setCamera(const sp& camera,const sp& proxy) = 0; 这个接口也是非常需要我们关注的,这里获取到了启动录像操作的本地对象(BnCameraRecordingProxy),并通过匿名binder通信方式,第二个参数就是本地对象.然后在startRecording时将帧监听对象注册到camera本地对象中了
virtual status_t setPreviewSurface(const sp& surface) = 0; 将preview预览surface对象设置给medaiRecorder,因为mediaRecorder也有一个camera本地client,所以这个surface对象最终还是会设置到cameraService用于显示。而录像的帧会在CameraService本地创建一个bufferQueue,具体下面会详细说明
virtual status_t setListener(const sp& listener) = 0; 这里一看就是设置监听对象,监听对象是jni中的JNIMediaRecorderListener对象,该对象可以回调MediaRecorder.java类中的postEventFromNative方法,将时间送到java层。其实MediaRecorder实现了BnMediaRecorderClient接口,即实现notify接口,那么这里其实将本地对象传到MediaRecorder本地的客户端对象中(本地对象拿到的就是代理对象了),参考代码片段1
virtual status_t start() = 0; 启动录像功能,函数追究下去和Camera关系不大了,这里就不细说了
1)代码片段1

mediaRecorder jni接口回调java方法,通知上层native事件。

2)代码片段2
3)代码片段3-setCamera本地实现

  最终ICamera,ICameraRecordingProxy代理对象都存放到StagefrightRecorder对应的成员变量中,看来猪脚就在这个类中。

4)代码片段4

  由上面的类图之间的关系的,就知道mediaRecorder间接包含了cameaSource对象,这里为了简单直接要害代码。

  • 1.在创建CameraSource对象时,会去检查一下Camera对象是否可用,可用的话就会根据传进来的代理对象重新创建Camera本地对象(注意这个时候Camera代理对象在mediaRecorder中)
  • 2.然后保存RecordingProxy代理对象到mCameraRecordingProxy成员中,然后绑定死亡通知对象到RecordingProxy代理对象。
5)代码片段5

来源:weixin_34109408

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年4月11日
下一篇 2018年4月11日

相关推荐