TimedTextDriver.cpp revision 25736fd247ba757feefe15d3071f7e747c64fea4
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> 26613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong#include <media/stagefright/FileSource.h> 27f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MediaDefs.h> 286655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h> 296655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h> 30f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MetaData.h> 316655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/Utils.h> 326655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ADebug.h> 336655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ALooper.h> 343254b25e8b0f674ccc2226609e01dd86a600802eInsun Kang#include <media/stagefright/timedtext/TimedTextDriver.h> 356655174826330afe66ef766258181ae8c11f3f6cInsun Kang 366655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h" 376655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextPlayer.h" 386655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSource.h" 396655174826330afe66ef766258181ae8c11f3f6cInsun Kang 406655174826330afe66ef766258181ae8c11f3f6cInsun Kangnamespace android { 416655174826330afe66ef766258181ae8c11f3f6cInsun Kang 426655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::TimedTextDriver( 436655174826330afe66ef766258181ae8c11f3f6cInsun Kang const wp<MediaPlayerBase> &listener) 446655174826330afe66ef766258181ae8c11f3f6cInsun Kang : mLooper(new ALooper), 456655174826330afe66ef766258181ae8c11f3f6cInsun Kang mListener(listener), 466655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState(UNINITIALIZED) { 476655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->setName("TimedTextDriver"); 486655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->start(); 496655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer = new TimedTextPlayer(listener); 506655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->registerHandler(mPlayer); 516655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 526655174826330afe66ef766258181ae8c11f3f6cInsun Kang 536655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::~TimedTextDriver() { 54f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.clear(); 556655174826330afe66ef766258181ae8c11f3f6cInsun Kang mLooper->stop(); 566655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 576655174826330afe66ef766258181ae8c11f3f6cInsun Kang 58f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::selectTrack_l(int32_t index) { 59f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (index >= (int)(mTextSourceVector.size())) { 606655174826330afe66ef766258181ae8c11f3f6cInsun Kang return BAD_VALUE; 616655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 626655174826330afe66ef766258181ae8c11f3f6cInsun Kang 636655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 64f9d660a5e0196240add5daf0199f128d471e592cInsun Kang source = mTextSourceVector.itemAt(index); 656655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->setDataSource(source); 66f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (mState == UNINITIALIZED) { 67f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mState = PAUSED; 68f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 69f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mCurrentTrackIndex = index; 706655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 716655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 726655174826330afe66ef766258181ae8c11f3f6cInsun Kang 736655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::start() { 746655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 756655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 766655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 776655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 786655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 796655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 806655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 81f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mPlayer->start(); 826655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 836655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 846655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 856655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 866655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PLAYING; 876655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 886655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 896655174826330afe66ef766258181ae8c11f3f6cInsun Kang 906655174826330afe66ef766258181ae8c11f3f6cInsun Kang// TODO: Test if pause() works properly. 916655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 1: start - pause - resume 926655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 2: start - seek 936655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 3: start - pause - seek - resume 946655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::pause() { 956655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 966655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 976655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 986655174826330afe66ef766258181ae8c11f3f6cInsun Kang return INVALID_OPERATION; 996655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1026655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 1036655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1046655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 1056655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1066655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1076655174826330afe66ef766258181ae8c11f3f6cInsun Kang mState = PAUSED; 1086655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1096655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1106655174826330afe66ef766258181ae8c11f3f6cInsun Kang 111f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::selectTrack(int32_t index) { 1126655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t ret = OK; 1136655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (mState) { 1156655174826330afe66ef766258181ae8c11f3f6cInsun Kang case UNINITIALIZED: 1166655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PAUSED: 117f9d660a5e0196240add5daf0199f128d471e592cInsun Kang ret = selectTrack_l(index); 1186655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang case PLAYING: 1206655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->pause(); 121f9d660a5e0196240add5daf0199f128d471e592cInsun Kang ret = selectTrack_l(index); 1226655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (ret != OK) { 1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1246655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1256655174826330afe66ef766258181ae8c11f3f6cInsun Kang mPlayer->start(); 1266655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1276655174826330afe66ef766258181ae8c11f3f6cInsun Kang defaut: 1286655174826330afe66ef766258181ae8c11f3f6cInsun Kang TRESPASS(); 1296655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1306655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ret; 1316655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1326655174826330afe66ef766258181ae8c11f3f6cInsun Kang 133f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::unselectTrack(int32_t index) { 134f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (mCurrentTrackIndex != index) { 135f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return INVALID_OPERATION; 136f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 137f9d660a5e0196240add5daf0199f128d471e592cInsun Kang status_t err = pause(); 138f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (err != OK) { 139f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return err; 140f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 141f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Mutex::Autolock autoLock(mLock); 142f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mState = UNINITIALIZED; 143f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 144f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 145f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 146f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::seekToAsync(int64_t timeUs) { 147f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mPlayer->seekToAsync(timeUs); 148f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 149f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 150f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 1516655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addInBandTextSource( 1526655174826330afe66ef766258181ae8c11f3f6cInsun Kang const sp<MediaSource>& mediaSource) { 1536655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source = 1546655174826330afe66ef766258181ae8c11f3f6cInsun Kang TimedTextSource::CreateTimedTextSource(mediaSource); 1556655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 1566655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1576655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1586655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 159f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.add(source); 1606655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1616655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 1626655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1636655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource( 164f9d660a5e0196240add5daf0199f128d471e592cInsun Kang const char *uri, const char *mimeType) { 1656655174826330afe66ef766258181ae8c11f3f6cInsun Kang // To support local subtitle file only for now 166f9d660a5e0196240add5daf0199f128d471e592cInsun Kang if (strncasecmp("file://", uri, 7)) { 167613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong ALOGE("uri('%s') is not a file", uri); 1686655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1696655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 170613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 1716655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<DataSource> dataSource = 1726655174826330afe66ef766258181ae8c11f3f6cInsun Kang DataSource::CreateFromURI(uri); 173613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong return createOutOfBandTextSource(mimeType, dataSource); 174613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong} 175613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 176613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::addOutOfBandTextSource( 177613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong int fd, off64_t offset, off64_t length, const char *mimeType) { 178613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 179613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong if (fd < 0) { 180613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong ALOGE("Invalid file descriptor: %d", fd); 181613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong return ERROR_UNSUPPORTED; 182613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong } 183613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 184613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong sp<DataSource> dataSource = new FileSource(dup(fd), offset, length); 185613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong return createOutOfBandTextSource(mimeType, dataSource); 186613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong} 187613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 188613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::createOutOfBandTextSource( 189613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong const char *mimeType, const sp<DataSource>& dataSource) { 190613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong 1916655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (dataSource == NULL) { 1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang 1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang sp<TimedTextSource> source; 1967c5afe93c9ca2f9f3958663bc3fa9649ec2f5331Insun Kang if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP) == 0) { 1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang source = TimedTextSource::CreateTimedTextSource( 1986655174826330afe66ef766258181ae8c11f3f6cInsun Kang dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT); 1996655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (source == NULL) { 2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_UNSUPPORTED; 2036655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2046655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2056655174826330afe66ef766258181ae8c11f3f6cInsun Kang Mutex::Autolock autoLock(mLock); 206f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mTextSourceVector.add(source); 207f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return OK; 208f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang 210f9d660a5e0196240add5daf0199f128d471e592cInsun Kangvoid TimedTextDriver::getTrackInfo(Parcel *parcel) { 211f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Mutex::Autolock autoLock(mLock); 212f9d660a5e0196240add5daf0199f128d471e592cInsun Kang Vector<sp<TimedTextSource> >::const_iterator iter; 213f9d660a5e0196240add5daf0199f128d471e592cInsun Kang parcel->writeInt32(mTextSourceVector.size()); 214f9d660a5e0196240add5daf0199f128d471e592cInsun Kang for (iter = mTextSourceVector.begin(); 215f9d660a5e0196240add5daf0199f128d471e592cInsun Kang iter != mTextSourceVector.end(); ++iter) { 216f9d660a5e0196240add5daf0199f128d471e592cInsun Kang sp<MetaData> meta = (*iter)->getFormat(); 217f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 21825736fd247ba757feefe15d3071f7e747c64fea4Insun Kang // There are two fields. 21925736fd247ba757feefe15d3071f7e747c64fea4Insun Kang parcel->writeInt32(2); 22025736fd247ba757feefe15d3071f7e747c64fea4Insun Kang 22125736fd247ba757feefe15d3071f7e747c64fea4Insun Kang // track type. 22225736fd247ba757feefe15d3071f7e747c64fea4Insun Kang parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT); 223f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 22425736fd247ba757feefe15d3071f7e747c64fea4Insun Kang const char *lang = "und"; 22525736fd247ba757feefe15d3071f7e747c64fea4Insun Kang if (meta != NULL) { 226f9d660a5e0196240add5daf0199f128d471e592cInsun Kang meta->findCString(kKeyMediaLanguage, &lang); 227f9d660a5e0196240add5daf0199f128d471e592cInsun Kang } 22825736fd247ba757feefe15d3071f7e747c64fea4Insun Kang parcel->writeString16(String16(lang)); 2296655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2306655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2316655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2326655174826330afe66ef766258181ae8c11f3f6cInsun Kang} // namespace android 233