113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang/*
213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * Copyright (C) 2011 The Android Open Source Project
313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *
413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * Licensed under the Apache License, Version 2.0 (the "License");
513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * you may not use this file except in compliance with the License.
613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * You may obtain a copy of the License at
713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *
813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *      http://www.apache.org/licenses/LICENSE-2.0
913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *
1013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * Unless required by applicable law or agreed to in writing, software
1113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * distributed under the License is distributed on an "AS IS" BASIS,
1213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * See the License for the specific language governing permissions and
1413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * limitations under the License.
1513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang */
1613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
1713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang#include "TimedTextParser.h"
1813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang#include <media/stagefright/DataSource.h>
1913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
2013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangnamespace android {
2113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
2213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria WangTimedTextParser::TimedTextParser()
2313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    : mDataSource(NULL),
2413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang      mOffset(0),
2513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang      mIndex(0) {
2613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
2713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
2813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria WangTimedTextParser::~TimedTextParser() {
2913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    reset();
3013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
3113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
3213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangstatus_t TimedTextParser::init(
3313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        const sp<DataSource> &dataSource, FileType fileType) {
3413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mDataSource = dataSource;
3513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mFileType = fileType;
3613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
3713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    status_t err;
3813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if ((err = scanFile()) != OK) {
3913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        reset();
4013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return err;
4113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
4213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
4313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    return OK;
4413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
4513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
4613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangvoid TimedTextParser::reset() {
4713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mDataSource.clear();
4813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mTextVector.clear();
4913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mOffset = 0;
5013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mIndex = 0;
5113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
5213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
5313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang// scan the text file to get start/stop time and the
5413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang// offset of each piece of text content
5513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangstatus_t TimedTextParser::scanFile() {
5613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (mFileType != OUT_OF_BAND_FILE_SRT) {
5713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return ERROR_UNSUPPORTED;
5813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
5913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
6013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    off64_t offset = 0;
6113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    int64_t startTimeUs;
6213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    bool endOfFile = false;
6313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
6413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    while (!endOfFile) {
6513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        TextInfo info;
6613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        status_t err = getNextInSrtFileFormat(&offset, &startTimeUs, &info);
6713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
6813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if (err != OK) {
6913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if (err == ERROR_END_OF_STREAM) {
7013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                endOfFile = true;
7113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            } else {
7213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                return err;
7313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
7413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        } else {
7513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            mTextVector.add(startTimeUs, info);
7613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
7713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
7813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
7913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (mTextVector.isEmpty()) {
8013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return ERROR_MALFORMED;
8113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
8213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    return OK;
8313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
8413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
8513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang// read one line started from *offset and store it into data.
8613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangstatus_t TimedTextParser::readNextLine(off64_t *offset, AString *data) {
8713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    char character;
8813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
8913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    data->clear();
9013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
9113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    while (true) {
9213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        ssize_t err;
9313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
9413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if (err == 0) {
9513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                return ERROR_END_OF_STREAM;
9613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
9713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            return ERROR_IO;
9813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
9913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
10013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        (*offset) ++;
10113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
10213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        // a line could end with CR, LF or CR + LF
10313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if (character == 10) {
10413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            break;
10513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        } else if (character == 13) {
10613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if ((err = mDataSource->readAt(*offset, &character, 1)) < 1) {
10713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                if (err == 0) { // end of the stream
10813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    return OK;
10913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                }
11013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                return ERROR_IO;
11113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
11213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
11313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            (*offset) ++;
11413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
11513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if (character != 10) {
11613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                (*offset) --;
11713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
11813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            break;
11913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
12013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
12113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        data->append(character);
12213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
12313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
12413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    return OK;
12513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
12613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
12713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang/* SRT format:
12813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  Subtitle number
12913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  Start time --> End time
13013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  Text of subtitle (one or more lines)
13113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  Blank line
13213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *
13313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang * .srt file example:
13413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  1
13513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  00:00:20,000 --> 00:00:24,400
13613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  Altocumulus clouds occur between six thousand
13713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *
13813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  2
13913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  00:00:24,600 --> 00:00:27,800
14013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang *  and twenty thousand feet above ground level.
14113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang */
14213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangstatus_t TimedTextParser::getNextInSrtFileFormat(
14313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        off64_t *offset, int64_t *startTimeUs, TextInfo *info) {
14413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    AString data;
14513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    status_t err;
14613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if ((err = readNextLine(offset, &data)) != OK) {
14713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return err;
14813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
14913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
15013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    // to skip the first line
15113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if ((err = readNextLine(offset, &data)) != OK) {
15213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return err;
15313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
15413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
15513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2;
15613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    // the start time format is: hours:minutes:seconds,milliseconds
15713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    // 00:00:24,600 --> 00:00:27,800
15813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d",
15913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) {
16013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return ERROR_MALFORMED;
16113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
16213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
16313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll;
16413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll;
16513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (info->endTimeUs <= *startTimeUs) {
16613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return ERROR_MALFORMED;
16713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
16813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
16913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    info->offset = *offset;
17013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
17113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    bool needMoreData = true;
17213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    while (needMoreData) {
17313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if ((err = readNextLine(offset, &data)) != OK) {
17413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if (err == ERROR_END_OF_STREAM) {
17513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                needMoreData = false;
17613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            } else {
17713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                return err;
17813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
17913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
18013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
18113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if (needMoreData) {
18213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            data.trim();
18313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            if (data.empty()) {
18413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                // it's an empty line used to separate two subtitles
18513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                needMoreData = false;
18613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
18713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
18813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
18913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
19013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    info->textLen = *offset - info->offset;
19113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
19213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    return OK;
19313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
19413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
19513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wangstatus_t TimedTextParser::getText(
19613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        AString *text, int64_t *startTimeUs, int64_t *endTimeUs,
19713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        const MediaSource::ReadOptions *options) {
19813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    Mutex::Autolock autoLock(mLock);
19913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
20013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    text->clear();
20113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
20213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    int64_t seekTimeUs;
20313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    MediaSource::ReadOptions::SeekMode mode;
20413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
20513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        int64_t lastEndTimeUs = mTextVector.valueAt(mTextVector.size() - 1).endTimeUs;
20613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        int64_t firstStartTimeUs = mTextVector.keyAt(0);
20713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
20813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        if (seekTimeUs < 0 || seekTimeUs > lastEndTimeUs) {
20913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            return ERROR_OUT_OF_RANGE;
21013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        } else if (seekTimeUs < firstStartTimeUs) {
21113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            mIndex = 0;
21213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        } else {
21313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            // binary search
21413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            ssize_t low = 0;
21513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            ssize_t high = mTextVector.size() - 1;
21613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            ssize_t mid = 0;
21713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            int64_t currTimeUs;
21813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
21913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            while (low <= high) {
22013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                mid = low + (high - low)/2;
22113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                currTimeUs = mTextVector.keyAt(mid);
22213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                const int diff = currTimeUs - seekTimeUs;
22313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
22413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                if (diff == 0) {
22513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    break;
22613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                } else if (diff < 0) {
22713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    low = mid + 1;
22813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                } else {
22913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    if ((high == mid + 1)
23013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                            && (seekTimeUs < mTextVector.keyAt(high))) {
23113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                        break;
23213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    }
23313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                    high = mid - 1;
23413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang                }
23513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            }
23613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
23713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang            mIndex = mid;
23813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        }
23913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
24013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
24113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    TextInfo info = mTextVector.valueAt(mIndex);
24213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    *startTimeUs = mTextVector.keyAt(mIndex);
24313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    *endTimeUs = info.endTimeUs;
24413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    mIndex ++;
24513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
24613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    char *str = new char[info.textLen];
24713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    if (mDataSource->readAt(info.offset, str, info.textLen) < info.textLen) {
24813bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        delete[] str;
24913bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang        return ERROR_IO;
25013bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    }
25113bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
25213bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    text->append(str, info.textLen);
25313bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    delete[] str;
25413bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang    return OK;
25513bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}
25613bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang
25713bc8cde1c842bea1fa3000a48739a6e22f25a9cGloria Wang}  // namespace android
258