Android4.2.2多媒体架构MediaPlay的创建过程分析(一)

 

        Android4.2.2多媒体架构MediaPlay的创建过程分析(一)       

 

来自:http://blog.csdn.net/gzzaigcnforever/article/details/26344413

分类:            我心所向之Android4.2.2多媒体、视频采集与显示android源码 351人阅读 评论(0) 收藏 举报

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

欢迎和大家交流。qq:1037701636 email:gzzaigcn2012@gmail.com

Android源码版本Version:4.2.2; 硬件平台 全志A31

前沿:
回首往事,记得2012年的时候,那时还年少不知,就研究过android的多媒体框架,那时还是2.3的源码,看过stagefright的源码,记得当时是特别的痛苦。而今,再次看起这个多媒体模块的代码,突然间觉得豁然开朗,模块间的层次清晰,有据可依,遇到的疑问往往都能迎刃而解。我想,也许这就是2年多来的进步与经验吧。感谢时间,让我学会了成才。
邓凡平老师告诉我:无论何时进入互联网都不算迟,的确站在巨人的肩膀上再次重新梳理旧的东西,还是能学习的更多更深。

接下去的一段时间,打算主攻android多媒体框架、camera架构、surfaceflinger等FrameWork层,HAL层的模块以及相关的Android系统定制与类平板的开发,更底层是linux内核中的视频采集与显示驱动等来作为接下去寻找工作的重中之重。自我感觉在移动互联以及嵌入式的世界里,这几个方面现在应该还都是不可欠缺的。

Android的多媒体框架熟悉的人很熟悉,像我等菜鸟,就只能慢慢的啃了。这里以4.2.2的源码为背景,记录下我所熟悉的多媒体框架的核心模块,以便以后使用。

多媒体框架在android中的功能主要体现杂音视频的播放以及录制等,前者对应着解码,后者对应着编码。Android中以一个MediaPlay类作为音视频播放的基础类,围绕着他开展了一系列的处理。学习一个新的模块,最简单的步骤就是找到一个典型的应用程序,通过它的实现,来分析整个模块的数据流和控制流。如SurfaceFlinger的研究可以以Bootanmation的启动来学习。典型的MediaPlay在Java处的接口包括视频播放类VideoView以及音频专用MediaPlay类。

