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