- CompoundButton 源码分析
- LinearLayout 源码分析
- SearchView 源码解析
- LruCache 源码解析
- ViewDragHelper 源码解析
- BottomSheets 源码解析
- Media Player 源码分析
- NavigationView 源码解析
- Service 源码解析
- Binder 源码分析
- Android 应用 Preference 相关及源码浅析 SharePreferences 篇
- ScrollView 源码解析
- Handler 源码解析
- NestedScrollView 源码解析
- SQLiteOpenHelper/SQLiteDatabase/Cursor 源码解析
- Bundle 源码解析
- LocalBroadcastManager 源码解析
- Toast 源码解析
- TextInputLayout
- LayoutInflater 和 LayoutInflaterCompat 源码解析
- TextView 源码解析
- NestedScrolling 事件机制源码解析
- ViewGroup 源码解析
- StaticLayout 源码分析
- AtomicFile 源码解析
- AtomicFile 源码解析
- Spannable 源码分析
- Notification 之 Android 5.0 实现原理
- CoordinatorLayout 源码分析
- Scroller 源码解析
- SwipeRefreshLayout 源码分析
- FloatingActionButton 源码解析
- AsyncTask 源码分析
- TabLayout 源码解析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
3.3 Prepare
通过之前的经验我们可以很快的知道 prepare 应该对应的是 AwesomePlayer 中的 prepare:
status_t AwesomePlayer::prepare() { ... return prepare_l(); } status_t AwesomePlayer::prepare_l() { ... status_t err = prepareAsync_l(); ... return mPrepareResult; } status_t AwesomePlayer::prepareAsync_l() { if (mFlags & PREPARING) { return UNKNOWN_ERROR; // async prepare already pending } if (!mQueueStarted) { mQueue.start(); mQueueStarted = true; } modifyFlags(PREPARING, SET); mAsyncPrepareEvent = new AwesomeEvent( this, &AwesomePlayer::onPrepareAsyncEvent); mQueue.postEvent(mAsyncPrepareEvent); return OK; }
mQueue 是 TimedEventQueue ,TimedEventQueue 和 Handler 很相似,使用 pthread 和 队列来管理消息。在这里通过异步方式回调 onPrepareAsyncEvent 方法:
void AwesomePlayer::onPrepareAsyncEvent() { Mutex::Autolock autoLock(mLock); beginPrepareAsync_l(); } void AwesomePlayer::beginPrepareAsync_l() { // 取消 prepare if (mFlags & PREPARE_CANCELLED) { ALOGI("prepare was cancelled before doing anything"); abortPrepare(UNKNOWN_ERROR); return; } // 网络媒体 if (mUri.size() > 0) { status_t err = finishSetDataSource_l(); if (err != OK) { abortPrepare(err); return; } } // 是否包含视频 if (mVideoTrack != NULL && mVideoSource == NULL) { // 初始化视频解码器 status_t err = initVideoDecoder(); if (err != OK) { abortPrepare(err); return; } } // 是否包含音频 if (mAudioTrack != NULL && mAudioSource == NULL) { // 初始化音频解码器 status_t err = initAudioDecoder(); if (err != OK) { abortPrepare(err); return; } } modifyFlags(PREPARING_CONNECTED, SET); // 不同的播放源类型 if (isStreamingHTTP()) { // 网络流媒体 postBufferingEvent_l(); } else { // 本地媒体 finishAsyncPrepare_l(); } } void AwesomePlayer::finishAsyncPrepare_l() { if (mIsAsyncPrepare) { if (mVideoSource == NULL) { notifyListener_l(MEDIA_SET_VIDEO_SIZE, 0, 0); } else { notifyVideoSize_l(); } notifyListener_l(MEDIA_PREPARED); } // 设置 player 的状态 mPrepareResult = OK; modifyFlags((PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED), CLEAR); modifyFlags(PREPARED, SET); mAsyncPrepareEvent = NULL; // 同步线程之间的状态 mPreparedCondition.broadcast(); // mAudioTearDown 默认为 false,当暂停的时候通过回调方法将其改为 true if (mAudioTearDown) { if (mPrepareResult == OK) { if (mExtractorFlags & MediaExtractor::CAN_SEEK) { seekTo_l(mAudioTearDownPosition); } if (mAudioTearDownWasPlaying) { modifyFlags(CACHE_UNDERRUN, CLEAR); play_l(); } } mAudioTearDown = false; } }
经过一番设置后,prepare 的过程也算是完成了。这一部分主要是对 player 的状态进行设置,通过消息机制让让调用端也知道这边的 player 状态。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论