TimedTextDriver.cpp revision bb6bc8491fe819f96e1902e56694715cb110ce94
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();
55eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceTypeVector.clear();
566655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mLooper->stop();
576655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
586655174826330afe66ef766258181ae8c11f3f6cInsun Kang
59eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::selectTrack_l(size_t index) {
606655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source;
61eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    source = mTextSourceVector.valueFor(index);
626655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mPlayer->setDataSource(source);
63f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (mState == UNINITIALIZED) {
64f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        mState = PAUSED;
65f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
66f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    mCurrentTrackIndex = index;
676655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
686655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
696655174826330afe66ef766258181ae8c11f3f6cInsun Kang
706655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::start() {
716655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
726655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
736655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
746655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return INVALID_OPERATION;
756655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
766655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return OK;
776655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PAUSED:
78f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            mPlayer->start();
79bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mState = PLAYING;
80bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
816655174826330afe66ef766258181ae8c11f3f6cInsun Kang        default:
826655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TRESPASS();
836655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
84bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    return UNKNOWN_ERROR;
856655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
866655174826330afe66ef766258181ae8c11f3f6cInsun Kang
876655174826330afe66ef766258181ae8c11f3f6cInsun Kang// TODO: Test if pause() works properly.
886655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 1: start - pause - resume
896655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 2: start - seek
906655174826330afe66ef766258181ae8c11f3f6cInsun Kang// Scenario 3: start - pause - seek - resume
916655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::pause() {
926655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
936655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
946655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
956655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return INVALID_OPERATION;
966655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
976655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->pause();
98bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mState = PAUSED;
99bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PAUSED:
1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return OK;
1026655174826330afe66ef766258181ae8c11f3f6cInsun Kang        default:
1036655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TRESPASS();
1046655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
105bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    return UNKNOWN_ERROR;
106bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang}
107bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang
108bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kangstatus_t TimedTextDriver::resume() {
109bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    Mutex::Autolock autoLock(mLock);
110bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    switch (mState) {
111bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        case UNINITIALIZED:
112bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return INVALID_OPERATION;
113bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        case PLAYING:
114bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
115bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        case PAUSED:
116bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mPlayer->resume();
117bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            mState = PLAYING;
118bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            return OK;
119bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang        default:
120bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang            TRESPASS();
121bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    }
122bb6bc8491fe819f96e1902e56694715cb110ce94Insun Kang    return UNKNOWN_ERROR;
1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
1246655174826330afe66ef766258181ae8c11f3f6cInsun Kang
125eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::selectTrack(size_t index) {
1266655174826330afe66ef766258181ae8c11f3f6cInsun Kang    status_t ret = OK;
1276655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
1286655174826330afe66ef766258181ae8c11f3f6cInsun Kang    switch (mState) {
1296655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case UNINITIALIZED:
1306655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PAUSED:
131f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            ret = selectTrack_l(index);
1326655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
1336655174826330afe66ef766258181ae8c11f3f6cInsun Kang        case PLAYING:
1346655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->pause();
135f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            ret = selectTrack_l(index);
1366655174826330afe66ef766258181ae8c11f3f6cInsun Kang            if (ret != OK) {
1376655174826330afe66ef766258181ae8c11f3f6cInsun Kang                break;
1386655174826330afe66ef766258181ae8c11f3f6cInsun Kang            }
1396655174826330afe66ef766258181ae8c11f3f6cInsun Kang            mPlayer->start();
1406655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
1416655174826330afe66ef766258181ae8c11f3f6cInsun Kang        defaut:
1426655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TRESPASS();
1436655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
1446655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return ret;
1456655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
1466655174826330afe66ef766258181ae8c11f3f6cInsun Kang
147eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongstatus_t TimedTextDriver::unselectTrack(size_t index) {
148f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (mCurrentTrackIndex != index) {
149f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        return INVALID_OPERATION;
150f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
151f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    status_t err = pause();
152f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (err != OK) {
153f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        return err;
154f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    }
155f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    Mutex::Autolock autoLock(mLock);
156f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    mState = UNINITIALIZED;
157f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    return OK;
158f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
159f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
160f9d660a5e0196240add5daf0199f128d471e592cInsun Kangstatus_t TimedTextDriver::seekToAsync(int64_t timeUs) {
161f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    mPlayer->seekToAsync(timeUs);
162f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    return OK;
163f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
164f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
1656655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addInBandTextSource(
166eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, const sp<MediaSource>& mediaSource) {
1676655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source =
1686655174826330afe66ef766258181ae8c11f3f6cInsun Kang            TimedTextSource::CreateTimedTextSource(mediaSource);
1696655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (source == NULL) {
1706655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
1716655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
1726655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
173eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceVector.add(trackIndex, source);
174692ac36c4b6a09fed5113a4f45f00a041665a769James Dong    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_IN_BAND);
1756655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
1766655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
1776655174826330afe66ef766258181ae8c11f3f6cInsun Kang
1786655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextDriver::addOutOfBandTextSource(
179eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, const char *uri, const char *mimeType) {
180eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang    // To support local subtitle file only for now
182f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    if (strncasecmp("file://", uri, 7)) {
183613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        ALOGE("uri('%s') is not a file", uri);
1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
186613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
1876655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<DataSource> dataSource =
1886655174826330afe66ef766258181ae8c11f3f6cInsun Kang            DataSource::CreateFromURI(uri);
189eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
190613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong}
191613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
192613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::addOutOfBandTextSource(
193eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex, int fd, off64_t offset, off64_t length, const char *mimeType) {
194613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
195613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    if (fd < 0) {
196613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        ALOGE("Invalid file descriptor: %d", fd);
197613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong        return ERROR_UNSUPPORTED;
198613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    }
199613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
200613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong    sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
201eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return createOutOfBandTextSource(trackIndex, mimeType, dataSource);
202613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong}
203613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
204613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dongstatus_t TimedTextDriver::createOutOfBandTextSource(
205eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        size_t trackIndex,
206eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        const char *mimeType,
207eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        const sp<DataSource>& dataSource) {
208613c8ae1b7a2b4f43b33a72dc2fff0bc8b7d4c6fJames Dong
2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (dataSource == NULL) {
2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
2116655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2126655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2136655174826330afe66ef766258181ae8c11f3f6cInsun Kang    sp<TimedTextSource> source;
2147c5afe93c9ca2f9f3958663bc3fa9649ec2f5331Insun Kang    if (strcasecmp(mimeType, MEDIA_MIMETYPE_TEXT_SUBRIP) == 0) {
2156655174826330afe66ef766258181ae8c11f3f6cInsun Kang        source = TimedTextSource::CreateTimedTextSource(
2166655174826330afe66ef766258181ae8c11f3f6cInsun Kang                dataSource, TimedTextSource::OUT_OF_BAND_FILE_SRT);
2176655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2186655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2196655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (source == NULL) {
220eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        ALOGE("Failed to create timed text source");
2216655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return ERROR_UNSUPPORTED;
2226655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2236655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2246655174826330afe66ef766258181ae8c11f3f6cInsun Kang    Mutex::Autolock autoLock(mLock);
225eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    mTextSourceVector.add(trackIndex, source);
226692ac36c4b6a09fed5113a4f45f00a041665a769James Dong    mTextSourceTypeVector.add(TEXT_SOURCE_TYPE_OUT_OF_BAND);
227f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    return OK;
228f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
2296655174826330afe66ef766258181ae8c11f3f6cInsun Kang
230eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongsize_t TimedTextDriver::countExternalTracks() const {
231eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    size_t nTracks = 0;
232eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
233692ac36c4b6a09fed5113a4f45f00a041665a769James Dong        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_OUT_OF_BAND) {
234eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong            ++nTracks;
235eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        }
236eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    }
237eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    return nTracks;
238eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong}
239eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
240eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dongvoid TimedTextDriver::getExternalTrackInfo(Parcel *parcel) {
241f9d660a5e0196240add5daf0199f128d471e592cInsun Kang    Mutex::Autolock autoLock(mLock);
242eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong    for (size_t i = 0, n = mTextSourceTypeVector.size(); i < n; ++i) {
243692ac36c4b6a09fed5113a4f45f00a041665a769James Dong        if (mTextSourceTypeVector[i] == TEXT_SOURCE_TYPE_IN_BAND) {
244eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong            continue;
245eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        }
246eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong
247eec46abb88dcc50621fd2d3f17a6b8d24fd07a19James Dong        sp<MetaData> meta = mTextSourceVector.valueAt(i)->getFormat();
248f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
24925736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        // There are two fields.
25025736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeInt32(2);
25125736fd247ba757feefe15d3071f7e747c64fea4Insun Kang
25225736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        // track type.
25325736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeInt32(MEDIA_TRACK_TYPE_TIMEDTEXT);
25425736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        const char *lang = "und";
25525736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        if (meta != NULL) {
256f9d660a5e0196240add5daf0199f128d471e592cInsun Kang            meta->findCString(kKeyMediaLanguage, &lang);
257f9d660a5e0196240add5daf0199f128d471e592cInsun Kang        }
25825736fd247ba757feefe15d3071f7e747c64fea4Insun Kang        parcel->writeString16(String16(lang));
2596655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2606655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
2616655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2626655174826330afe66ef766258181ae8c11f3f6cInsun Kang}  // namespace android
263