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) { 39965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 40965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 416655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextSRTSource::~TimedTextSRTSource() { 42965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 43965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 446655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::start() { 456655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t err = scanFile(); 466655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (err != OK) { 47965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang reset(); 48965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 49f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // TODO: Need to detect the language, because SRT doesn't give language 50f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // information explicitly. 51f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mMetaData->setCString(kKeyMediaLanguage, ""); 526655174826330afe66ef766258181ae8c11f3f6cInsun Kang return err; 53965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 54965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 556655174826330afe66ef766258181ae8c11f3f6cInsun Kangvoid TimedTextSRTSource::reset() { 56f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mMetaData->clear(); 57965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mTextVector.clear(); 58965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = 0; 59965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 60965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 616655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::stop() { 626655174826330afe66ef766258181ae8c11f3f6cInsun Kang reset(); 636655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 646655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 656655174826330afe66ef766258181ae8c11f3f6cInsun Kang 666655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::read( 67bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang int64_t *startTimeUs, 68bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang int64_t *endTimeUs, 696655174826330afe66ef766258181ae8c11f3f6cInsun Kang Parcel *parcel, 706655174826330afe66ef766258181ae8c11f3f6cInsun Kang const MediaSource::ReadOptions *options) { 716655174826330afe66ef766258181ae8c11f3f6cInsun Kang AString text; 72bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang status_t err = getText(options, &text, startTimeUs, endTimeUs); 736655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (err != OK) { 746655174826330afe66ef766258181ae8c11f3f6cInsun Kang return err; 756655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 766655174826330afe66ef766258181ae8c11f3f6cInsun Kang 77bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang CHECK_GE(*startTimeUs, 0); 78bae00e73c6d1d87cc5fd42b50f95d1d9572162eaInsun Kang extractAndAppendLocalDescriptions(*startTimeUs, text, parcel); 796655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 806655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 81965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 82a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kangsp<MetaData> TimedTextSRTSource::getFormat() { 83a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang return mMetaData; 84a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang} 85a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang 866655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::scanFile() { 87965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang off64_t offset = 0; 88965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t startTimeUs; 89965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang bool endOfFile = false; 90965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 91965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (!endOfFile) { 92965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang TextInfo info; 936655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t err = getNextSubtitleInfo(&offset, &startTimeUs, &info); 946655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (err) { 956655174826330afe66ef766258181ae8c11f3f6cInsun Kang case OK: 966655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextVector.add(startTimeUs, info); 976655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 986655174826330afe66ef766258181ae8c11f3f6cInsun Kang case ERROR_END_OF_STREAM: 99965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang endOfFile = true; 1006655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1016655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 102965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 103965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 104965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 105965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (mTextVector.isEmpty()) { 106965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 107965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 108965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 109965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 110965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 111965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang/* SRT format: 1126655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Subtitle number 1136655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Start time --> End time 1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Text of subtitle (one or more lines) 1156655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Blank lines 116965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * 117965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * .srt file example: 1186655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 1 1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:20,000 --> 00:00:24,400 1206655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Altocumulus clouds occr between six thousand 121965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * 1226655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 2 1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:24,600 --> 00:00:27,800 1246655174826330afe66ef766258181ae8c11f3f6cInsun Kang * and twenty thousand feet above ground level. 125965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang */ 1266655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getNextSubtitleInfo( 1276655174826330afe66ef766258181ae8c11f3f6cInsun Kang off64_t *offset, int64_t *startTimeUs, TextInfo *info) { 128965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang AString data; 129965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang status_t err; 130965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1310e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang // To skip blank lines. 1320e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang do { 1330e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang if ((err = readNextLine(offset, &data)) != OK) { 1340e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang return err; 1350e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang } 1360e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang data.trim(); 1376655174826330afe66ef766258181ae8c11f3f6cInsun Kang } while (data.empty()); 1380e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang 1390e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang // Just ignore the first non-blank line which is subtitle sequence number. 140965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((err = readNextLine(offset, &data)) != OK) { 141965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 142965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 143965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2; 144965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // the start time format is: hours:minutes:seconds,milliseconds 145965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // 00:00:24,600 --> 00:00:27,800 146965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", 1476655174826330afe66ef766258181ae8c11f3f6cInsun Kang &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) { 148965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 149965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 150965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 151965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll; 152965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll; 153965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (info->endTimeUs <= *startTimeUs) { 154965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 155965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 156965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 157965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->offset = *offset; 158965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang bool needMoreData = true; 159965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (needMoreData) { 160965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((err = readNextLine(offset, &data)) != OK) { 161965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (err == ERROR_END_OF_STREAM) { 162a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang break; 163965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 164965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 165965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 166965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 167965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 168a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang data.trim(); 169a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang if (data.empty()) { 170a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang // it's an empty line used to separate two subtitles 171a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang needMoreData = false; 172965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 173965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 174965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->textLen = *offset - info->offset; 175965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 176965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 177965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1786655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::readNextLine(off64_t *offset, AString *data) { 1796655174826330afe66ef766258181ae8c11f3f6cInsun Kang data->clear(); 1806655174826330afe66ef766258181ae8c11f3f6cInsun Kang while (true) { 1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang ssize_t readSize; 1826655174826330afe66ef766258181ae8c11f3f6cInsun Kang char character; 1836655174826330afe66ef766258181ae8c11f3f6cInsun Kang if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) { 1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (readSize == 0) { 1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_END_OF_STREAM; 1866655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1876655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_IO; 1886655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 189965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1906655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)++; 191965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang // a line could end with CR, LF or CR + LF 1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (character == 10) { 1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang } else if (character == 13) { 1966655174826330afe66ef766258181ae8c11f3f6cInsun Kang if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) { 1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (readSize == 0) { // end of the stream 1986655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1996655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_IO; 2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2036655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)++; 2046655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (character != 10) { 2056655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)--; 2066655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2076655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 2086655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang data->append(character); 2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2116655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2126655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2136655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2146655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getText( 2156655174826330afe66ef766258181ae8c11f3f6cInsun Kang const MediaSource::ReadOptions *options, 2166655174826330afe66ef766258181ae8c11f3f6cInsun Kang AString *text, int64_t *startTimeUs, int64_t *endTimeUs) { 2170a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (mTextVector.size() == 0) { 2180a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang return ERROR_END_OF_STREAM; 2190a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } 2206655174826330afe66ef766258181ae8c11f3f6cInsun Kang text->clear(); 221965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t seekTimeUs; 222965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang MediaSource::ReadOptions::SeekMode mode; 2236655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 2246655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t lastEndTimeUs = 2256655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextVector.valueAt(mTextVector.size() - 1).endTimeUs; 226a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang if (seekTimeUs < 0) { 227965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_OUT_OF_RANGE; 228a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang } else if (seekTimeUs >= lastEndTimeUs) { 229a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang return ERROR_END_OF_STREAM; 230965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 231965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // binary search 2320a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang size_t low = 0; 2330a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang size_t high = mTextVector.size() - 1; 2340a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang size_t mid = 0; 235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (low <= high) { 237965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mid = low + (high - low)/2; 238a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang int diff = compareExtendedRangeAndTime(mid, seekTimeUs); 239a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang if (diff == 0) { 240965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang break; 241a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang } else if (diff < 0) { 242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang low = mid + 1; 243965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 244965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang high = mid - 1; 245965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 246965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 247965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = mid; 248965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 249965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 2500a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang 2510a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (mIndex >= mTextVector.size()) { 2520a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang return ERROR_END_OF_STREAM; 2530a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } 254a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang 2556655174826330afe66ef766258181ae8c11f3f6cInsun Kang const TextInfo &info = mTextVector.valueAt(mIndex); 256965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *startTimeUs = mTextVector.keyAt(mIndex); 257965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *endTimeUs = info.endTimeUs; 2586655174826330afe66ef766258181ae8c11f3f6cInsun Kang mIndex++; 259965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 260965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang char *str = new char[info.textLen]; 2616655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (mSource->readAt(info.offset, str, info.textLen) < info.textLen) { 262965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 263965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_IO; 264965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang text->append(str, info.textLen); 266965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 268965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 269965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 2706655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::extractAndAppendLocalDescriptions( 2716655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t timeUs, const AString &text, Parcel *parcel) { 2726655174826330afe66ef766258181ae8c11f3f6cInsun Kang const void *data = text.c_str(); 2736655174826330afe66ef766258181ae8c11f3f6cInsun Kang size_t size = text.size(); 2746655174826330afe66ef766258181ae8c11f3f6cInsun Kang int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS | 2756655174826330afe66ef766258181ae8c11f3f6cInsun Kang TextDescriptions::OUT_OF_BAND_TEXT_SRT; 2766655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2776655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (size > 0) { 2786655174826330afe66ef766258181ae8c11f3f6cInsun Kang return TextDescriptions::getParcelOfDescriptions( 2796655174826330afe66ef766258181ae8c11f3f6cInsun Kang (const uint8_t *)data, size, flag, timeUs / 1000, parcel); 2806655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2816655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2826655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2836655174826330afe66ef766258181ae8c11f3f6cInsun Kang 284a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kangint TimedTextSRTSource::compareExtendedRangeAndTime(size_t index, int64_t timeUs) { 285a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang CHECK_LT(index, mTextVector.size()); 286a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang int64_t endTimeUs = mTextVector.valueAt(index).endTimeUs; 287a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang int64_t startTimeUs = (index > 0) ? 288a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang mTextVector.valueAt(index - 1).endTimeUs : 0; 289a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang if (timeUs >= startTimeUs && timeUs < endTimeUs) { 290a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang return 0; 291a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang } else if (endTimeUs <= timeUs) { 292a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang return -1; 293a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang } else { 294a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang return 1; 295a3c9d82d0f898d30982840b48d1f00fd0d831e19Insun Kang } 296f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 297f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 298965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} // namespace android 299