AwesomePlayer里面定义了一个TimedEventQueue,通过向它发事件消息,来驱动player的运转。
定义在AwesomePlayer.h里面,如下:
TimedEventQueue mQueue;
TimedEventQueue中维护了一个队列,外面通过调用其提供的方法postEvent, postEventWithDelay等等来向队列添加事件,在执行完mQueue.start()后,TimedEventQueue将启动一个线程,用来取出队列中的事件,并执行之。
先看mQueue.start()
void TimedEventQueue::start() {
if (mRunning) {
return;
}
mStopped = false;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// 创建线程,线程函数为ThreadWrapper
pthread_create(&mThread, &attr, ThreadWrapper, this);
pthread_attr_destroy(&attr);
mRunning = true;
}
// static
void *TimedEventQueue::ThreadWrapper(void *me) {
androidSetThreadPriority(0, ANDROID_PRIORITY_FOREGROUND);
// 线程函数又调用了自己的threadEntry()
static_cast<TimedEventQueue *>(me)->threadEntry();
return NULL;
}
void TimedEventQueue::threadEntry() {
prctl(PR_SET_NAME, (unsigned long)"TimedEventQueue", 0, 0, 0);
for (;;) {
int64_t now_us = 0;
sp<Event> event;
{
Mutex::Autolock autoLock(mLock);
if (mStopped) {
break;
}
// 等待队列中有事件来
while (mQueue.empty()) {
mQueueNotEmptyCondition.wait(mLock);
}
event_id eventID = 0;
for (;;) {
if (mQueue.empty()) {
// The only event in the queue could have been cancelled
// while we were waiting for its scheduled time.
break;
}
// 往队列中添加事件是按照事件的时间先后顺序添加的
// 所以这里是取执行时间最靠前的事件
List<QueueItem>::iterator it = mQueue.begin();
eventID = (*it).event->eventID();
now_us = ALooper::GetNowUs();
int64_t when_us = (*it).realtime_us;
int64_t delay_us;
if (when_us < 0 || when_us == INT64_MAX) {
delay_us = 0;
} else {
delay_us = when_us - now_us;
}
if (delay_us <= 0) {
break; // 不需要等待
}
static int64_t kMaxTimeoutUs = 10000000ll; // 10 secs
bool timeoutCapped = false;
// 等待时间超过10secs,则分成几次来等
if (delay_us > kMaxTimeoutUs) {
ALOGW("delay_us exceeds max timeout: %lld us", delay_us);
// We'll never block for more than 10 secs, instead
// we will split up the full timeout into chunks of
// 10 secs at a time. This will also avoid overflow
// when converting from us to ns.
delay_us = kMaxTimeoutUs;
timeoutCapped = true;
}
// 等待相应的时长
status_t err = mQueueHeadChangedCondition.waitRelative(
mLock, delay_us * 1000ll);
if (!timeoutCapped && err == -ETIMEDOUT) {
// We finally hit the time this event is supposed to
// trigger.
now_us = ALooper::GetNowUs();
break;
}
}
// The event w/ this id may have been cancelled while we're
// waiting for its trigger-time, in that case
// removeEventFromQueue_l will return NULL.
// Otherwise, the QueueItem will be removed
// from the queue and the referenced event returned.
event = removeEventFromQueue_l(eventID);
}
// 执行取出的事件
if (event != NULL) {
// Fire event with the lock NOT held.
event->fire(this, now_us);
}
}
}
可见,mQueue.start()之后,TimedEventQueue就启动了一个线程,等待外面给它发event,然后取出消息,并通过调用event->fire(this, now_us)执行之。
接下来,就去看看AwesomePlayer往队列里发的event。
mAsyncPrepareEvent = new AwesomeEvent(
this, &AwesomePlayer::onPrepareAsyncEvent);
mQueue.postEvent(mAsyncPrepareEvent);
AwesomeEvent的定义如下:struct AwesomeEvent : public TimedEventQueue::Event {
AwesomeEvent(
AwesomePlayer *player,
void (AwesomePlayer::*method)())
: mPlayer(player),
mMethod(method) {
}
protected:
virtual ~AwesomeEvent() {}
virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
(mPlayer->*mMethod)();
}
private:
AwesomePlayer *mPlayer;
void (AwesomePlayer::*mMethod)();
AwesomeEvent(const AwesomeEvent &);
AwesomeEvent &operator=(const AwesomeEvent &);
};
在构造函数中,mPlayer被赋值为this,即AwesomePlayer自己,mMethod被赋值为AwesomePlayer::onPrepareAsyncEvent。AwesomeEvent实现了fire方法,(mPlayer->*mMethod)(),综合前面对TimedEventQueue的了解,当这个AwesomeEvent被post到TimedEventQueue的队列后,就会在TimedEventQueue启动的线程函数中被取出,然后会调用event的fire函数,在这里就是调用AwesomePlayer的onPrepareAsyncEvent方法了。
AwesomePlayer里面定义的AwesomeEvent有:
mVideoEvent = new AwesomeEvent(this,&AwesomePlayer::onVideoEvent);
mStreamDoneEvent = new AwesomeEvent(this,&AwesomePlayer::onStreamDone);
mBufferingEvent = new AwesomeEvent(this,&AwesomePlayer::onBufferingUpdate);
mVideoLagEvent = new AwesomeEvent(this,&AwesomePlayer::onVideoLagUpdate);
mAsyncPrepareEvent = new AwesomeEvent(
this, &AwesomePlayer::onPrepareAsyncEvent);
等等……
到此,TimedEventQueue分析完毕。