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