16655174826330afe66ef766258181ae8c11f3f6cInsun Kang /*
26655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Copyright (C) 2012 The Android Open Source Project
3965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *
4965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * Licensed under the Apache License, Version 2.0 (the "License");
5965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * you may not use this file except in compliance with the License.
6965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * You may obtain a copy of the License at
7965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *
8965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *      http://www.apache.org/licenses/LICENSE-2.0
9965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *
10965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * Unless required by applicable law or agreed to in writing, software
11965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * distributed under the License is distributed on an "AS IS" BASIS,
12965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * See the License for the specific language governing permissions and
14965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * limitations under the License.
15965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang */
16965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
176655174826330afe66ef766258181ae8c11f3f6cInsun Kang//#define LOG_NDEBUG 0
186655174826330afe66ef766258181ae8c11f3f6cInsun Kang#define LOG_TAG "TimedTextSRTSource"
196655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <utils/Log.h>
206655174826330afe66ef766258181ae8c11f3f6cInsun Kang
216655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <binder/Parcel.h>
22bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang#include <media/stagefright/foundation/ADebug.h>  // for CHECK_xx
236655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/AString.h>
24965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include <media/stagefright/DataSource.h>
25f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MediaDefs.h>  // for MEDIA_MIMETYPE_xxx
266655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h>
276655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h>
28f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MetaData.h>
296655174826330afe66ef766258181ae8c11f3f6cInsun Kang
306655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSRTSource.h"
316655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h"
32965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
33965d08ba16ee82bc85f69546360c18e7da907406Gloria Wangnamespace android {
34965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
356655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextSRTSource::TimedTextSRTSource(const sp<DataSource>& dataSource)
366655174826330afe66ef766258181ae8c11f3f6cInsun Kang        : mSource(dataSource),
37f9d660a5e0196240add5daf0199f128d471e592cInsun Kang          mMetaData(new MetaData),
386655174826330afe66ef766258181ae8c11f3f6cInsun Kang          mIndex(0) {
392ba042ff8a8bb5aa0320580119771e11e64ba2cdInsun Kang    // TODO: Need to detect the language, because SRT doesn't give language
402ba042ff8a8bb5aa0320580119771e11e64ba2cdInsun Kang    // information explicitly.
412ba042ff8a8bb5aa0320580119771e11e64ba2cdInsun Kang    mMetaData->setCString(kKeyMediaLanguage, "und");
42965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
43965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
446655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextSRTSource::~TimedTextSRTSource() {
45965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
46965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
476655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::start() {
486655174826330afe66ef766258181ae8c11f3f6cInsun Kang    status_t err = scanFile();
496655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (err != OK) {
50965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        reset();
51965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
526655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return err;
53965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
54965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
556655174826330afe66ef766258181ae8c11f3f6cInsun Kangvoid TimedTextSRTSource::reset() {
56965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    mTextVector.clear();
57965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    mIndex = 0;
58965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
59965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
606655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::stop() {
616655174826330afe66ef766258181ae8c11f3f6cInsun Kang    reset();
626655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
636655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
646655174826330afe66ef766258181ae8c11f3f6cInsun Kang
656655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::read(
66bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang        int64_t *startTimeUs,
67bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang        int64_t *endTimeUs,
686655174826330afe66ef766258181ae8c11f3f6cInsun Kang        Parcel *parcel,
696655174826330afe66ef766258181ae8c11f3f6cInsun Kang        const MediaSource::ReadOptions *options) {
706655174826330afe66ef766258181ae8c11f3f6cInsun Kang    AString text;
71bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang    status_t err = getText(options, &text, startTimeUs, endTimeUs);
726655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (err != OK) {
736655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return err;
746655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
756655174826330afe66ef766258181ae8c11f3f6cInsun Kang
76bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang    CHECK_GE(*startTimeUs, 0);
77bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang    extractAndAppendLocalDescriptions(*startTimeUs, text, parcel);
786655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
796655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
80965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
81a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kangsp<MetaData> TimedTextSRTSource::getFormat() {
82a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    return mMetaData;
83a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang}
84a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang
856655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::scanFile() {
86965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    off64_t offset = 0;
87965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    int64_t startTimeUs;
88965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    bool endOfFile = false;
89965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
90965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    while (!endOfFile) {
91965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        TextInfo info;
926655174826330afe66ef766258181ae8c11f3f6cInsun Kang        status_t err = getNextSubtitleInfo(&offset, &startTimeUs, &info);
936655174826330afe66ef766258181ae8c11f3f6cInsun Kang        switch (err) {
946655174826330afe66ef766258181ae8c11f3f6cInsun Kang            case OK:
956655174826330afe66ef766258181ae8c11f3f6cInsun Kang                mTextVector.add(startTimeUs, info);
966655174826330afe66ef766258181ae8c11f3f6cInsun Kang                break;
976655174826330afe66ef766258181ae8c11f3f6cInsun Kang            case ERROR_END_OF_STREAM:
98965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                endOfFile = true;
996655174826330afe66ef766258181ae8c11f3f6cInsun Kang                break;
1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang            default:
101965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                return err;
102965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
103965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
104965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (mTextVector.isEmpty()) {
105965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return ERROR_MALFORMED;
106965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
107965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    return OK;
108965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
109965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
110965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang/* SRT format:
1116655174826330afe66ef766258181ae8c11f3f6cInsun Kang *   Subtitle number
1126655174826330afe66ef766258181ae8c11f3f6cInsun Kang *   Start time --> End time
1136655174826330afe66ef766258181ae8c11f3f6cInsun Kang *   Text of subtitle (one or more lines)
1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang *   Blank lines
115965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *
116965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * .srt file example:
1176655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 1
1186655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:20,000 --> 00:00:24,400
1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Altocumulus clouds occr between six thousand
120965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *
1216655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 2
1226655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:24,600 --> 00:00:27,800
1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang * and twenty thousand feet above ground level.
124965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang */
1256655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getNextSubtitleInfo(
1266655174826330afe66ef766258181ae8c11f3f6cInsun Kang          off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
127965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    AString data;
128965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    status_t err;
129965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
1300e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang    // To skip blank lines.
1310e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang    do {
1320e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang        if ((err = readNextLine(offset, &data)) != OK) {
1330e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang            return err;
1340e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang        }
1350e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang        data.trim();
1366655174826330afe66ef766258181ae8c11f3f6cInsun Kang    } while (data.empty());
1370e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang
1380e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang    // Just ignore the first non-blank line which is subtitle sequence number.
139965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if ((err = readNextLine(offset, &data)) != OK) {
140965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return err;
141965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
142965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2;
143965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    // the start time format is: hours:minutes:seconds,milliseconds
144965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    // 00:00:24,600 --> 00:00:27,800
145965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
1466655174826330afe66ef766258181ae8c11f3f6cInsun Kang               &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) {
147965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return ERROR_MALFORMED;
148965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
149965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
150965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll;
151965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll;
152965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    if (info->endTimeUs <= *startTimeUs) {
153965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return ERROR_MALFORMED;
154965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
155965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
156965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    info->offset = *offset;
157965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    bool needMoreData = true;
158965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    while (needMoreData) {
159965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        if ((err = readNextLine(offset, &data)) != OK) {
160965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            if (err == ERROR_END_OF_STREAM) {
161a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang                break;
162965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            } else {
163965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                return err;
164965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            }
165965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
166965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
167a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        data.trim();
168a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        if (data.empty()) {
169a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang            // it's an empty line used to separate two subtitles
170a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang            needMoreData = false;
171965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
172965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
173965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    info->textLen = *offset - info->offset;
174965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    return OK;
175965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
176965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
1776655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::readNextLine(off64_t *offset, AString *data) {
1786655174826330afe66ef766258181ae8c11f3f6cInsun Kang    data->clear();
1796655174826330afe66ef766258181ae8c11f3f6cInsun Kang    while (true) {
1806655174826330afe66ef766258181ae8c11f3f6cInsun Kang        ssize_t readSize;
1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang        char character;
1826655174826330afe66ef766258181ae8c11f3f6cInsun Kang        if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) {
1836655174826330afe66ef766258181ae8c11f3f6cInsun Kang            if (readSize == 0) {
1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang                return ERROR_END_OF_STREAM;
1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang            }
1866655174826330afe66ef766258181ae8c11f3f6cInsun Kang            return ERROR_IO;
1876655174826330afe66ef766258181ae8c11f3f6cInsun Kang        }
188965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
1896655174826330afe66ef766258181ae8c11f3f6cInsun Kang        (*offset)++;
190965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
1916655174826330afe66ef766258181ae8c11f3f6cInsun Kang        // a line could end with CR, LF or CR + LF
1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang        if (character == 10) {
1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang        } else if (character == 13) {
1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang            if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) {
1966655174826330afe66ef766258181ae8c11f3f6cInsun Kang                if (readSize == 0) {  // end of the stream
1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang                    return OK;
1986655174826330afe66ef766258181ae8c11f3f6cInsun Kang                }
1996655174826330afe66ef766258181ae8c11f3f6cInsun Kang                return ERROR_IO;
2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang            }
2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang            (*offset)++;
2036655174826330afe66ef766258181ae8c11f3f6cInsun Kang            if (character != 10) {
2046655174826330afe66ef766258181ae8c11f3f6cInsun Kang                (*offset)--;
2056655174826330afe66ef766258181ae8c11f3f6cInsun Kang            }
2066655174826330afe66ef766258181ae8c11f3f6cInsun Kang            break;
2076655174826330afe66ef766258181ae8c11f3f6cInsun Kang        }
2086655174826330afe66ef766258181ae8c11f3f6cInsun Kang        data->append(character);
2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
2116655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
2126655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2136655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getText(
2146655174826330afe66ef766258181ae8c11f3f6cInsun Kang        const MediaSource::ReadOptions *options,
2156655174826330afe66ef766258181ae8c11f3f6cInsun Kang        AString *text, int64_t *startTimeUs, int64_t *endTimeUs) {
2160a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang    if (mTextVector.size() == 0) {
2170a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang        return ERROR_END_OF_STREAM;
2180a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang    }
2196655174826330afe66ef766258181ae8c11f3f6cInsun Kang    text->clear();
220965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    int64_t seekTimeUs;
221965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    MediaSource::ReadOptions::SeekMode mode;
2226655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) {
2236655174826330afe66ef766258181ae8c11f3f6cInsun Kang        int64_t lastEndTimeUs =
2246655174826330afe66ef766258181ae8c11f3f6cInsun Kang                mTextVector.valueAt(mTextVector.size() - 1).endTimeUs;
225a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        if (seekTimeUs < 0) {
226965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            return ERROR_OUT_OF_RANGE;
227a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        } else if (seekTimeUs >= lastEndTimeUs) {
228a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang            return ERROR_END_OF_STREAM;
229965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        } else {
230965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            // binary search
2310a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang            size_t low = 0;
2320a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang            size_t high = mTextVector.size() - 1;
2330a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang            size_t mid = 0;
234965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            while (low <= high) {
236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                mid = low + (high - low)/2;
237a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang                int diff = compareExtendedRangeAndTime(mid, seekTimeUs);
238a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang                if (diff == 0) {
239965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                    break;
240a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang                } else if (diff < 0) {
241965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                    low = mid + 1;
242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                } else {
243965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                    high = mid - 1;
244965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang                }
245965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            }
246965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang            mIndex = mid;
247965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        }
248965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
2490a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang
2500a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang    if (mIndex >= mTextVector.size()) {
2510a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang        return ERROR_END_OF_STREAM;
2520a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang    }
253a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang
2546655174826330afe66ef766258181ae8c11f3f6cInsun Kang    const TextInfo &info = mTextVector.valueAt(mIndex);
255965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    *startTimeUs = mTextVector.keyAt(mIndex);
256965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    *endTimeUs = info.endTimeUs;
2576655174826330afe66ef766258181ae8c11f3f6cInsun Kang    mIndex++;
258965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
259965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    char *str = new char[info.textLen];
2606655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (mSource->readAt(info.offset, str, info.textLen) < info.textLen) {
261965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        delete[] str;
262965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang        return ERROR_IO;
263965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    }
264965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    text->append(str, info.textLen);
265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    delete[] str;
266965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang    return OK;
267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}
268965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang
2696655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::extractAndAppendLocalDescriptions(
2706655174826330afe66ef766258181ae8c11f3f6cInsun Kang        int64_t timeUs, const AString &text, Parcel *parcel) {
2716655174826330afe66ef766258181ae8c11f3f6cInsun Kang    const void *data = text.c_str();
2726655174826330afe66ef766258181ae8c11f3f6cInsun Kang    size_t size = text.size();
2736655174826330afe66ef766258181ae8c11f3f6cInsun Kang    int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS |
2746655174826330afe66ef766258181ae8c11f3f6cInsun Kang                   TextDescriptions::OUT_OF_BAND_TEXT_SRT;
2756655174826330afe66ef766258181ae8c11f3f6cInsun Kang
2766655174826330afe66ef766258181ae8c11f3f6cInsun Kang    if (size > 0) {
2776655174826330afe66ef766258181ae8c11f3f6cInsun Kang        return TextDescriptions::getParcelOfDescriptions(
2786655174826330afe66ef766258181ae8c11f3f6cInsun Kang                (const uint8_t *)data, size, flag, timeUs / 1000, parcel);
2796655174826330afe66ef766258181ae8c11f3f6cInsun Kang    }
2806655174826330afe66ef766258181ae8c11f3f6cInsun Kang    return OK;
2816655174826330afe66ef766258181ae8c11f3f6cInsun Kang}
2826655174826330afe66ef766258181ae8c11f3f6cInsun Kang
283a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kangint TimedTextSRTSource::compareExtendedRangeAndTime(size_t index, int64_t timeUs) {
284a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    CHECK_LT(index, mTextVector.size());
285a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    int64_t endTimeUs = mTextVector.valueAt(index).endTimeUs;
286a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    int64_t startTimeUs = (index > 0) ?
287a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang            mTextVector.valueAt(index - 1).endTimeUs : 0;
288a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    if (timeUs >= startTimeUs && timeUs < endTimeUs) {
289a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        return 0;
290a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    } else if (endTimeUs <= timeUs) {
291a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        return -1;
292a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    } else {
293a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang        return 1;
294a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang    }
295f9d660a5e0196240add5daf0199f128d471e592cInsun Kang}
296f9d660a5e0196240add5daf0199f128d471e592cInsun Kang
297965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang}  // namespace android
298