http://blog.chinaunix.net/uid-7318785-id-3251504.html
注:本文主要参考了“stagefright框架(X)”系列的几篇文章,并基于Android 4.0.3源代码结合自己的理解整理而成。由于是精简版本,故未贴上相关源代码,请谅解。
1 Stagefright Player location in Android media framework
Stagefright于Android 2.0版本引入系统,自 Android 2.3(Gingerbread)版本开始被设置为默认多媒体架构。Stagefright模块所处位置如图1。
2 Video Playback
这里主要介绍Stagefright是如何播放一段video的,源代码参照的是Android 4.0.3。
Stagefright 是以 shared library 形式存在于Android 系统中,其库名为 libstagefright.so。其中,module -- AwesomePlayer承担了本地媒体播放的主要工作,而streaming方面则交由nuPlayer来完成。
在JAVA层中,若要播放一段影片,我们会这样写:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE); ....... (1)
mp.prepare(); ......................... (2)
mp.start(); ........................... (3)
对应于media framework中,首先会new AwesomePlayer。随后的(1), (2), (3)分别会对应执行:
(1) AwesomePlayer::setDataSource();
根据文件类型创建对应的extractor,并执行相应的getTrack函数得到mVideoTrack和mAudioTrack。
(2) AwesomePlayer::prepare();
启动mQueue,触发onPrepareAsyncEvent。通过执行initVideoDecoder()在OMXCodec中创建video decoder,得到mVideoSource;执行initAudioDecoder()中创建audio decoder,得到mAudioSource。并分别执行对应的start()函数完成buffer的初始化工作。
(3) AwesomePlayer::play();
首先会new AudioPlayer,所以之后对于audio data的处理会交由AudioPlayer完成。接着会通过postVideoEvent_l()启动onVideoEvent()函数的线程。
在onVideoEvent()函数中,先执行mVideoSource->read,完成数据的读取和decoder工作。如果是首次运行该函数,则执行mAudioPlayer->start,创建audio thread,属于AwesomePlayer的外部线程。随后会获取audio的TimeStamp,check 对应的video buffer time,以决定是否render当前video buffer,从而实现A/V同步。函数在完成上述所有工作后,会再次调用postVideoEvent_l(),以循环执行流程。
Video Playback的整体架构如图2所示:
图 2
其中video data的传输可参考图3:
Video 的事件驱动和工作流程可参照图4:
详细执行过程如下序列图所示: