TimedTextPlayer.cpp revision 7a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3
17a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang /*
27a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * Copyright (C) 2011 The Android Open Source Project
37a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *
47a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * Licensed under the Apache License, Version 2.0 (the "License");
57a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * you may not use this file except in compliance with the License.
67a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * You may obtain a copy of the License at
77a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *
87a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *      http://www.apache.org/licenses/LICENSE-2.0
97a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang *
107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * Unless required by applicable law or agreed to in writing, software
117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * distributed under the License is distributed on an "AS IS" BASIS,
127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * See the License for the specific language governing permissions and
147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang * limitations under the License.
157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang */
167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang//#define LOG_NDEBUG 0
187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#define LOG_TAG "TimedTextPlayer"
197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <utils/Log.h>
207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <binder/IPCThreadState.h>
227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MediaDebug.h>
237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MediaDefs.h>
247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MediaErrors.h>
257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MediaSource.h>
267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MetaData.h>
277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/MediaBuffer.h>
287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/Utils.h>
297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/AwesomePlayer.h"
307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/TimedTextPlayer.h"
317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangnamespace android {
337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstruct TimedTextEvent : public TimedEventQueue::Event {
357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent(
367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            TimedTextPlayer *player,
377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            void (TimedTextPlayer::*method)())
387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        : mPlayer(player),
397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang          mMethod(method) {
407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangprotected:
437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    virtual ~TimedTextEvent() {}
447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        (mPlayer->*mMethod)();
477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangprivate:
507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextPlayer *mPlayer;
517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    void (TimedTextPlayer::*mMethod)();
527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent(const TimedTextEvent &);
547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent &operator=(const TimedTextEvent &);
557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang};
567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria WangTimedTextPlayer::TimedTextPlayer(
587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        AwesomePlayer *observer,
597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        const wp<MediaPlayerBase> &listener,
607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        TimedEventQueue *queue)
617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    : mSource(NULL),
627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mSeekTimeUs(0),
637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mStarted(false),
647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mTextEventPending(false),
657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mQueue(queue),
667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mListener(listener),
677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mObserver(observer),
687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mTextBuffer(NULL) {
697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEvent = new TimedTextEvent(this, &TimedTextPlayer::onTextEvent);
707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria WangTimedTextPlayer::~TimedTextPlayer() {
737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mStarted) {
747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        reset();
757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextTrackVector.clear();
787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::start(uint8_t index) {
817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(!mStarted);
827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (index >= mTextTrackVector.size()) {
847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        LOGE("Incorrect text track index");
857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return BAD_VALUE;
867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSource = mTextTrackVector.itemAt(index);
897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    status_t err = mSource->start();
917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (err != OK) {
937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return err;
947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    int64_t positionUs;
977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mObserver->getPosition(&positionUs);
987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    seekTo(positionUs);
997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    postTextEvent();
1017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mStarted = true;
1037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
1057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::pause() {
1087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    cancelTextEvent();
1117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::resume() {
1147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    postTextEvent();
1177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::reset() {
1207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    // send an empty text to clear the screen
1237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    notifyListener(MEDIA_TIMED_TEXT);
1247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    cancelTextEvent();
1267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeeking = false;
1287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mStarted = false;
1297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextBuffer != NULL) {
1317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextBuffer->release();
1327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextBuffer = NULL;
1337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mSource != NULL) {
1367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mSource->stop();
1377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mSource.clear();
1387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mSource = NULL;
1397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::seekTo(int64_t time_us) {
1437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    Mutex::Autolock autoLock(mLock);
1447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeeking = true;
1467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeekTimeUs = time_us;
1477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
1497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::setTimedTextTrackIndex(int32_t index) {
1527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (index >= (int)(mTextTrackVector.size())) {
1537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return BAD_VALUE;
1547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mStarted) {
1577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        reset();
1587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (index >= 0) {
1617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return start(index);
1627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
1647a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::onTextEvent() {
1677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    Mutex::Autolock autoLock(mLock);
1687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (!mTextEventPending) {
1707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return;
1717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = false;
1737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    MediaSource::ReadOptions options;
1757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mSeeking) {
1767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        options.setSeekTo(mSeekTimeUs,
1777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
1787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mSeeking = false;
1797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        if (mTextBuffer != NULL) {
1817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            mTextBuffer->release();
1827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            mTextBuffer = NULL;
1837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
1847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        notifyListener(MEDIA_TIMED_TEXT); //empty text to clear the screen
1867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextBuffer != NULL) {
1897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        uint8_t *tmp = (uint8_t *)(mTextBuffer->data());
1907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        size_t len = (*tmp) << 8 | (*(tmp + 1));
1917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        notifyListener(MEDIA_TIMED_TEXT,
1937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                       tmp + 2,
1947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                       len);
1957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextBuffer->release();
1977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mTextBuffer = NULL;
1987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mSource->read(&mTextBuffer, &options) != OK) {
2027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return;
2037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    int64_t positionUs, timeUs;
2067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mObserver->getPosition(&positionUs);
2077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextBuffer->meta_data()->findInt64(kKeyTime, &timeUs);
2087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    //send the text now
2107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (timeUs <= positionUs + 100000ll) {
2117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        postTextEvent();
2127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    } else {
2137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        postTextEvent(timeUs - positionUs - 100000ll);
2147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::postTextEvent(int64_t delayUs) {
2187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextEventPending) {
2197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return;
2207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = true;
2237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mQueue->postEventWithDelay(mTextEvent, delayUs < 0 ? 10000 : delayUs);
2247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::cancelTextEvent() {
2277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mQueue->cancelEvent(mTextEvent->eventID());
2287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = false;
2297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::addTextSource(sp<MediaSource> source) {
2327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextTrackVector.add(source);
2337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::notifyListener(
2367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        int msg, const void *data, size_t size) {
2377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mListener != NULL) {
2387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        sp<MediaPlayerBase> listener = mListener.promote();
2397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        if (listener != NULL) {
2417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (size > 0) {
2427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                mData.freeData();
2437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                mData.write(data, size);
2447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                listener->sendEvent(msg, 0, 0, &mData);
2467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else { // send an empty timed text to clear the screen
2477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                listener->sendEvent(msg);
2487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
2497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
2507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
253