TimedTextDriver.cpp revision f9d660a5e0196240add5daf0199f128d471e592c
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 23f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/mediaplayer.h> 246655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/MediaPlayerInterface.h> 25f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/DataSource.h> 26f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MediaDefs.h> 276655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h> 286655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h> 29f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MetaData.h> 306655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/Utils.h> 316655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ADebug.h> 326655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ALooper.h> 333254b25e8b0f674ccc2226609e01dd86a600802eInsun Kang#include <media/stagefright/timedtext/TimedTextDriver.h> 346655174826330afe66ef766258181ae8c11f3f6cInsun Kang 356655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h" 366655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextPlayer.h" 376655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSource.h" 386655174826330afe66ef766258181ae8c11f3f6cInsun Kang 396655174826330afe66ef766258181ae8c11f3f6cInsun Kangnamespace android { 406655174826330afe66ef766258181ae8c11f3f6cInsun Kang 416655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::TimedTextDriver( 426655174826330afe66ef766258181ae8c11f3f6cInsun Kang const wp<MediaPlayerBase> &listener) 436655174826330afe66ef766258181ae8c11f3f6cInsun Kang : mLooper(new ALooper), 446655174826330afe66ef766258181ae8c11f3f6cInsun Kang mListener(listener), 456655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState(UNINITIALIZED) { 466655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->setName("TimedTextDriver"); 476655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->start(); 486655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer = new TimedTextPlayer(listener); 496655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->registerHandler(mPlayer); 506655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 516655174826330afe66ef766258181ae8c11f3f6cInsun Kang 526655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::~TimedTextDriver() { 53f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.clear(); 546655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->stop(); 556655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 566655174826330afe66ef766258181ae8c11f3f6cInsun Kang 57f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::selectTrack_l(int32_t index) { 58f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (index >= (int)(mTextSourceVector.size())) { 596655174826330afe66ef766258181ae8c11f3f6cInsun Kang return BAD_VALUE; 606655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 616655174826330afe66ef766258181ae8c11f3f6cInsun Kang 626655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 63f9d660a5e0196240add5daf0199f128d471e592cInsun Kang source = mTextSourceVector.itemAt(index); 646655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->setDataSource(source); 65f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (mState == UNINITIALIZED) { 66f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mState = PAUSED; 67f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 68f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mCurrentTrackIndex = index; 696655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 706655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 716655174826330afe66ef766258181ae8c11f3f6cInsun Kang 726655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::start() { 736655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 746655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 756655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 766655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 776655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 786655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 796655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 80f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mPlayer->start(); 816655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 826655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 836655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 846655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 856655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PLAYING; 866655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 876655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 886655174826330afe66ef766258181ae8c11f3f6cInsun Kang 896655174826330afe66ef766258181ae8c11f3f6cInsun Kang// TODO: Test if pause() works properly. 906655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 1: start - pause - resume 916655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 2: start - seek 926655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 3: start - pause - seek - resume 936655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::pause() { 946655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 956655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 966655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 976655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 986655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 996655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 1026655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1036655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 1046655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1056655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1066655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PAUSED; 1076655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1086655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1096655174826330afe66ef766258181ae8c11f3f6cInsun Kang 110f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::selectTrack(int32_t index) { 1116655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t ret = OK; 1126655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 1136655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 1156655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 116f9d660a5e0196240add5daf0199f128d471e592cInsun Kang ret = selectTrack_l(index); 1176655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1186655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 120f9d660a5e0196240add5daf0199f128d471e592cInsun Kang ret = selectTrack_l(index); 1216655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (ret != OK) { 1226655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1246655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->start(); 1256655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1266655174826330afe66ef766258181ae8c11f3f6cInsun Kang defaut: 1276655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1286655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1296655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ret; 1306655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1316655174826330afe66ef766258181ae8c11f3f6cInsun Kang 132f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::unselectTrack(int32_t index) { 133f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (mCurrentTrackIndex != index) { 134f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return INVALID_OPERATION; 135f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 136f9d660a5e0196240add5daf0199f128d471e592cInsun Kang status_t err = pause(); 137f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (err != OK) { 138f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return err; 139f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 140f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Mutex::Autolock autoLock(mLock); 141f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mState = UNINITIALIZED; 142f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 143f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 144f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 145f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::seekToAsync(int64_t timeUs) { 146f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mPlayer->seekToAsync(timeUs); 147f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 148f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 149f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 1506655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addInBandTextSource( 1516655174826330afe66ef766258181ae8c11f3f6cInsun Kang const sp<MediaSource>& mediaSource) { 1526655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source = 1536655174826330afe66ef766258181ae8c11f3f6cInsun Kang TimedTextSource::CreateTimedTextSource(mediaSource); 1546655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 1556655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1566655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1576655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 158f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.add(source); 1596655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1606655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1616655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1626655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource( 163f9d660a5e0196240add5daf0199f128d471e592cInsun Kang const char *uri, const char *mimeType) { 1646655174826330afe66ef766258181ae8c11f3f6cInsun Kang // TODO: Define "TimedTextSource::CreateFromURI(uri)" 1656655174826330afe66ef766258181ae8c11f3f6cInsun Kang // and move below lines there..? 1666655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1676655174826330afe66ef766258181ae8c11f3f6cInsun Kang // To support local subtitle file only for now 168f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (strncasecmp("file://", uri, 7)) { 1696655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1706655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1716655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<DataSource> dataSource = 1726655174826330afe66ef766258181ae8c11f3f6cInsun Kang DataSource::CreateFromURI(uri); 1736655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (dataSource == NULL) { 1746655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1756655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1766655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1776655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 178f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP)) { 1796655174826330afe66ef766258181ae8c11f3f6cInsun Kang source = TimedTextSource::CreateTimedTextSource( 1806655174826330afe66ef766258181ae8c11f3f6cInsun Kang dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT); 1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1826655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1836655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1866655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1876655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 188f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.add(source); 189f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 190f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 1916655174826330afe66ef766258181ae8c11f3f6cInsun Kang 192f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource( 193f9d660a5e0196240add5daf0199f128d471e592cInsun Kang int fd, off64_t offset, size_t length, const char *mimeType) { 194f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // Not supported yet. This requires DataSource::sniff to detect various text 195f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // formats such as srt/smi/ttml. 196f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return ERROR_UNSUPPORTED; 197f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 198f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 199f9d660a5e0196240add5daf0199f128d471e592cInsun Kangvoid TimedTextDriver::getTrackInfo(Parcel *parcel) { 200f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Mutex::Autolock autoLock(mLock); 201f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Vector<sp<TimedTextSource> >::const_iterator iter; 202f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeInt32(mTextSourceVector.size()); 203f9d660a5e0196240add5daf0199f128d471e592cInsun Kang for (iter = mTextSourceVector.begin(); 204f9d660a5e0196240add5daf0199f128d471e592cInsun Kang iter != mTextSourceVector.end(); ++iter) { 205f9d660a5e0196240add5daf0199f128d471e592cInsun Kang sp<MetaData> meta = (*iter)->getFormat(); 206f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (meta != NULL) { 207f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // There are two fields. 208f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeInt32(2); 209f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 210f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // track type. 211f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); 212f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 213f9d660a5e0196240add5daf0199f128d471e592cInsun Kang const char *lang = "und"; 214f9d660a5e0196240add5daf0199f128d471e592cInsun Kang meta->findCString(kKeyMediaLanguage, &lang); 215f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeString16(String16(lang)); 216f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } else { 217f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeInt32(0); 218f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 2196655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2206655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2216655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2226655174826330afe66ef766258181ae8c11f3f6cInsun Kang} // namespace android 223