1.APP闪的VideoView类,其实质是用MediaPlay类来实现的,只是由于其是视频播放,不得不和surfaceview挂上够,才将其独立出来。使得其有如下的结构:

  1. public class VideoView extends SurfaceView implements MediaPlayerControl { 
  2.     private String TAG = "VideoView"
  3.     // settable by the client 
  4.     private Uri         mUri; 
  5.     private Map<String, String> mHeaders; 
public class VideoView extends SurfaceView implements MediaPlayerControl {
    private String TAG = "VideoView";
    // settable by the client
    private Uri         mUri;
    private Map<String, String> mHeaders;

在APP中,VideoView的典型简单使用如下:

  1.               video = (VideoView) findViewById(R.id.videoView1);     
  2. mediacontroller =new MediaController(this); 
  3. video.setVideoPath(Video_fd); 
  4. mediacontroller.setAnchorView(video);        //控件和视频绑定 
  5. video.setMediaController(mediacontroller);  //设置视频播放的控制器 
  6. video.start(); 
                video = (VideoView) findViewById(R.id.videoView1);	
		mediacontroller =new MediaController(this);
		video.setVideoPath(Video_fd);
		mediacontroller.setAnchorView(video);        //控件和视频绑定
		video.setMediaController(mediacontroller);  //设置视频播放的控制器
		video.start();

通过setVideoPath的API处理,依次进行如下的调用:

  1. public void setVideoPath(String path) { 
  2.       setVideoURI(Uri.parse(path)); 
  3.   } 
  4.  
  5.   public void setVideoURI(Uri uri) { 
  6.       setVideoURI(uri, null); 
  7.   } 
  8.  
  9.   /**
  10.    * @hide
  11.    */ 
  12.   public void setVideoURI(Uri uri, Map<String, String> headers) { 
  13.       mUri = uri; 
  14.       mHeaders = headers; 
  15.       mSeekWhenPrepared = 0
  16.       openVideo(); 
  17.       requestLayout(); 
  18.       invalidate(); 
  19.   } 
  public void setVideoPath(String path) {
        setVideoURI(Uri.parse(path));
    }

    public void setVideoURI(Uri uri) {
        setVideoURI(uri, null);
    }

    /**
     * @hide
     */
    public void setVideoURI(Uri uri, Map<String, String> headers) {
        mUri = uri;
        mHeaders = headers;
        mSeekWhenPrepared = 0;
        openVideo();
        requestLayout();
        invalidate();
    }

openVideo的处理,让最终的处理权交给了MediaPlayer。

  1.     private void openVideo() { 
  2.         if (mUri == null || mSurfaceHolder == null) { 
  3.             // not ready for playback just yet, will try again later 
  4.             return
  5.         } 
  6.         // Tell the music playback service to pause 
  7.         // TODO: these constants need to be published somewhere in the framework. 
  8.         Intent i = new Intent("com.android.music.musicservicecommand"); 
  9.         i.putExtra("command", "pause"); 
  10.         mContext.sendBroadcast(i); 
  11.  
  12.         // we shouldn't clear the target state, because somebody might have 
  13.         // called start() previously 
  14.         release(false); 
  15.         try
  16.             mMediaPlayer = new MediaPlayer(); 
  17. ...... 
  18.             */ 
  19.             mMediaPlayer.setDataSource(mContext, mUri, mHeaders); 
  20. ......... 
    private void openVideo() {
        if (mUri == null || mSurfaceHolder == null) {
            // not ready for playback just yet, will try again later
            return;
        }
        // Tell the music playback service to pause
        // TODO: these constants need to be published somewhere in the framework.
        Intent i = new Intent("com.android.music.musicservicecommand");
        i.putExtra("command", "pause");
        mContext.sendBroadcast(i);

        // we shouldn't clear the target state, because somebody might have
        // called start() previously
        release(false);
        try {
            mMediaPlayer = new MediaPlayer();
......
			*/
            mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
.........
}

上述的两个架构,在音频播放的APP调用更加紧密,如下所示:

  1. mediaplayer = new MediaPlayer(); 
  2. mediaplayer.setDataSource(Music_fd);  //设置要播放的音频文件 
  3. mediaplayer.prepare();  
  4. mediaplayer.seekTo(0); 
		mediaplayer = new MediaPlayer();
		mediaplayer.setDataSource(Music_fd);  //设置要播放的音频文件
		mediaplayer.prepare(); 
		mediaplayer.seekTo(0);

到这里基本的音视频框架在APP中的调用就基本完成了。

2.进入MediaPlay的世界

2.1 首先关注MediaPlay的对象创建过程,这也是分析android源码的一个基本要求。依次通过java,JNI(libmedia_jni.so)进入Framework(libmedia.so)的处理流程。

new VideoView——> new MediaPlay ——>native_setup:典型的一个对象的建立,并传统到JNI。native_setup主要用于本地C++层的对象的建立

进入JNI做android_media_MediaPlayer_native_setup处理,使得最终进入C++的世界。

  1. android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this) 
  2.     ALOGV("native_setup"); 
  3.     sp<MediaPlayer> mp = new MediaPlayer(); 
  4.     if (mp == NULL) { 
  5.         jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); 
  6.         return
  7.     } 
  8.  
  9.     // create new listener and give it to MediaPlayer 
  10.     sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this); 
  11.     mp->setListener(listener); 
  12.  
  13.     // Stow our new C++ MediaPlayer in an opaque field in the Java object. 
  14.     setMediaPlayer(env, thiz, mp); 
android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
{
    ALOGV("native_setup");
    sp<MediaPlayer> mp = new MediaPlayer();
    if (mp == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
        return;
    }

    // create new listener and give it to MediaPlayer
    sp<JNIMediaPlayerListener> listener = new JNIMediaPlayerListener(env, thiz, weak_this);
    mp->setListener(listener);

    // Stow our new C++ MediaPlayer in an opaque field in the Java object.
    setMediaPlayer(env, thiz, mp);
}

好了,到此为止,真正的建立了一个所谓native处的MediaPlayer对象。当然java处也有这个对象类。

2.2 setDataSource

MediaPlay的C++代码位于/home/A31_Android4.2.2/android/frameworks/av/media/libmedia下形成一个libmedia.so。

下面来看这个API的处理,接下去都只分析FW层的C++的处理流,java的流和上面的分析类似。

  1. status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length) 
  2.     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 
  3.     status_t err = UNKNOWN_ERROR; 
  4.     const sp<IMediaPlayerService>& service(getMediaPlayerService()); 
  5.     if (service != 0) { 
  6.         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));//返回一个Bpmediaplayer 
  7.         if ((NO_ERROR != doSetRetransmitEndpoint(player)) || 
  8.             (NO_ERROR != player->setDataSource(fd, offset, length))) {//设置视频源 
  9.             player.clear(); 
  10.         } 
  11.         err = attachNewPlayer(player); 
  12.     } 
  13.     return err; 
