TimedTextSRTSource.cpp revision 0a2f0e047a2e593c62f54b07b903baf4728b9d0a
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 826655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::scanFile() { 83965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang off64_t offset = 0; 84965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t startTimeUs; 85965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang bool endOfFile = false; 86965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 87965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (!endOfFile) { 88965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang TextInfo info; 896655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t err = getNextSubtitleInfo(&offset, &startTimeUs, &info); 906655174826330afe66ef766258181ae8c11f3f6cInsun Kang switch (err) { 916655174826330afe66ef766258181ae8c11f3f6cInsun Kang case OK: 926655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextVector.add(startTimeUs, info); 936655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 946655174826330afe66ef766258181ae8c11f3f6cInsun Kang case ERROR_END_OF_STREAM: 95965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang endOfFile = true; 966655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 976655174826330afe66ef766258181ae8c11f3f6cInsun Kang default: 98965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 99965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 100965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 101965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (mTextVector.isEmpty()) { 102965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 103965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 104965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 105965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 106965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 107965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang/* SRT format: 1086655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Subtitle number 1096655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Start time --> End time 1106655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Text of subtitle (one or more lines) 1116655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Blank lines 112965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * 113965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * .srt file example: 1146655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 1 1156655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:20,000 --> 00:00:24,400 1166655174826330afe66ef766258181ae8c11f3f6cInsun Kang * Altocumulus clouds occr between six thousand 117965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang * 1186655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 2 1196655174826330afe66ef766258181ae8c11f3f6cInsun Kang * 00:00:24,600 --> 00:00:27,800 1206655174826330afe66ef766258181ae8c11f3f6cInsun Kang * and twenty thousand feet above ground level. 121965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang */ 1226655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getNextSubtitleInfo( 1236655174826330afe66ef766258181ae8c11f3f6cInsun Kang off64_t *offset, int64_t *startTimeUs, TextInfo *info) { 124965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang AString data; 125965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang status_t err; 126965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1270e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang // To skip blank lines. 1280e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang do { 1290e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang if ((err = readNextLine(offset, &data)) != OK) { 1300e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang return err; 1310e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang } 1320e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang data.trim(); 1336655174826330afe66ef766258181ae8c11f3f6cInsun Kang } while (data.empty()); 1340e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang 1350e0c3220ee1c4d57765e2cba3b07923921c55e08Insun Kang // Just ignore the first non-blank line which is subtitle sequence number. 136965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((err = readNextLine(offset, &data)) != OK) { 137965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 138965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 139965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int hour1, hour2, min1, min2, sec1, sec2, msec1, msec2; 140965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // the start time format is: hours:minutes:seconds,milliseconds 141965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // 00:00:24,600 --> 00:00:27,800 142965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (sscanf(data.c_str(), "%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", 1436655174826330afe66ef766258181ae8c11f3f6cInsun Kang &hour1, &min1, &sec1, &msec1, &hour2, &min2, &sec2, &msec2) != 8) { 144965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 145965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 146965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 147965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *startTimeUs = ((hour1 * 3600 + min1 * 60 + sec1) * 1000 + msec1) * 1000ll; 148965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->endTimeUs = ((hour2 * 3600 + min2 * 60 + sec2) * 1000 + msec2) * 1000ll; 149965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (info->endTimeUs <= *startTimeUs) { 150965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_MALFORMED; 151965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 152965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 153965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->offset = *offset; 154965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang bool needMoreData = true; 155965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (needMoreData) { 156965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((err = readNextLine(offset, &data)) != OK) { 157965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (err == ERROR_END_OF_STREAM) { 158965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang needMoreData = false; 159965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 160965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return err; 161965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 162965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 163965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 164965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (needMoreData) { 165965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang data.trim(); 166965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (data.empty()) { 167965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // it's an empty line used to separate two subtitles 168965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang needMoreData = false; 169965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 170965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 171965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 172965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang info->textLen = *offset - info->offset; 173965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 174965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 175965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1766655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::readNextLine(off64_t *offset, AString *data) { 1776655174826330afe66ef766258181ae8c11f3f6cInsun Kang data->clear(); 1786655174826330afe66ef766258181ae8c11f3f6cInsun Kang while (true) { 1796655174826330afe66ef766258181ae8c11f3f6cInsun Kang ssize_t readSize; 1806655174826330afe66ef766258181ae8c11f3f6cInsun Kang char character; 1816655174826330afe66ef766258181ae8c11f3f6cInsun Kang if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) { 1826655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (readSize == 0) { 1836655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_END_OF_STREAM; 1846655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1856655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_IO; 1866655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 187965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1886655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)++; 189965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 1906655174826330afe66ef766258181ae8c11f3f6cInsun Kang // a line could end with CR, LF or CR + LF 1916655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (character == 10) { 1926655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 1936655174826330afe66ef766258181ae8c11f3f6cInsun Kang } else if (character == 13) { 1946655174826330afe66ef766258181ae8c11f3f6cInsun Kang if ((readSize = mSource->readAt(*offset, &character, 1)) < 1) { 1956655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (readSize == 0) { // end of the stream 1966655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 1976655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 1986655174826330afe66ef766258181ae8c11f3f6cInsun Kang return ERROR_IO; 1996655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2006655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2016655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)++; 2026655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (character != 10) { 2036655174826330afe66ef766258181ae8c11f3f6cInsun Kang (*offset)--; 2046655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2056655174826330afe66ef766258181ae8c11f3f6cInsun Kang break; 2066655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2076655174826330afe66ef766258181ae8c11f3f6cInsun Kang data->append(character); 2086655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2096655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2106655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2116655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2126655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::getText( 2136655174826330afe66ef766258181ae8c11f3f6cInsun Kang const MediaSource::ReadOptions *options, 2146655174826330afe66ef766258181ae8c11f3f6cInsun Kang AString *text, int64_t *startTimeUs, int64_t *endTimeUs) { 2150a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (mTextVector.size() == 0) { 2160a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang return ERROR_END_OF_STREAM; 2170a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } 2186655174826330afe66ef766258181ae8c11f3f6cInsun Kang text->clear(); 219965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t seekTimeUs; 220965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang MediaSource::ReadOptions::SeekMode mode; 2216655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 2226655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t lastEndTimeUs = 2236655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextVector.valueAt(mTextVector.size() - 1).endTimeUs; 224965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t firstStartTimeUs = mTextVector.keyAt(0); 225965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (seekTimeUs < 0 || seekTimeUs > lastEndTimeUs) { 226965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_OUT_OF_RANGE; 227965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else if (seekTimeUs < firstStartTimeUs) { 228965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = 0; 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 int64_t currTimeUs; 235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (low <= high) { 237965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mid = low + (high - low)/2; 238965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang currTimeUs = mTextVector.keyAt(mid); 2390a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang const int64_t diffTime = currTimeUs - seekTimeUs; 240965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 2410a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (diffTime == 0) { 242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang break; 2430a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } else if (diffTime < 0) { 244965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang low = mid + 1; 245965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 246965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((high == mid + 1) 2476655174826330afe66ef766258181ae8c11f3f6cInsun Kang && (seekTimeUs < mTextVector.keyAt(high))) { 248965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang break; 249965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 2500a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (mid < 1) { 2510a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang break; 2520a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } 253965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang high = mid - 1; 254965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 255965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 256965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = mid; 257965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 258965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 2590a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang 2600a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang if (mIndex >= mTextVector.size()) { 2610a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang return ERROR_END_OF_STREAM; 2620a2f0e047a2e593c62f54b07b903baf4728b9d0aInsun Kang } 2636655174826330afe66ef766258181ae8c11f3f6cInsun Kang const TextInfo &info = mTextVector.valueAt(mIndex); 264965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *startTimeUs = mTextVector.keyAt(mIndex); 265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *endTimeUs = info.endTimeUs; 2666655174826330afe66ef766258181ae8c11f3f6cInsun Kang mIndex++; 267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 268965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang char *str = new char[info.textLen]; 2696655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (mSource->readAt(info.offset, str, info.textLen) < info.textLen) { 270965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 271965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_IO; 272965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 273965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang text->append(str, info.textLen); 274965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 275965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 276965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 277965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 2786655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::extractAndAppendLocalDescriptions( 2796655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t timeUs, const AString &text, Parcel *parcel) { 2806655174826330afe66ef766258181ae8c11f3f6cInsun Kang const void *data = text.c_str(); 2816655174826330afe66ef766258181ae8c11f3f6cInsun Kang size_t size = text.size(); 2826655174826330afe66ef766258181ae8c11f3f6cInsun Kang int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS | 2836655174826330afe66ef766258181ae8c11f3f6cInsun Kang TextDescriptions::OUT_OF_BAND_TEXT_SRT; 2846655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2856655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (size > 0) { 2866655174826330afe66ef766258181ae8c11f3f6cInsun Kang return TextDescriptions::getParcelOfDescriptions( 2876655174826330afe66ef766258181ae8c11f3f6cInsun Kang (const uint8_t *)data, size, flag, timeUs / 1000, parcel); 2886655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2896655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2906655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2916655174826330afe66ef766258181ae8c11f3f6cInsun Kang 292f9d660a5e0196240add5daf0199f128d471e592cInsun Kangsp<MetaData> TimedTextSRTSource::getFormat() { 293f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return mMetaData; 294f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 295f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 296965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} // namespace android 297