TimedTextPlayer.cpp revision 965d08ba16ee82bc85f69546360c18e7da907406
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>
28965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include <media/stagefright/FileSource.h>
297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include <media/stagefright/Utils.h>
307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang#include "include/AwesomePlayer.h"
31965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include "TimedTextPlayer.h"
32965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include "TimedTextParser.h"
337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangnamespace android {
357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstruct TimedTextEvent : public TimedEventQueue::Event {
377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent(
387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            TimedTextPlayer *player,
397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            void (TimedTextPlayer::*method)())
407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        : mPlayer(player),
417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang          mMethod(method) {
427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangprotected:
457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    virtual ~TimedTextEvent() {}
467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        (mPlayer->*mMethod)();
497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangprivate:
527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextPlayer *mPlayer;
537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    void (TimedTextPlayer::*mMethod)();
547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent(const TimedTextEvent &);
567a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    TimedTextEvent &operator=(const TimedTextEvent &);
577a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang};
587a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
597a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria WangTimedTextPlayer::TimedTextPlayer(
607a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        AwesomePlayer *observer,
617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        const wp<MediaPlayerBase> &listener,
627a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        TimedEventQueue *queue)
637a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    : mSource(NULL),
64965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang      mOutOfBandSource(NULL),
657a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mSeekTimeUs(0),
667a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mStarted(false),
677a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mTextEventPending(false),
687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mQueue(queue),
697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mListener(listener),
707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang      mObserver(observer),
71965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang      mTextBuffer(NULL),
72965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang      mTextParser(NULL),
73965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang      mTextType(kNoText) {
747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEvent = new TimedTextEvent(this, &TimedTextPlayer::onTextEvent);
757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria WangTimedTextPlayer::~TimedTextPlayer() {
787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mStarted) {
797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        reset();
807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextTrackVector.clear();
83965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    mTextOutOfBandVector.clear();
847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::start(uint8_t index) {
877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(!mStarted);
887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
89965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (index >=
90965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextTrackVector.size() + mTextOutOfBandVector.size()) {
91965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        LOGE("Incorrect text track index: %d", index);
927a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return BAD_VALUE;
937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
95965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (index < mTextTrackVector.size()) { // start an in-band text
96965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mSource = mTextTrackVector.itemAt(index);
977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
98965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        status_t err = mSource->start();
997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
100965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (err != OK) {
101965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return err;
102965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
103965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mTextType = kInBandText;
104965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    } else { // start an out-of-band text
105965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        OutOfBandText text =
106965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextOutOfBandVector.itemAt(index - mTextTrackVector.size());
107965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
108965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mOutOfBandSource = text.source;
109965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        TimedTextParser::FileType fileType = text.type;
110965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
111965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextParser == NULL) {
112965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextParser = new TimedTextParser();
113965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
114965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
115965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        status_t err;
116965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if ((err = mTextParser->init(mOutOfBandSource, fileType)) != OK) {
117965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return err;
118965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
119965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mTextType = kOutOfBandText;
1207a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1217a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1227a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    int64_t positionUs;
1237a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mObserver->getPosition(&positionUs);
1247a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    seekTo(positionUs);
1257a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1267a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    postTextEvent();
1277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mStarted = true;
1297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
1317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::pause() {
1347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    cancelTextEvent();
1377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::resume() {
1407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    postTextEvent();
1437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::reset() {
1467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    CHECK(mStarted);
1477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    // send an empty text to clear the screen
1497a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    notifyListener(MEDIA_TIMED_TEXT);
1507a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1517a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    cancelTextEvent();
1527a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1537a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeeking = false;
1547a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mStarted = false;
1557a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
156965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (mTextType == kInBandText) {
157965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextBuffer != NULL) {
158965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextBuffer->release();
159965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextBuffer = NULL;
160965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
1617a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
162965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mSource != NULL) {
163965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mSource->stop();
164965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mSource.clear();
165965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mSource = NULL;
166965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
167965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    } else {
168965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextParser != NULL) {
169965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextParser.clear();
170965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextParser = NULL;
171965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
172965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mOutOfBandSource != NULL) {
173965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mOutOfBandSource.clear();
174965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mOutOfBandSource = NULL;
175965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
1767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::seekTo(int64_t time_us) {
1807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    Mutex::Autolock autoLock(mLock);
1817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeeking = true;
1837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mSeekTimeUs = time_us;
1847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
185965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    postTextEvent();
186965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
1877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
1887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
1897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangstatus_t TimedTextPlayer::setTimedTextTrackIndex(int32_t index) {
191965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (index >=
192965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            (int)(mTextTrackVector.size() + mTextOutOfBandVector.size())) {
1937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return BAD_VALUE;
1947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
1967a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mStarted) {
1977a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        reset();
1987a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
1997a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2007a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (index >= 0) {
2017a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return start(index);
2027a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2037a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    return OK;
2047a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2057a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2067a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::onTextEvent() {
2077a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    Mutex::Autolock autoLock(mLock);
2087a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2097a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (!mTextEventPending) {
2107a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return;
2117a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2127a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = false;
2137a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2147a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    MediaSource::ReadOptions options;
2157a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mSeeking) {
2167a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        options.setSeekTo(mSeekTimeUs,
2177a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
2187a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        mSeeking = false;
2197a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
220965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextType == kInBandText) {
221965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            if (mTextBuffer != NULL) {
222965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                mTextBuffer->release();
223965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                mTextBuffer = NULL;
224965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            }
225965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        } else {
226965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mText.clear();
2277a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
2287a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2297a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        notifyListener(MEDIA_TIMED_TEXT); //empty text to clear the screen
2307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
232965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    int64_t positionUs, timeUs;
233965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    mObserver->getPosition(&positionUs);
2347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (mTextType == kInBandText) {
236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextBuffer != NULL) {
237965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            uint8_t *tmp = (uint8_t *)(mTextBuffer->data());
238965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            size_t len = (*tmp) << 8 | (*(tmp + 1));
2397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
240965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            notifyListener(MEDIA_TIMED_TEXT,
241965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                           tmp + 2,
242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                           len);
2437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
244965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextBuffer->release();
245965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mTextBuffer = NULL;
2467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
247965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
2487a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
249965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mSource->read(&mTextBuffer, &options) != OK) {
250965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return;
251965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
252965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
253965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mTextBuffer->meta_data()->findInt64(kKeyTime, &timeUs);
254965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    } else {
255965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mText.size() > 0) {
256965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            notifyListener(MEDIA_TIMED_TEXT,
257965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                           mText.c_str(),
258965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                           mText.size());
259965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mText.clear();
260965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
261965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
262965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        int64_t endTimeUs;
263965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (mTextParser->getText(
264965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                    &mText, &timeUs, &endTimeUs, &options) != OK) {
265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return;
266965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
2687a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2697a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    //send the text now
2707a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (timeUs <= positionUs + 100000ll) {
2717a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        postTextEvent();
2727a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    } else {
2737a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        postTextEvent(timeUs - positionUs - 100000ll);
2747a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2757a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2767a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2777a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::postTextEvent(int64_t delayUs) {
2787a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mTextEventPending) {
2797a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        return;
2807a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
2817a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2827a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = true;
2837a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mQueue->postEventWithDelay(mTextEvent, delayUs < 0 ? 10000 : delayUs);
2847a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2857a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2867a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::cancelTextEvent() {
2877a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mQueue->cancelEvent(mTextEvent->eventID());
2887a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextEventPending = false;
2897a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2907a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
2917a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::addTextSource(sp<MediaSource> source) {
292965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    Mutex::Autolock autoLock(mLock);
2937a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    mTextTrackVector.add(source);
2947a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
2957a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
296965d08ba16ee82bc85f69546360c18e7da907406Gloria Wangstatus_t TimedTextPlayer::setParameter(int key, const Parcel &request) {
297965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    Mutex::Autolock autoLock(mLock);
298965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
299965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (key == KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE) {
300965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        String8 uri = request.readString8();
301965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        KeyedVector<String8, String8> headers;
302965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
303965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        // To support local subtitle file only for now
304965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (strncasecmp("file://", uri.string(), 7)) {
305965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return INVALID_OPERATION;
306965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
307965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        sp<DataSource> dataSource =
308965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            DataSource::CreateFromURI(uri, &headers);
309965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        status_t err = dataSource->initCheck();
310965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
311965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (err != OK) {
312965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return err;
313965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
314965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
315965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        OutOfBandText text;
316965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        text.source = dataSource;
317965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if (uri.getPathExtension() == String8(".srt")) {
318965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            text.type = TimedTextParser::OUT_OF_BAND_FILE_SRT;
319965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        } else {
320965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return ERROR_UNSUPPORTED;
321965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
322965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
323965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        mTextOutOfBandVector.add(text);
324965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
325965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return OK;
326965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
327965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    return INVALID_OPERATION;
328965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
329965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
3307a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wangvoid TimedTextPlayer::notifyListener(
3317a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        int msg, const void *data, size_t size) {
3327a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    if (mListener != NULL) {
3337a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        sp<MediaPlayerBase> listener = mListener.promote();
3347a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
3357a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        if (listener != NULL) {
3367a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            if (size > 0) {
3377a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                mData.freeData();
3387a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                mData.write(data, size);
3397a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang
3407a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                listener->sendEvent(msg, 0, 0, &mData);
3417a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            } else { // send an empty timed text to clear the screen
3427a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang                listener->sendEvent(msg);
3437a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang            }
3447a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang        }
3457a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang    }
3467a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
3477a1e3e81264189e23a1db2b174e1b5a5d4c7d1c3Gloria Wang}
348