status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
    ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
    status_t err = UNKNOWN_ERROR;
    const sp<IMediaPlayerService>& service(getMediaPlayerService());
    if (service != 0) {
        sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));//返回一个Bpmediaplayer
        if ((NO_ERROR != doSetRetransmitEndpoint(player)) ||
            (NO_ERROR != player->setDataSource(fd, offset, length))) {//设置视频源
            player.clear();
        }
        err = attachNewPlayer(player);
    }
    return err;
}

典型的Binder C/S架构,获取MediaPlayerService(MPS)的proxy,提交给MPS处理。

3. MediaPlayerService的工作。

MPS和千万万的Service一样,以一个服务者的身份存在,他是作为分析Binder驱动架构和原理的一个典型代表。在mediaserver中启动,和其他CameraService和AudioFlinger做为多媒体服务。

  1. int main(int argc, char** argv) 
  2.     signal(SIGPIPE, SIG_IGN); 
  3.     sp<ProcessState> proc(ProcessState::self()); 
  4.     sp<IServiceManager> sm = defaultServiceManager(); 
  5.     ALOGI("ServiceManager: %p", sm.get()); 
  6.     AudioFlinger::instantiate();//多媒体服务的启动包括音频,摄像头等 
  7.     MediaPlayerService::instantiate(); 
  8.     CameraService::instantiate(); 
  9.     AudioPolicyService::instantiate(); 
  10.     ProcessState::self()->startThreadPool(); 
  11.     IPCThreadState::self()->joinThreadPool(); 
int main(int argc, char** argv)
{
    signal(SIGPIPE, SIG_IGN);
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p", sm.get());
    AudioFlinger::instantiate();//多媒体服务的启动包括音频,摄像头等
    MediaPlayerService::instantiate();
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

3.1 处理create请求:

  1. sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, 
  2.         int audioSessionId)//创建一个mediaplayer,范范一个Client 
  3.     ALOGV("MediaPlayerService::create"); 
  4.     int32_t connId = android_atomic_inc(&mNextConnId); 
  5.  
  6.     sp<Client> c = new Client( 
  7.             this, pid, connId, client, audioSessionId, 
  8.             IPCThreadState::self()->getCallingUid());//内部类创建,实现BnMediaPlayer 
  9. ..... 
  10.    } 
sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
        int audioSessionId)//创建一个mediaplayer,范范一个Client
{
    ALOGV("MediaPlayerService::create");
    int32_t connId = android_atomic_inc(&mNextConnId);

    sp<Client> c = new Client(
            this, pid, connId, client, audioSessionId,
            IPCThreadState::self()->getCallingUid());//内部类创建,实现BnMediaPlayer
.....
   }

创建一个MPS的内部客户端类Client(继承于Binder本地接口类BnMediaPlay),这个看上去和CameraService很相似。有了这个本地客户端类,那么应用端的MediaPlay后续只需要和Client交互即可,而这其中是匿名的Binder在起作用。

3.2 player->setDataSource()

player是调用MPS后返回的一个BpBinder派生类,最终调用MPS的内部类Client的setDataSource()来实现。

  1. status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length) 
  2.   ......... 
  3.     player_type playerType = MediaPlayerFactory::getPlayerType(this
  4.                                                      fd, 
  5.                                             offset, 
  6.                                                                length, 
  7.         true );//根据视频源获取要使用的播放器的类型 
  8. ........ 
  9.         sp<MediaPlayerBase> p = setDataSource_pre(playerType);    // now set data source 
  10.     setDataSource_post(p, p->setDataSource(fd, offset, length)); 
  11.     return mStatus; 
