Android多媒體開發筆記[7]-- AwesomePlayer 學習之TimedEventQueue-event事件

來源:互聯網
上載者:User

視頻處理過程中有很多都是十分耗時的,如果都放在一個大的線程空間中。使用者體驗的效果可想而知。所以通常都是做非同步作業。
AwesomePlayer是通過event事件調度來實現這些功能之間的驅動和調用的。
AwesomePlayer中的內部變數
[cpp] 
TimedEventQueue mQueue; 
這個mQueue就是AwesomePlayer的事件隊列,也是事件調度器。從他類型的名字上就能很清楚的看出他是以時間為基礎事件隊列。接下來看看它是怎麼玩轉的。

1.先來看TimedEventQueue的內部結構,TimedEventQueue內部有一個 List<QueueItem>,每個QueueItem包含enent和時間
[cpp] 
struct QueueItem { 
       sp<Event> event; 
       int64_t realtime_us; 
   }; 
有一個獨立線程threadEntry是在TimedEventQueue::start被建立,TimedEventQueue::stop被銷毀的。
[cpp] 
void TimedEventQueue::start() { 
    if (mRunning) { 
        return; 
    } 
 
    mStopped = false; 
 
    pthread_attr_t attr; 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
 
    pthread_create(&mThread, &attr, ThreadWrapper, this); 
 
    pthread_attr_destroy(&attr); 
 
    mRunning = true; 

 
void TimedEventQueue::stop(bool flush) { 
    if (!mRunning) { 
        return; 
    } 
 
    if (flush) { 
        postEventToBack(new StopEvent); 
    } else { 
        postTimedEvent(new StopEvent, INT64_MIN); 
    } 
 
    void *dummy; 
    pthread_join(mThread, &dummy); 
 
    mQueue.clear(); 
 
    mRunning = false; 

2.List<QueueItem>目的就是按照延時時間維護一個event事件隊列,threadEntry線程就是不斷的從隊列的頭取出一個event,然後通過  event->fire(this, now_us); 回調到這個event事件提前註冊好的相對應功能函數。
3.然後看看AwesomePlayer是怎麼用TimedEventQueue,AwesomePlayer會定義很多類型的event事件,並把和這些事件相關的功能函數一定綁定起來。
[cpp] 
mVideoEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoEvent); 
mVideoEventPending = false; 
mStreamDoneEvent = new AwesomeEvent(this, &AwesomePlayer::onStreamDone); 
mStreamDoneEventPending = false; 
mBufferingEvent = new AwesomeEvent(this, &AwesomePlayer::onBufferingUpdate); 
mBufferingEventPending = false; 
mVideoLagEvent = new AwesomeEvent(this, &AwesomePlayer::onVideoLagUpdate); 
mVideoEventPending = false; 
mCheckAudioStatusEvent = new AwesomeEvent(this, &AwesomePlayer::onCheckAudioStatus); 
  原因之前也說了,因為好多音視頻處理的功能是十分耗時間的,假如AwesomePlayer 想用某個功能,他並不是直線去調用它,而是抽象成一種AwesomeEvent,將想要調用的功能函數與事件捆綁。通過TimedEventQueue::postTimedEvent(),按照延時的優先順序把它放到TimedEventQueue的隊列之中。然後AwesomePlayer就不管了。TimedEventQueue start之後,自己內部的線程會從隊列中依次取出這些事件,然後通過event->fire回調事件的功能函數。這樣就達到了AwesomePlayer的目的。
4.之前也介紹過mediaPlayer大致流程就是
mediaPlayer.setDataSource(path); 
mediaPlayer.prepare(); 
mediaPlayer.start();
在AwesomePlayer 也是這種流程,在AwesomePlayer prepare()相關函數中。
[cpp]
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; 

他並沒有實際的調用onPrepareAsyncEvent()真正的功能函數,他只是把mQueue start之後,然後建立個mAsyncPrepareEvent事件,把它插入到mQueue之中就不管了,具體調用是由mQueue中的threadEntry線程來做。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.