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