- 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.4 start
Java 代码这边的 start 方法对应的是 StagefrightPlayer 中的 start,其中又调用了 player 的 play 方法
status_t StagefrightPlayer::start() { ALOGV("start"); return mPlayer->play(); }
对应的是 AwesomePlayer 中的 play 方法:
status_t AwesomePlayer::play() { ATRACE_CALL(); Mutex::Autolock autoLock(mLock); modifyFlags(CACHE_UNDERRUN, CLEAR); return play_l(); } status_t AwesomePlayer::play_l() { modifyFlags(SEEK_PREVIEW, CLEAR); // 如果正在播放,则什么也不做 if (mFlags & PLAYING) { return OK; } mMediaRenderingStartGeneration = ++mStartGeneration; // 如果没有之前没有调用 prepare,这里会帮你调用一次,顺便我还做了个实验,create 之后 直接 start 是可以播放的,并没有报错什么的。 if (!(mFlags & PREPARED)) { status_t err = prepare_l(); if (err != OK) { return err; } } modifyFlags(PLAYING, SET); modifyFlags(FIRST_FRAME, SET); if (mDecryptHandle != NULL) { int64_t position; getPosition(&position); mDrmManagerClient->setPlaybackStatus(mDecryptHandle, Playback::START, position / 1000); } if (mAudioSource != NULL) { if (mAudioPlayer == NULL) { createAudioPlayer_l(); } CHECK(!(mFlags & AUDIO_RUNNING)); if (mVideoSource == NULL) { // We don't want to post an error notification at this point, // the error returned from MediaPlayer::start() will suffice. status_t err = startAudioPlayer_l(false /* sendErrorNotification */); // 是否可以硬解音频 if ((err != OK) && mOffloadAudio) { ALOGI("play_l() cannot create offload output, fallback to sw decode"); int64_t curTimeUs; getPosition(&curTimeUs); delete mAudioPlayer; mAudioPlayer = NULL; // if the player was started it will take care of stopping the source when destroyed if (!(mFlags & AUDIOPLAYER_STARTED)) { mAudioSource->stop(); } modifyFlags((AUDIO_RUNNING | AUDIOPLAYER_STARTED), CLEAR); mOffloadAudio = false; mAudioSource = mOmxSource; if (mAudioSource != NULL) { err = mAudioSource->start(); if (err != OK) { mAudioSource.clear(); } else { mSeekNotificationSent = true; if (mExtractorFlags & MediaExtractor::CAN_SEEK) { seekTo_l(curTimeUs); } createAudioPlayer_l(); // 播放音频 err = startAudioPlayer_l(false); } } } if (err != OK) { delete mAudioPlayer; mAudioPlayer = NULL; modifyFlags((PLAYING | FIRST_FRAME), CLEAR); if (mDecryptHandle != NULL) { mDrmManagerClient->setPlaybackStatus(mDecryptHandle, Playback::STOP, 0); } return err; } } } // timesource 用于视音频同步,通常来说是根据 audio 中的 timesource 为基准, // 这里判断下是否有音频时间和音频播放器,如果没有,则采用系统的时间 if (mTimeSource == NULL && mAudioPlayer == NULL) { mTimeSource = &mSystemTimeSource; } // 播放视频 if (mVideoSource != NULL) { // Kick off video playback postVideoEvent_l(); if (mAudioSource != NULL && mVideoSource != NULL) { postVideoLagEvent_l(); } } // 流的结尾 if (mFlags & AT_EOS) { // Legacy behaviour, if a stream finishes playing and then // is started again, we play from the start... seekTo_l(0); } uint32_t params = IMediaPlayerService::kBatteryDataCodecStarted | IMediaPlayerService::kBatteryDataTrackDecoder; if ((mAudioSource != NULL) && (mAudioSource != mAudioTrack)) { params |= IMediaPlayerService::kBatteryDataTrackAudio; } if (mVideoSource != NULL) { params |= IMediaPlayerService::kBatteryDataTrackVideo; } addBatteryData(params); if (isStreamingHTTP()) { postBufferingEvent_l(); } return OK; }
视频的播放是通过不断的 postVideoEvent_l 来实现画面的播放,postVideoEvent_l 会向队列中 post 一个 videoEvent,这个 event 最终又会触发 AwesomePlayer::onVideoEvent 的方法, onVideoEvent 方法中又会调用 postVideoEvent_l,形成循环,最终实现视频的播放。startAudioPlayer_l 最终会调用到 AudioPlayer 播放音频。
播放的过程到这里就结束了,接下来暂停和结束的部分就相对简单了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论