TimedTextDriver.cpp revision 3254b25e8b0f674ccc2226609e01dd86a600802e
16655174826330afe66ef766258181ae8c11f3f6cInsun Kang /* 26655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Copyright (C) 2012 The Android Open Source Project 36655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 46655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Licensed under the Apache License, Version 2.0 (the "License"); 56655174826330afe66ef766258181ae8c11f3f6cInsun Kang * you may not use this file except in compliance with the License. 66655174826330afe66ef766258181ae8c11f3f6cInsun Kang * You may obtain a copy of the License at 76655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 86655174826330afe66ef766258181ae8c11f3f6cInsun Kang * http://www.apache.org/licenses/LICENSE-2.0 96655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 106655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Unless required by applicable law or agreed to in writing, software 116655174826330afe66ef766258181ae8c11f3f6cInsun Kang * distributed under the License is distributed on an "AS IS" BASIS, 126655174826330afe66ef766258181ae8c11f3f6cInsun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136655174826330afe66ef766258181ae8c11f3f6cInsun Kang * See the License for the specific language governing permissions and 146655174826330afe66ef766258181ae8c11f3f6cInsun Kang * limitations under the License. 156655174826330afe66ef766258181ae8c11f3f6cInsun Kang */ 166655174826330afe66ef766258181ae8c11f3f6cInsun Kang 176655174826330afe66ef766258181ae8c11f3f6cInsun Kang//#define LOG_NDEBUG 0 186655174826330afe66ef766258181ae8c11f3f6cInsun Kang#define LOG_TAG "TimedTextDriver" 196655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <utils/Log.h> 206655174826330afe66ef766258181ae8c11f3f6cInsun Kang 216655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <binder/IPCThreadState.h> 226655174826330afe66ef766258181ae8c11f3f6cInsun Kang 236655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/MediaPlayerInterface.h> 246655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h> 256655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h> 266655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/DataSource.h> 276655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/Utils.h> 286655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ADebug.h> 296655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ALooper.h> 303254b25e8b0f674ccc2226609e01dd86a600802eInsun Kang#include <media/stagefright/timedtext/TimedTextDriver.h> 316655174826330afe66ef766258181ae8c11f3f6cInsun Kang 326655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h" 336655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextPlayer.h" 346655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSource.h" 356655174826330afe66ef766258181ae8c11f3f6cInsun Kang 366655174826330afe66ef766258181ae8c11f3f6cInsun Kangnamespace android { 376655174826330afe66ef766258181ae8c11f3f6cInsun Kang 386655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::TimedTextDriver( 396655174826330afe66ef766258181ae8c11f3f6cInsun Kang const wp<MediaPlayerBase> &listener) 406655174826330afe66ef766258181ae8c11f3f6cInsun Kang : mLooper(new ALooper), 416655174826330afe66ef766258181ae8c11f3f6cInsun Kang mListener(listener), 426655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState(UNINITIALIZED) { 436655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->setName("TimedTextDriver"); 446655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->start(); 456655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer = new TimedTextPlayer(listener); 466655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->registerHandler(mPlayer); 476655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 486655174826330afe66ef766258181ae8c11f3f6cInsun Kang 496655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::~TimedTextDriver() { 506655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextInBandVector.clear(); 516655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextOutOfBandVector.clear(); 526655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->stop(); 536655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 546655174826330afe66ef766258181ae8c11f3f6cInsun Kang 556655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::setTimedTextTrackIndex_l(int32_t index) { 566655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (index >= 576655174826330afe66ef766258181ae8c11f3f6cInsun Kang (int)(mTextInBandVector.size() + mTextOutOfBandVector.size())) { 586655174826330afe66ef766258181ae8c11f3f6cInsun Kang return BAD_VALUE; 596655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 606655174826330afe66ef766258181ae8c11f3f6cInsun Kang 616655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 626655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (index < mTextInBandVector.size()) { 636655174826330afe66ef766258181ae8c11f3f6cInsun Kang source = mTextInBandVector.itemAt(index); 646655174826330afe66ef766258181ae8c11f3f6cInsun Kang } else { 656655174826330afe66ef766258181ae8c11f3f6cInsun Kang source = mTextOutOfBandVector.itemAt(index - mTextInBandVector.size()); 666655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 676655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->setDataSource(source); 686655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 696655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 706655174826330afe66ef766258181ae8c11f3f6cInsun Kang 716655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::start() { 726655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 736655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 746655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 756655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 766655174826330afe66ef766258181ae8c11f3f6cInsun Kang case STOPPED: 776655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->start(); 786655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 796655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 806655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 816655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 826655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->resume(); 836655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 846655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 856655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 866655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 876655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PLAYING; 886655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 896655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 906655174826330afe66ef766258181ae8c11f3f6cInsun Kang 916655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::stop() { 926655174826330afe66ef766258181ae8c11f3f6cInsun Kang return pause(); 936655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 946655174826330afe66ef766258181ae8c11f3f6cInsun Kang 956655174826330afe66ef766258181ae8c11f3f6cInsun Kang// TODO: Test if pause() works properly. 966655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 1: start - pause - resume 976655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 2: start - seek 986655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 3: start - pause - seek - resume 996655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::pause() { 1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 1026655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 1036655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 1046655174826330afe66ef766258181ae8c11f3f6cInsun Kang case STOPPED: 1056655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1066655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 1076655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 1086655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1096655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 1106655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1116655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 1126655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1136655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PAUSED; 1156655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1166655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1176655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1186655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::resume() { 1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang return start(); 1206655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1216655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1226655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::seekToAsync(int64_t timeUs) { 1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->seekToAsync(timeUs); 1246655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1256655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1266655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1276655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::setTimedTextTrackIndex(int32_t index) { 1286655174826330afe66ef766258181ae8c11f3f6cInsun Kang // TODO: This is current implementation for MediaPlayer::disableTimedText(). 1296655174826330afe66ef766258181ae8c11f3f6cInsun Kang // Find better way for readability. 1306655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (index < 0) { 1316655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 1326655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1336655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1346655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1356655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t ret = OK; 1366655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 1376655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 1386655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 1396655174826330afe66ef766258181ae8c11f3f6cInsun Kang ret = INVALID_OPERATION; 1406655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1416655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 1426655174826330afe66ef766258181ae8c11f3f6cInsun Kang ret = setTimedTextTrackIndex_l(index); 1436655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1446655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 1456655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 1466655174826330afe66ef766258181ae8c11f3f6cInsun Kang ret = setTimedTextTrackIndex_l(index); 1476655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (ret != OK) { 1486655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1496655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1506655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->start(); 1516655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1526655174826330afe66ef766258181ae8c11f3f6cInsun Kang case STOPPED: 1536655174826330afe66ef766258181ae8c11f3f6cInsun Kang // TODO: The only difference between STOPPED and PAUSED is this 1546655174826330afe66ef766258181ae8c11f3f6cInsun Kang // part. Revise the flow from "MediaPlayer::enableTimedText()" and 1556655174826330afe66ef766258181ae8c11f3f6cInsun Kang // remove one of the status, PAUSED and STOPPED, if possible. 1566655174826330afe66ef766258181ae8c11f3f6cInsun Kang ret = setTimedTextTrackIndex_l(index); 1576655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (ret != OK) { 1586655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1596655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1606655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->start(); 1616655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1626655174826330afe66ef766258181ae8c11f3f6cInsun Kang defaut: 1636655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1646655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1656655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ret; 1666655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1676655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1686655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addInBandTextSource( 1696655174826330afe66ef766258181ae8c11f3f6cInsun Kang const sp<MediaSource>& mediaSource) { 1706655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source = 1716655174826330afe66ef766258181ae8c11f3f6cInsun Kang TimedTextSource::CreateTimedTextSource(mediaSource); 1726655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 1736655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1746655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1756655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 1766655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextInBandVector.add(source); 1776655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (mState == UNINITIALIZED) { 1786655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = STOPPED; 1796655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1806655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1826655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1836655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource( 1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang const Parcel &request) { 1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang // TODO: Define "TimedTextSource::CreateFromURI(uri)" 1866655174826330afe66ef766258181ae8c11f3f6cInsun Kang // and move below lines there..? 1876655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1886655174826330afe66ef766258181ae8c11f3f6cInsun Kang // String values written in Parcel are UTF-16 values. 1896655174826330afe66ef766258181ae8c11f3f6cInsun Kang const String16 uri16 = request.readString16(); 1906655174826330afe66ef766258181ae8c11f3f6cInsun Kang String8 uri = String8(request.readString16()); 1916655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang uri.toLower(); 1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang // To support local subtitle file only for now 1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (strncasecmp("file://", uri.string(), 7)) { 1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1966655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<DataSource> dataSource = 1986655174826330afe66ef766258181ae8c11f3f6cInsun Kang DataSource::CreateFromURI(uri); 1996655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (dataSource == NULL) { 2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2036655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 2046655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (uri.getPathExtension() == String8(".srt")) { 2056655174826330afe66ef766258181ae8c11f3f6cInsun Kang source = TimedTextSource::CreateTimedTextSource( 2066655174826330afe66ef766258181ae8c11f3f6cInsun Kang dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT); 2076655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2086655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 2116655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2126655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2136655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 2146655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2156655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextOutOfBandVector.add(source); 2166655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (mState == UNINITIALIZED) { 2176655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = STOPPED; 2186655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2196655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2206655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2216655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2226655174826330afe66ef766258181ae8c11f3f6cInsun Kang} // namespace android 223