android MediaPlayer NuPlayer以及Android MediaPlayerService解析

MediaPlayer


通常MediaPlayer的调用逻辑是,构造函数-> setDataSource -> SetVideoSurfaceTexture-> prepare/prepareAsync -> start-> stop-> reset-> 析构函数,按照实际需求还会调用pause、isPlaying、getDuration、getCurrentPosition、setLooping、seekTo等方法。


1、 MediaPlayer的状态图
Idle状态
调用new或reset()方法创建MediaPlayer后进入空闲
End状态
调用release()后就结束
Error状态
播放控制操作出错或无效状态下调用播放控制操作
Initialized状态
调用setDataSource之后完成初始化
Prepared状态
同步prepare()或异步prepareAsync()完成准备
Preparing状态
是一种瞬时状态,调用prepareAsync()时会先进入此状态
Started 状态
要开始播放必须调用start()
Paused 状态
调用pause()并成功返回后播放可以被暂停
Stopped状态
调用stop()会停止播放
PlaybackCompleted状态
当播放到达流末端时,播放完成


2、 MediaPlayer实例的获取
用new直接创建
MediaPlayer mp = new MediaPlayer();
用create创建,这种方法不用再调用setDataSource
MediaPlayer mp = MediaPlayer.create(this, R.raw.test);


3、 MediaPlayer和MediaPlayerService
3.1、MediaPlayerService服务
mediaserver 启动后会把media相关一些服务添加到servicemanager中,其中就有mediaPlayerService。这样应用启动前,系统就有了mediaPlayerService这个服务程序。【Main_mediaserver.cpp】

3.2、创建MediaPlayer
Java应用程序中创建MediaPlayer对象 MediaPlayer mediaPlayer = new MediaPlayer();
MediaPlayer的构造函数中比较重要的就是本地的native函数:native_setup ,其对应的函数为
android_media_MediaPlayer_native_setup 

构造Native层的MediaPlayer对象的时候【MediaPlayer.cpp】,也会构造其父类的对象。在MediaPlayer的父类IMediaDeathNotifier中有个很重要的方法getMediaPlayerService()来获取MediaPlayerService,其关系到MediaPlayer和MediaPlayerService之间的通信。



3.3、setDataSource设置播放资源

在整个应用程序的进程中,Mediaplayer.cpp 中 setDataSource会从service manager中获得mediaPlayerService 服务,然后通过服务来创建player,这个player就是播放器的真实实例,同时也使MediaPlayer和MediaPlayerService建立了联系。
在java层MediaPlayer.java中的setDataSource最终会调用_setDataSource方法,对应native层MediaPlayer.cpp中的setDataSource方法。
          

通过 getMediaPlayerService 得到的BpMediaPlayerService类型的service,和mediaPlayerService进程中的BnMediaPlayerService 相对应负责binder通讯。

                     

在create函数中创建了一个MediaPlayerService::Client的实例,是MediaPlayerService的内部类,也就是说MediaPlayerService会为每个client应用进程创建一个相应的MediaPlayerService::Client的实例,来实现播放以及播放过程的控制,向MediaPlayer发事件通知。到这里,在Server端的对象就创建完成了。

    然后在MediaPlayer.cpp中就得到了一个sever端的player实例,它和本地其他类的实例没什么用法上的区别,而实际上则是通过binder机制运行在另外一个进程中的。获得此实例后继续player->setDataSource操作。


总结:Java应用程序中使用MediaPlayer.java的setDataSource()会传递到Native层中MediaPlayer.cpp的setDataSource()去执行,而MediaPlayer.cpp又会把这个方法交给MediaPlayerservice去执行。MediaPlayerService则是使用NuPlayer实现的,最后, setDataSource还是交给了NuPlayer去执行了。这个过程把MediaPlayer和MediaPlayerService之间的联系建立起来,同时又把MediaPlayerService和NuPlayer的关系建立了起来。



NuPlayer

NuPlayer由NuPlayerDriver封装,利用了底层的ALooper/AHandler机制来异步地处理请求,ALooper保存消息请求,然后在AHandler中处理。另外,NuPlayer中利用到了Acodec。


1、整体框架图
 
