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
231b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
24f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/mediaplayer.h>
256655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/MediaPlayerInterface.h>
26f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/DataSource.h>
27613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong#include <media/stagefright/FileSource.h>
28f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MediaDefs.h>
296655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h>
306655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h>
31f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MetaData.h>
326655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/Utils.h>
336655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ADebug.h>
346655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/ALooper.h>
353254b25e8b0f674ccc2226609e01dd86a600802eInsun Kang#include <media/stagefright/timedtext/TimedTextDriver.h>
366655174826330afe66ef766258181ae8c11f3f6cInsun Kang
376655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h"
386655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextPlayer.h"
396655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSource.h"
406655174826330afe66ef766258181ae8c11f3f6cInsun Kang
416655174826330afe66ef766258181ae8c11f3f6cInsun Kangnamespace android {
426655174826330afe66ef766258181ae8c11f3f6cInsun Kang
436655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::TimedTextDriver(
441b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const wp<MediaPlayerBase> &listener,
451b86fe063badb5f28c467ade39be0f4008688947Andreas Huber        const sp<IMediaHTTPService> &httpService)
466655174826330afe66ef766258181ae8c11f3f6cInsun Kang    : mLooper(new ALooper),
476655174826330afe66ef766258181ae8c11f3f6cInsun Kang      mListener(listener),
480f37620e0f79bfab1354e2e3049c260342a2637eColin Cross      mHTTPService(httpService),
4923580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang      mState(UNINITIALIZED),
5023580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang      mCurrentTrackIndex(UINT_MAX) {
516655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mLooper->setName("TimedTextDriver");
526655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mLooper->start();
536655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mPlayer = new TimedTextPlayer(listener);
546655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mLooper->registerHandler(mPlayer);
556655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
566655174826330afe66ef766258181ae8c11f3f6cInsun Kang
576655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextDriver::~TimedTextDriver() {
58f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    mTextSourceVector.clear();
59eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceTypeVector.clear();
606655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mLooper->stop();
616655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
626655174826330afe66ef766258181ae8c11f3f6cInsun Kang
63eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::selectTrack_l(size_t index) {
6423580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang    if (mCurrentTrackIndex == index) {
6523580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang        return OK;
6623580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang    }
676655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source;
68eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    source = mTextSourceVector.valueFor(index);
696655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mPlayer->setDataSource(source);
70f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (mState == UNINITIALIZED) {
71c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        mState = PREPARED;
72f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
73f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    mCurrentTrackIndex = index;
746655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
756655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
766655174826330afe66ef766258181ae8c11f3f6cInsun Kang
776655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::start() {
786655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
796655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
806655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
816655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return INVALID_OPERATION;
826655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
836655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return OK;
84c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PREPARED:
85f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            mPlayer->start();
86bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mState = PLAYING;
87bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
88c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PAUSED:
89c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mPlayer->resume();
90c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mState = PLAYING;
91c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            return OK;
926655174826330afe66ef766258181ae8c11f3f6cInsun Kang        default:
936655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TRESPASS();
946655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
95bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    return UNKNOWN_ERROR;
966655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
976655174826330afe66ef766258181ae8c11f3f6cInsun Kang
986655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::pause() {
996655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
100c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang    ALOGV("%s() is called", __FUNCTION__);
1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
1026655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
1036655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return INVALID_OPERATION;
1046655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
1056655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->pause();
106bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mState = PAUSED;
107bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
108c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PREPARED:
109bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return INVALID_OPERATION;
110bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        case PAUSED:
111bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
112bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        default:
113bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            TRESPASS();
114bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    }
115bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    return UNKNOWN_ERROR;
1166655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
1176655174826330afe66ef766258181ae8c11f3f6cInsun Kang
118eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::selectTrack(size_t index) {
1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang    status_t ret = OK;
1206655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
121c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang    ALOGV("%s() is called", __FUNCTION__);
1226655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
124c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PREPARED:
1256655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PAUSED:
126f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            ret = selectTrack_l(index);
1276655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
1286655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
1296655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->pause();
130f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            ret = selectTrack_l(index);
1316655174826330afe66ef766258181ae8c11f3f6cInsun Kang            if (ret != OK) {
1326655174826330afe66ef766258181ae8c11f3f6cInsun Kang                break;
1336655174826330afe66ef766258181ae8c11f3f6cInsun Kang            }
1346655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->start();
1356655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
1366655174826330afe66ef766258181ae8c11f3f6cInsun Kang        defaut:
1376655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TRESPASS();
1386655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
1396655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return ret;
1406655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
1416655174826330afe66ef766258181ae8c11f3f6cInsun Kang
142eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::unselectTrack(size_t index) {
1436472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    Mutex::Autolock autoLock(mLock);
144c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang    ALOGV("%s() is called", __FUNCTION__);
145f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (mCurrentTrackIndex != index) {
146f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        return INVALID_OPERATION;
147f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
14823580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang    mCurrentTrackIndex = UINT_MAX;
1496472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    switch (mState) {
1506472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case UNINITIALIZED:
1516472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return INVALID_OPERATION;
1526472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case PLAYING:
15323580bb8d6cafbc2b65dd0a4ce1acb52562d1b05Insun Kang            mPlayer->setDataSource(NULL);
1546472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            mState = UNINITIALIZED;
1556472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return OK;
156c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PREPARED:
1576472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case PAUSED:
1586472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            mState = UNINITIALIZED;
1596472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return OK;
1606472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        default:
1616472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            TRESPASS();
162f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
1636472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    return UNKNOWN_ERROR;
164f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
165f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
166f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::seekToAsync(int64_t timeUs) {
1676472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    Mutex::Autolock autoLock(mLock);
168c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang    ALOGV("%s() is called", __FUNCTION__);
1696472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    switch (mState) {
1706472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case UNINITIALIZED:
1716472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return INVALID_OPERATION;
172c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang        case PREPARED:
173c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mPlayer->seekToAsync(timeUs);
174c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mPlayer->pause();
175c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mState = PAUSED;
176c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            return OK;
1776472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case PAUSED:
1786472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            mPlayer->seekToAsync(timeUs);
179c9729ca1cb1760da836e293e3ed7a82f769f3e07Insun Kang            mPlayer->pause();
1806472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return OK;
1816472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        case PLAYING:
1826472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            mPlayer->seekToAsync(timeUs);
1836472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            return OK;
1846472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang        defaut:
1856472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang            TRESPASS();
1866472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    }
1876472badc497a9e748411f8c8c9ed5d83ef335a85Insun Kang    return UNKNOWN_ERROR;
188f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
189f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
1906655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addInBandTextSource(
191eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, const sp<MediaSource>& mediaSource) {
1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source =
1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TimedTextSource::CreateTimedTextSource(mediaSource);
1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (source == NULL) {
1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
1966655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
198eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceVector.add(trackIndex, source);
199692ac36c4b6a09fed5113a4f45f00a041665a769James Dong    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_IN_BAND);
2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2036655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource(
204eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, const char *uri, const char *mimeType) {
205eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
2066655174826330afe66ef766258181ae8c11f3f6cInsun Kang    // To support local subtitle file only for now
207f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (strncasecmp("file://", uri, 7)) {
208613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        ALOGE("uri('%s') is not a file", uri);
2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
211613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
2126655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<DataSource> dataSource =
2131b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            DataSource::CreateFromURI(mHTTPService, uri);
214eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
215613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong}
216613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
217613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::addOutOfBandTextSource(
218eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) {
219613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
220613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    if (fd < 0) {
221613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        ALOGE("Invalid file descriptor: %d", fd);
222613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        return ERROR_UNSUPPORTED;
223613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    }
224613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
225613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
226eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
227613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong}
228613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
229613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::createOutOfBandTextSource(
230eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex,
231eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        const char *mimeType,
232eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        const sp<DataSource>& dataSource) {
233613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
2346655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (dataSource == NULL) {
2356655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
2366655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2376655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2386655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source;
2397c5afe93c9ca2f9f3958663bc3fa9649ec2f5331Insun Kang    if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP) == 0) {
2406655174826330afe66ef766258181ae8c11f3f6cInsun Kang        source = TimedTextSource::CreateTimedTextSource(
2416655174826330afe66ef766258181ae8c11f3f6cInsun Kang                dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT);
2426655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2436655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2446655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (source == NULL) {
245eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        ALOGE("Failed to create timed text source");
2466655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
2476655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2486655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2496655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
250eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceVector.add(trackIndex, source);
251692ac36c4b6a09fed5113a4f45f00a041665a769James Dong    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_OUT_OF_BAND);
252f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    return OK;
253f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
2546655174826330afe66ef766258181ae8c11f3f6cInsun Kang
255eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongsize_t TimedTextDriver::countExternalTracks() const {
256eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    size_t nTracks = 0;
257eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
258692ac36c4b6a09fed5113a4f45f00a041665a769James Dong        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_OUT_OF_BAND) {
259eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong            ++nTracks;
260eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        }
261eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    }
262eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return nTracks;
263eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong}
264eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
265eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongvoid TimedTextDriver::getExternalTrackInfo(Parcel *parcel) {
266f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    Mutex::Autolock autoLock(mLock);
267eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
268692ac36c4b6a09fed5113a4f45f00a041665a769James Dong        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_IN_BAND) {
269eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong            continue;
270eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        }
271eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
272eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat();
273f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
27425736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        // There are two fields.
27525736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeInt32(2);
27625736fd247ba757feefe15d3071f7e747c64fea4Insun Kang
27725736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        // track type.
27825736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
27925736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        const char *lang = "und";
28025736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        if (meta != NULL) {
281f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            meta->findCString(kKeyMediaLanguage, &lang);
282f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        }
28325736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeString16(String16(lang));
2846655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2856655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
2866655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2876655174826330afe66ef766258181ae8c11f3f6cInsun Kang}  // namespace android
288