TimedTextSRTSource.cpp revision f9d660a5e0196240add5daf0199f128d471e592c
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> 226655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/foundation/AString.h> 23965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang#include <media/stagefright/DataSource.h> 24f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx 256655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaErrors.h> 266655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include <media/stagefright/MediaSource.h> 27f9d660a5e0196240add5daf0199f128d471e592cInsun Kang#include <media/stagefright/MetaData.h> 286655174826330afe66ef766258181ae8c11f3f6cInsun Kang 296655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TimedTextSRTSource.h" 306655174826330afe66ef766258181ae8c11f3f6cInsun Kang#include "TextDescriptions.h" 31965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 32965d08ba16ee82bc85f69546360c18e7da907406Gloria Wangnamespace android { 33965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 346655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextSRTSource::TimedTextSRTSource(const sp<DataSource>& dataSource) 356655174826330afe66ef766258181ae8c11f3f6cInsun Kang : mSource(dataSource), 36f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mMetaData(new MetaData), 376655174826330afe66ef766258181ae8c11f3f6cInsun Kang mIndex(0) { 38965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 39965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 406655174826330afe66ef766258181ae8c11f3f6cInsun KangTimedTextSRTSource::~TimedTextSRTSource() { 41965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 42965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 436655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::start() { 446655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t err = scanFile(); 456655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (err != OK) { 46965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang reset(); 47965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 48f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // TODO: Need to detect the language, because SRT doesn't give language 49f9d660a5e0196240add5daf0199f128d471e592cInsun Kang // information explicitly. 50f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mMetaData->setCString(kKeyMediaLanguage, ""); 516655174826330afe66ef766258181ae8c11f3f6cInsun Kang return err; 52965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 53965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 546655174826330afe66ef766258181ae8c11f3f6cInsun Kangvoid TimedTextSRTSource::reset() { 55f9d660a5e0196240add5daf0199f128d471e592cInsun Kang mMetaData->clear(); 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( 666655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t *timeUs, 676655174826330afe66ef766258181ae8c11f3f6cInsun Kang Parcel *parcel, 686655174826330afe66ef766258181ae8c11f3f6cInsun Kang const MediaSource::ReadOptions *options) { 696655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t endTimeUs; 706655174826330afe66ef766258181ae8c11f3f6cInsun Kang AString text; 716655174826330afe66ef766258181ae8c11f3f6cInsun Kang status_t err = getText(options, &text, timeUs, &endTimeUs); 726655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (err != OK) { 736655174826330afe66ef766258181ae8c11f3f6cInsun Kang return err; 746655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 756655174826330afe66ef766258181ae8c11f3f6cInsun Kang 766655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (*timeUs > 0) { 776655174826330afe66ef766258181ae8c11f3f6cInsun Kang extractAndAppendLocalDescriptions(*timeUs, text, parcel); 78965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 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) { 2156655174826330afe66ef766258181ae8c11f3f6cInsun Kang text->clear(); 216965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t seekTimeUs; 217965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang MediaSource::ReadOptions::SeekMode mode; 2186655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (options != NULL && options->getSeekTo(&seekTimeUs, &mode)) { 2196655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t lastEndTimeUs = 2206655174826330afe66ef766258181ae8c11f3f6cInsun Kang mTextVector.valueAt(mTextVector.size() - 1).endTimeUs; 221965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t firstStartTimeUs = mTextVector.keyAt(0); 222965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (seekTimeUs < 0 || seekTimeUs > lastEndTimeUs) { 223965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_OUT_OF_RANGE; 224965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else if (seekTimeUs < firstStartTimeUs) { 225965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = 0; 226965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 227965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang // binary search 228965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang ssize_t low = 0; 229965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang ssize_t high = mTextVector.size() - 1; 230965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang ssize_t mid = 0; 231965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang int64_t currTimeUs; 232965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 233965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang while (low <= high) { 234965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mid = low + (high - low)/2; 235965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang currTimeUs = mTextVector.keyAt(mid); 236965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang const int diff = currTimeUs - seekTimeUs; 237965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 238965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if (diff == 0) { 239965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang break; 240965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else if (diff < 0) { 241965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang low = mid + 1; 242965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } else { 243965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang if ((high == mid + 1) 2446655174826330afe66ef766258181ae8c11f3f6cInsun Kang && (seekTimeUs < mTextVector.keyAt(high))) { 245965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang break; 246965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 247965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang high = mid - 1; 248965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 249965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 250965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang mIndex = mid; 251965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 252965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 2536655174826330afe66ef766258181ae8c11f3f6cInsun Kang const TextInfo &info = mTextVector.valueAt(mIndex); 254965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *startTimeUs = mTextVector.keyAt(mIndex); 255965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang *endTimeUs = info.endTimeUs; 2566655174826330afe66ef766258181ae8c11f3f6cInsun Kang mIndex++; 257965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 258965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang char *str = new char[info.textLen]; 2596655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (mSource->readAt(info.offset, str, info.textLen) < info.textLen) { 260965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 261965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return ERROR_IO; 262965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang } 263965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang text->append(str, info.textLen); 264965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang delete[] str; 265965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang return OK; 266965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} 267965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang 2686655174826330afe66ef766258181ae8c11f3f6cInsun Kangstatus_t TimedTextSRTSource::extractAndAppendLocalDescriptions( 2696655174826330afe66ef766258181ae8c11f3f6cInsun Kang int64_t timeUs, const AString &text, Parcel *parcel) { 2706655174826330afe66ef766258181ae8c11f3f6cInsun Kang const void *data = text.c_str(); 2716655174826330afe66ef766258181ae8c11f3f6cInsun Kang size_t size = text.size(); 2726655174826330afe66ef766258181ae8c11f3f6cInsun Kang int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS | 2736655174826330afe66ef766258181ae8c11f3f6cInsun Kang TextDescriptions::OUT_OF_BAND_TEXT_SRT; 2746655174826330afe66ef766258181ae8c11f3f6cInsun Kang 2756655174826330afe66ef766258181ae8c11f3f6cInsun Kang if (size > 0) { 2766655174826330afe66ef766258181ae8c11f3f6cInsun Kang return TextDescriptions::getParcelOfDescriptions( 2776655174826330afe66ef766258181ae8c11f3f6cInsun Kang (const uint8_t *)data, size, flag, timeUs / 1000, parcel); 2786655174826330afe66ef766258181ae8c11f3f6cInsun Kang } 2796655174826330afe66ef766258181ae8c11f3f6cInsun Kang return OK; 2806655174826330afe66ef766258181ae8c11f3f6cInsun Kang} 2816655174826330afe66ef766258181ae8c11f3f6cInsun Kang 282f9d660a5e0196240add5daf0199f128d471e592cInsun Kangsp<MetaData> TimedTextSRTSource::getFormat() { 283f9d660a5e0196240add5daf0199f128d471e592cInsun Kang return mMetaData; 284f9d660a5e0196240add5daf0199f128d471e592cInsun Kang} 285f9d660a5e0196240add5daf0199f128d471e592cInsun Kang 286965d08ba16ee82bc85f69546360c18e7da907406Gloria Wang} // namespace android 287