其中的几个部分:
NuPlayer::Source 解析模块(parser,功能类似FFmpeg的avformat)。其接口与MediaExtractor和
MediaSource组合的接口差不多,同时提供了用于快速定位的seekTo接口。
NuPlayer::Decoder 解码模块(decoder,功能类似FFmpeg的avcodec),封装了用于AVC、AAC解码的接口,
通过ACodec实现解码(包含OMX硬解码和软解码)。
NuPlayer::Render 渲染模块(render,功能类似声卡驱动和显卡驱动),主要用于音视频渲染和同步,与
NativeWindow有关。
NuPlayer 是播放框架中连接Source、Decoder、Renderer的纽带
NuPlayerDriver 作为NuPlayer类的封装,直接调用NuPlayer。


2、ALooper/AHandler机制

NuPlayer本身继承自AHandler类,而ALooper对象保存在NuPlayerDriver中。ALooper/AHandler机制是一种消息循环处理方式,通常有三个主要部分:消息(message,通常包含Handler)、消息队列(queue)、消息处理线程(looperthread)。此机制会将变量封装到一个消息AMessage结构体中,然后放到队列中去,后台专门有一个线程会从这个队列中取出消息然后通过函数onMessageReceived执行。

2.1、AHandler

是消息处理类的父类,基本上只有一个onMessageReceived用于子类继承,deliverMessage用于给类AMessage使用,setID用于给友元类ALooperRoster使用(消息的发送和取出都是调用辅助类ALooperRoster完成的)。

2.2、AMessage

    其是消息的载体,在使用AMessage时只需要指定消息类别和要处理该消息的AHandler即可,可以通过构造函数创建,也可以单独调用setWhat和setTarget接口来设置。AMessage构造完成之后,可以调用setXXX设置对应的参数,通过findXXX获取传递的参数。最后通过post即可将消息投递到AHandler的消息队列中。

2.3、ALooper及后台线程

是消息处理循环,其调用逻辑是先创建一个ALooper对象,然后调用setName和start接口,之后调用registerHandler设置一个AHandler,这样就完成了初始化。在析构之前需要调用stop接口。

2.4、例子

2.5、总结

总的来说整个消息的处理过程就是:在ALoop中的ALooper::start接口会启动一个线程LooperThread,并调用ALooper::loop函数来完成消息的实际执行。而消息是由AMessage通过调用ALooper::post接口,将AMessage添加到消息队列中的。ALooper中存在的后台线程线程LooperThread维护着这个消息队列,线程函数不断从这个队列中取出消息执行。其流程如下图所示:


frameworks/av/media/libmediaplayerservice/MediaPlayerService.h

MediaPlayerService 类的继承关系如下:
这里写图片描述

Client 和 AudioOutput 是 MediaPlayerService的内部类
IMediaPlayerService是对为提供的接口类, 定义如下:

frameworks/av/include/media/IMediaPlayerService.h
43class IMediaPlayerService: public IInterface
44{
45public:
46    DECLARE_META_INTERFACE(MediaPlayerService);
47
48    virtual sp<IMediaRecorder> createMediaRecorder(const String16 &opPackageName) = 0;
49    virtual sp<IMediaMetadataRetriever> createMetadataRetriever() = 0;
50    virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
51            audio_session_t audioSessionId = AUDIO_SESSION_ALLOCATE) = 0;
52    virtual sp<IOMX>            getOMX() = 0;
53    virtual sp<IHDCP>           makeHDCP(bool createEncryptionModule) = 0;
54    virtual sp<IMediaCodecList> getCodecList() const = 0;
55
56    // Connects to a remote display.
57    // 'iface' specifies the address of the local interface on which to listen for
58    // a connection from the remote display as an ip address and port number
59    // of the form "x.x.x.x:y".  The media server should call back into the provided remote
60    // display client when display connection, disconnection or errors occur.
61    // The assumption is that at most one remote display will be connected to the
62    // provided interface at a time.
63    virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
64            const sp<IRemoteDisplayClient>& client, const String8& iface) = 0;
65
66    // codecs and audio devices usage tracking for the battery app
67    enum BatteryDataBits {
68        // tracking audio codec
69        kBatteryDataTrackAudio          = 0x1,
70        // tracking video codec
71        kBatteryDataTrackVideo          = 0x2,
72        // codec is started, otherwise codec is paused
73        kBatteryDataCodecStarted        = 0x4,
74        // tracking decoder (for media player),
75        // otherwise tracking encoder (for media recorder)
76        kBatteryDataTrackDecoder        = 0x8,
77        // start to play an audio on an audio device
78        kBatteryDataAudioFlingerStart   = 0x10,
79        // stop/pause the audio playback
80        kBatteryDataAudioFlingerStop    = 0x20,
81        // audio is rounted to speaker
82        kBatteryDataSpeakerOn           = 0x40,
83        // audio is rounted to devices other than speaker
84        kBatteryDataOtherAudioDeviceOn  = 0x80,
85    };
86
87    virtual void addBatteryData(uint32_t params) = 0;
88    virtual status_t pullBatteryData(Parcel* reply) = 0;
89};
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

