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