status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
{
  .........
    player_type playerType = MediaPlayerFactory::getPlayerType(this,
                                                     fd,
                                            offset,
                                                               length,
        true );//根据视频源获取要使用的播放器的类型
 ........
        sp<MediaPlayerBase> p = setDataSource_pre(playerType);    // now set data source
    setDataSource_post(p, p->setDataSource(fd, offset, length));
    return mStatus;
}

这里面出现了一个MediaPlayerFactory,姑且理解为播放器厂商类吧。通过它来获取当前传入的视频源的视频源后缀格式等:如mp4,avi,3gp等。最终假设当前返回的playerType为STAGEFRIGHT_PLAYER。接着分析setDataSource_pre函数:

  1. sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre( 
  2.         player_type playerType) 
  3.     // create the right type of player 
  4.     sp<MediaPlayerBase> p = createPlayer(playerType);//创建一个播放器 
  5.     if (p == NULL) { 
  6.         return p; 
  7.     } 
  8.  
  9.     if (!p->hardwareOutput()) { 
  10.         mAudioOutput = new AudioOutput(mAudioSessionId); 
  11.         static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);//强制转化为MediaPlayerInterface 
  12.     } 
  13.  
  14.     return p; 
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
        player_type playerType)
{
    // create the right type of player
    sp<MediaPlayerBase> p = createPlayer(playerType);//创建一个播放器
    if (p == NULL) {
        return p;
    }

    if (!p->hardwareOutput()) {
        mAudioOutput = new AudioOutput(mAudioSessionId);
        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);//强制转化为MediaPlayerInterface
    }

    return p;
}


3.3 真正的创建一个适合于当前视频文件播放需要的Player:createPlayer。

  1. sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType) 
  2.     // determine if we have the right player type 
  3.     sp<MediaPlayerBase> p = mPlayer; 
  4.     if ((p != NULL) && (p->playerType() != playerType)) { 
  5.         ALOGV("delete player"); 
  6.         p.clear(); 
  7.     } 
  8.     if (p == NULL) { 
  9.         p = MediaPlayerFactory::createPlayer(playerType, this, notify);//新建一个player 
  10.     } 
  11.  
  12.     if (p != NULL) { 
  13.         p->setUID(mUID); 
  14.     } 
  15.  
  16.     return p; 
sp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
{
    // determine if we have the right player type
    sp<MediaPlayerBase> p = mPlayer;
    if ((p != NULL) && (p->playerType() != playerType)) {
        ALOGV("delete player");
        p.clear();
    }
    if (p == NULL) {
        p = MediaPlayerFactory::createPlayer(playerType, this, notify);//新建一个player
    }

    if (p != NULL) {
        p->setUID(mUID);
    }

    return p;
}

第一次处理时,mPlayer肯定为空,故可以看到最终还是回到了这个厂商播放器类来实现,因为这个类维护着当前平台支持的播放器类型(说到低就是解码器的种类).

  1. sp<MediaPlayerBase> MediaPlayerFactory::createPlayer( 
  2.         player_type playerType, 
  3.         void* cookie, 
  4.         notify_callback_f notifyFunc) { 
  5.     sp<MediaPlayerBase> p; 
  6.     IFactory* factory; 
  7.     status_t init_result; 
  8.     Mutex::Autolock lock_(&sLock); 
  9.  
  10.     if (sFactoryMap.indexOfKey(playerType) < 0) { 
  11.         ALOGE("Failed to create player object of type %d, no registered" 
  12.               " factory", playerType); 
  13.         return p; 
  14.     } 
  15.  
  16.     factory = sFactoryMap.valueFor(playerType);//根据type类型获取一个StagefrightPlayerFactory 
  17.     CHECK(NULL != factory); 
  18.     p = factory->createPlayer();//调用创建一个真正的palyer StagefrightPlayerPlay 
  19.  
  20.     if (p == NULL) { 
  21.         ALOGE("Failed to create player object of type %d, create failed"
  22.                playerType); 
  23.         return p; 
  24.     } 
  25.  
  26.     init_result = p->initCheck(); 
  27.     if (init_result == NO_ERROR) { 
  28.         p->setNotifyCallback(cookie, notifyFunc); 
  29.     } else
  30.         ALOGE("Failed to create player object of type %d, initCheck failed" 
  31.               " (res = %d)", playerType, init_result); 
  32.         p.clear(); 
  33.     } 
  34.  
  35.     return p; 
sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
        player_type playerType,
        void* cookie,
        notify_callback_f notifyFunc) {
    sp<MediaPlayerBase> p;
    IFactory* factory;
    status_t init_result;
    Mutex::Autolock lock_(&sLock);

    if (sFactoryMap.indexOfKey(playerType) < 0) {
        ALOGE("Failed to create player object of type %d, no registered"
              " factory", playerType);
        return p;
    }

    factory = sFactoryMap.valueFor(playerType);//根据type类型获取一个StagefrightPlayerFactory
    CHECK(NULL != factory);
    p = factory->createPlayer();//调用创建一个真正的palyer StagefrightPlayerPlay

    if (p == NULL) {
        ALOGE("Failed to create player object of type %d, create failed",
               playerType);
        return p;
    }

    init_result = p->initCheck();
    if (init_result == NO_ERROR) {
        p->setNotifyCallback(cookie, notifyFunc);
    } else {
        ALOGE("Failed to create player object of type %d, initCheck failed"
              " (res = %d)", playerType, init_result);
        p.clear();
    }

    return p;
}

这里出现了一个全局变量SFactoryMap变量:

MediaPlayerFactory::tFactoryMap sFactoryMap;//实际的类型是typedef KeyedVector<player_type, IFactory*> tFactoryMap;KeyedVector是一个向量类,类似于数组,通过一个index进行索引查找。他代表着当前支持的播放器列表。那么这个表的是在何处被初始化呢,我们需要回到MediaPlyerService的构造函数之中。

3.4 系统支持的播放器类型相关信息的注册:

  1. MediaPlayerService::MediaPlayerService() 
  2.     ALOGV("MediaPlayerService created"); 
  3.     mNextConnId = 1; 
  4.  
  5.     mBatteryAudio.refCount = 0; 
  6.     for (int i = 0; i < NUM_AUDIO_DEVICES; i++) { 
  7.         mBatteryAudio.deviceOn[i] = 0; 
  8.         mBatteryAudio.lastTime[i] = 0; 
  9.         mBatteryAudio.totalTime[i] = 0; 
  10.     } 
  11.     // speaker is on by default 
  12.     mBatteryAudio.deviceOn[SPEAKER] = 1; 
  13.  
  14.     MediaPlayerFactory::registerBuiltinFactories();//注册建立厂商的play 
MediaPlayerService::MediaPlayerService()
{
    ALOGV("MediaPlayerService created");
    mNextConnId = 1;

    mBatteryAudio.refCount = 0;
    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
        mBatteryAudio.deviceOn[i] = 0;
        mBatteryAudio.lastTime[i] = 0;
        mBatteryAudio.totalTime[i] = 0;
    }
    // speaker is on by default
    mBatteryAudio.deviceOn[SPEAKER] = 1;

    MediaPlayerFactory::registerBuiltinFactories();//注册建立厂商的play
  1. void MediaPlayerFactory::registerBuiltinFactories() { 
  2.     Mutex::Autolock lock_(&sLock); 
  3.  
  4.     if (sInitComplete) 
  5.         return
  6.  
  7.     registerFactory_l(new CedarXPlayerFactory(), CEDARX_PLAYER); 
  8.     registerFactory_l(new CedarAPlayerFactory(), CEDARA_PLAYER); 
  9.     registerFactory_l(new TPlayerFactory(), THUMBNAIL_PLAYER); 
  10.     registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER); 
  11.     registerFactory_l(new NuPlayerFactory(), NU_PLAYER); 
  12.     registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER); 
  13.     registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);//不同的播放器注册 
  14.  
  15.     sInitComplete = true