MediaPlayerService 是native系统服务, 通过ServiceManager注册到系统中

frameworks/av/media/mediaserver/main_mediaserver.cpp
.....
38    sp<ProcessState> proc(ProcessState::self());
39    sp<IServiceManager> sm(defaultServiceManager());
40    ALOGI("ServiceManager: %p", sm.get());
41    InitializeIcuOrDie();
42    MediaPlayerService::instantiate();
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

instantiate() 创建MediaPlayerService并注册到系统服务中

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
267void MediaPlayerService::instantiate() {
268    defaultServiceManager()->addService(
269            String16("media.player"), new MediaPlayerService());
270}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

MediaPlayerService构造函数如下:

272MediaPlayerService::MediaPlayerService()
273{
274    ALOGV("MediaPlayerService created");
275    mNextConnId = 1;
276
277    mBatteryAudio.refCount = 0;
278    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
279        mBatteryAudio.deviceOn[i] = 0;
280        mBatteryAudio.lastTime[i] = 0;
281        mBatteryAudio.totalTime[i] = 0;
282    }
283    // speaker is on by default
284    mBatteryAudio.deviceOn[SPEAKER] = 1;
285
286    // reset battery stats
287    // if the mediaserver has crashed, battery stats could be left
288    // in bad state, reset the state upon service start.
289    BatteryNotifier::getInstance().noteResetVideo();
290    //register built-in player
291    MediaPlayerFactory::registerBuiltinFactories();
292}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

registerBuiltinFactories() register the NU_PLAYER and TEST_PLAYER

243void MediaPlayerFactory::registerBuiltinFactories() {
244    Mutex::Autolock lock_(&sLock);
245
246    if (sInitComplete)
247        return;
248
249    registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
250    registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
251
252    sInitComplete = true;
253}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

createMediaRecorder() 创建Recorder用于录音

299sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName)
300{
301    pid_t pid = IPCThreadState::self()->getCallingPid();
302    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);
303    wp<MediaRecorderClient> w = recorder;
304    Mutex::Autolock lock(mLock);
305    mMediaRecorderClients.add(w);
306    ALOGV("Create new media recorder client from pid %d", pid);
307    return recorder;
308}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

创建Client主要用于播放

325sp<IMediaPlayer> MediaPlayerService::create(const sp<IMediaPlayerClient>& client,
326        audio_session_t audioSessionId)
327{
328    pid_t pid = IPCThreadState::self()->getCallingPid();
329    int32_t connId = android_atomic_inc(&mNextConnId);
330
331    sp<Client> c = new Client(
332            this, pid, connId, client, audioSessionId,
333            IPCThreadState::self()->getCallingUid());
334
335    ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
336         IPCThreadState::self()->getCallingUid());
337
338    wp<Client> w = c;
339    {
340        Mutex::Autolock lock(mLock);
341        mClients.add(w);
342    }
343    return c;
344}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
567MediaPlayerService::Client::Client(
568        const sp<MediaPlayerService>& service, pid_t pid,
569        int32_t connId, const sp<IMediaPlayerClient>& client,
570        audio_session_t audioSessionId, uid_t uid)
571{
572    ALOGV("Client(%d) constructor", connId);
573    mPid = pid;
574    mConnId = connId;
575    mService = service;
576    mClient = client;
577    mLoop = false;
578    mStatus = NO_INIT;
579    mAudioSessionId = audioSessionId;
580    mUID = uid;
581    mRetransmitEndpointValid = false;
582    mAudioAttributes = NULL;
583
584#if CALLBACK_ANTAGONIZER
585    ALOGD("create Antagonizer");
586    mAntagonizer = new Antagonizer(notify, this);
587#endif
588}
  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
      <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
              </div>

frameworks/av/media/libmediaplayerservice/MediaPlayerService.h

猜你喜欢

转载自blog.csdn.net/shanshenyuyou/article/details/90520139