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