JetPlayer
EAS库函数:
接口 | 说明 |
EAS_FILE | 描述文件位置,可以是路径或者文件描述符 |
EAS_DATA_HANDLE | 描述文件数据流,可以暂停、恢复,设置,读取事件 |
EAS_PCM | 描述音频PCM数据,可以直接拷贝给AudioTrack |
EAS_STATE | 描述Jet状态 |
EAS_Init | |
EAS_Prepare | |
EAS_Resume | |
EAS_Pause | |
EAS_Locate | |
EAS_GetLocation | |
EAS_SetRepeat | |
EAS_Render | 解码 |
EAS_State | |
EAS_Shutdown |
JET库函数:
接口 | 说明 |
EAS_FILE_LOCATOR | 描述文件位置,可以是路径或者文件描述符 |
JET_OpenFile | 打开 |
JET_Play | 设置播放(恢复)状态 |
JET_Pause | 设置暂停状态 |
JET_Clear_Queue | 清空队列 |
JET_QueueSegment | 插入分段 |
JET_SetMuteFlags/JET_SetMuteFlag | 设置静音 |
JET_GetEvent | 获取事件 |
JET_CloseFile | 关闭文件 |
JetPlayer通过Jet库函数和AudioTrack实现Jet播放,管理事件状态回调jetevent_callback。
JetPlayerThread(JetPlayer::render):循环调用EAS_Render解码,将解码数据发给 AudioTrack;同时处理暂停、恢复状态变化,发布事件和状态变化给外部。
AwesomePlayer
AwesomePlayer的主要调用流程:
- setDataSource
- prepare
- play
- pause
- reset
AwesomePlayer主要由事件驱动,通过TimedEventQueue内部线程fire事件。
通过Uri、fd创建DataSource(Uri方式要延后到prepare时处理),再创建MediaExtractor,通过MediaExtractor获取各个Track(MediaSource),然后分别创建Audio、Video的OMXCodec(也是MediaSource),再创建AudioPlayer处理音频播放,视频播放由AwesomePlayer自己处理。
AudioPlayer由底层AudioSink(这个是在创建AudioPlayer之前,MediaPlayer就设置了,由AudioOutput实现)回调驱动(AudioTrack线程),响应回调时通过MediaSource读取音频数据(已解码)。
视频播放在事件线程处理,在onVideoEvent中从MediaSource读取视频数据,交给AwesomeRenderer(延迟创建)渲染。为了音视频同步,渲染有时需要延迟。
NuPlayer
StagefrightRecorder
WifiDisplaySource
MediaScanner
- MediaScanner.scanSingleFile()
- MediaScanner.MyMediaScannerClient.doScanFile()
- beginFile() 【创建FileEntry】
- MediaScanner.processFile()【JNI】
- MediaScanner::processFile() 【StagefrightMediaScanner】
- StagefrightMediaScanner::processFileInternal()
- MediaScannerClient::addStringTag()【多次调用】
- MediaScannerClient::handleStringTag()【MyMediaScannerClient虚方法】
- MediaScanner.MyMediaScannerClient.handleStringTag()【JNI回调】
- MediaScannerClient::handleStringTag()【MyMediaScannerClient虚方法】
- MediaScannerClient::addStringTag()【多次调用】
- StagefrightMediaScanner::processFileInternal()
- MediaScanner::processFile() 【StagefrightMediaScanner】
- endFile()
- MediaInserter.insert()
- IContentProvider.update()
- MediaScanner.processFile()【JNI】
- beginFile() 【创建FileEntry】
- MediaScanner.MyMediaScannerClient.doScanFile()
- MediaScanner.scanDirectories()
- prescan()
- processDirectory()【循环调用,JNI】
- MediaScanner::processDirectory () 【MediaScanner】
- doProcessDirectory()
- shouldSkipDirectory()
- doProcessDirectoryEntry()
- MediaScannerClient::scanFile()【MyMediaScannerClient虚方法】
- MediaScanner.MyMediaScannerClient.scanFile()
- doScanFile()【见上】
- MediaScanner.MyMediaScannerClient.scanFile()
- MediaScannerClient::scanFile()【MyMediaScannerClient虚方法】
- doProcessDirectory()
- MediaScanner::processDirectory () 【MediaScanner】
- postscan()