void MediaPlayerFactory::registerBuiltinFactories() {
    Mutex::Autolock lock_(&sLock);

    if (sInitComplete)
        return;

    registerFactory_l(new CedarXPlayerFactory(), CEDARX_PLAYER);
    registerFactory_l(new CedarAPlayerFactory(), CEDARA_PLAYER);
    registerFactory_l(new TPlayerFactory(), THUMBNAIL_PLAYER);
    registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER);
    registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
    registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER);
    registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);//不同的播放器注册

    sInitComplete = true;
}

这里以我们要举例的STAGEFRIGHT_PLAYER为例,进行分析:

a.new StagefrightPlayerFactory()新建一个播放器类,该类的结构如下:

  1. class StagefrightPlayerFactory : 
  2.     public MediaPlayerFactory::IFactory { 
  3.   public
  4.     virtual float scoreFactory(const sp<IMediaPlayer>& client, 
  5.                                int fd, 
  6.                                int64_t offset, 
  7.                                int64_t length, 
  8.                                float curScore) { 
  9.         char buf[20]; 
  10.         lseek(fd, offset, SEEK_SET); 
  11.         read(fd, buf, sizeof(buf)); 
  12.         lseek(fd, offset, SEEK_SET); 
  13.         long ident = *((long*)buf); 
  14.         // Ogg vorbis? 
  15.         if (ident == 0x5367674f) // 'OggS' 
  16.             return 1.0; 
  17.         return 0.0; 
  18.     } 
  19.     virtual sp<MediaPlayerBase> createPlayer() { 
  20.         ALOGV(" create StagefrightPlayer"); 
  21.         return new StagefrightPlayer();//新建一个StagefrightPlayer 
  22.     } 
  23. }; 
class StagefrightPlayerFactory :
    public MediaPlayerFactory::IFactory {
  public:
    virtual float scoreFactory(const sp<IMediaPlayer>& client,
                               int fd,
                               int64_t offset,
                               int64_t length,
                               float curScore) {
        char buf[20];
        lseek(fd, offset, SEEK_SET);
        read(fd, buf, sizeof(buf));
        lseek(fd, offset, SEEK_SET);
        long ident = *((long*)buf);
        // Ogg vorbis?
        if (ident == 0x5367674f) // 'OggS'
            return 1.0;
        return 0.0;
    }
    virtual sp<MediaPlayerBase> createPlayer() {
        ALOGV(" create StagefrightPlayer");
        return new StagefrightPlayer();//新建一个StagefrightPlayer
    }
};

很明显,该类的特点是继承并实现了IFactory这个接口类的相关功能。

b. 将新建的这个播放器对象进行注册,依次添加索引值:播放器类型type,并将其对应的factory保存到sFactorymap这种向量表中。

  1. status_t MediaPlayerFactory::registerFactory_l(IFactory* factory, 
  2.                                                player_type type) { 
  3.     if (NULL == factory) { 
  4.         ALOGE("Failed to register MediaPlayerFactory of type %d, factory is" 
  5.               " NULL.", type); 
  6.         return BAD_VALUE; 
  7.     } 
  8.  
  9.     if (sFactoryMap.indexOfKey(type) >= 0) { 
  10.         ALOGE("Failed to register MediaPlayerFactory of type %d, type is" 
  11.               " already registered.", type); 
  12.         return ALREADY_EXISTS; 
  13.     } 
  14.  
  15.     if (sFactoryMap.add(type, factory) < 0) { 
  16.         ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add" 
  17.               " to map.", type); 
  18.         return UNKNOWN_ERROR; 
  19.     } 
  20.  
  21.     return OK; 
status_t MediaPlayerFactory::registerFactory_l(IFactory* factory,
                                               player_type type) {
    if (NULL == factory) {
        ALOGE("Failed to register MediaPlayerFactory of type %d, factory is"
              " NULL.", type);
        return BAD_VALUE;
    }

    if (sFactoryMap.indexOfKey(type) >= 0) {
        ALOGE("Failed to register MediaPlayerFactory of type %d, type is"
              " already registered.", type);
        return ALREADY_EXISTS;
    }

    if (sFactoryMap.add(type, factory) < 0) {
        ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add"
              " to map.", type);
        return UNKNOWN_ERROR;
    }

    return OK;
}

我们回到3.3的程序中区,通过factory = sFactoryMap.valueFor(playerType);//根据type类型获取一个StagefrightPlayerFactory,即之前注册的factory对象。实际是调用他的虚函数create_player()来实现:

  1. virtual sp<MediaPlayerBase> createPlayer() { 
  2.     ALOGV(" create StagefrightPlayer"); 
  3.     return new StagefrightPlayer();//新建一个StagefrightPlayer 
    virtual sp<MediaPlayerBase> createPlayer() {
        ALOGV(" create StagefrightPlayer");
        return new StagefrightPlayer();//新建一个StagefrightPlayer
    }

接下去我们看到的将是真正进入StageFright的实现流程:

  1. StagefrightPlayer::StagefrightPlayer() 
  2.     : mPlayer(new AwesomePlayer) {//新建一个AwesomePlayer类,该结构体类属于Stagefright 
  3.     ALOGV("StagefrightPlayer"); 
  4.  
  5.     mPlayer->setListener(this);//注册StagefrightPlayer到AwesomePlayer类 
StagefrightPlayer::StagefrightPlayer()
    : mPlayer(new AwesomePlayer) {//新建一个AwesomePlayer类,该结构体类属于Stagefright
    ALOGV("StagefrightPlayer");

    mPlayer->setListener(this);//注册StagefrightPlayer到AwesomePlayer类
}

3.4 AwesimePlayer打入stagefright内部

  1.  
  2. AwesomePlayer::AwesomePlayer() 
  3.     : mQueueStarted(false), 
  4.       mUIDValid(false), 
  5.       mTimeSource(NULL), 
  6.       mVideoRenderingStarted(false), 
  7.       mVideoRendererIsPreview(false), 
  8.       mAudioPlayer(NULL), 
  9.       mDisplayWidth(0), 
  10.       mDisplayHeight(0), 
  11.       mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), 
  12.       mFlags(0), 
  13.       mExtractorFlags(0), 
  14.       mVideoBuffer(NULL), 
  15.       mDecryptHandle(NULL), 
  16.       mLastVideoTimeUs(-1), 
  17.       mTextDriver(NULL) { 
  18.     CHECK_EQ(mClient.connect(), (status_t)OK);//OMXClient,connect后维护一个mOMX:BpOMX 
  19.  
  20.     DataSource::RegisterDefaultSniffers(); 
  21.  
  22.     mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);//注册onVideoEvent事件 
  23.     mVideoEventPending = false
  24.     mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);//注册onStreamDone事件 
  25.     mStreamDoneEventPending = false
  26.     mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);//注册onBufferingUpdate 
  27.     mBufferingEventPending = false
  28.     mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate); 
  29.     mVideoEventPending = false
  30.  
  31.     mCheckAudioStatusEvent = new AwesomeEvent( 
  32.             this, &AwesomePlayer::onCheckAudioStatus); 
  33.  
  34.     mAudioStatusEventPending = false
  35.  
  36.     reset(); 

AwesomePlayer::AwesomePlayer()
    : mQueueStarted(false),
      mUIDValid(false),
      mTimeSource(NULL),
      mVideoRenderingStarted(false),
      mVideoRendererIsPreview(false),
      mAudioPlayer(NULL),
      mDisplayWidth(0),
      mDisplayHeight(0),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
      mFlags(0),
      mExtractorFlags(0),
      mVideoBuffer(NULL),
      mDecryptHandle(NULL),
      mLastVideoTimeUs(-1),
      mTextDriver(NULL) {
    CHECK_EQ(mClient.connect(), (status_t)OK);//OMXClient,connect后维护一个mOMX:BpOMX

    DataSource::RegisterDefaultSniffers();

    mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent);//注册onVideoEvent事件
    mVideoEventPending = false;
    mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone);//注册onStreamDone事件
    mStreamDoneEventPending = false;
    mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate);//注册onBufferingUpdate
    mBufferingEventPending = false;
    mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate);
    mVideoEventPending = false;

    mCheckAudioStatusEvent = new AwesomeEvent(
            this, &AwesomePlayer::onCheckAudioStatus);

    mAudioStatusEventPending = false;

    reset();
}

Awesomeplay的构造函数,主要过程是建立了几个事件处理的注册,具体的event处理机制在下一文中分享






 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值