1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "TimedText3GPPSource" 19 #include <utils/Log.h> 20 21 #include <binder/Parcel.h> 22 #include <media/stagefright/foundation/ADebug.h> // CHECK_XX macro 23 #include <media/stagefright/MediaBuffer.h> 24 #include <media/stagefright/MediaDefs.h> // for MEDIA_MIMETYPE_xxx 25 #include <media/stagefright/MediaErrors.h> 26 #include <media/stagefright/MediaSource.h> 27 #include <media/stagefright/MetaData.h> 28 29 #include "TimedText3GPPSource.h" 30 #include "TextDescriptions.h" 31 32 namespace android { 33 34 TimedText3GPPSource::TimedText3GPPSource(const sp<MediaSource>& mediaSource) 35 : mSource(mediaSource) { 36 } 37 38 TimedText3GPPSource::~TimedText3GPPSource() { 39 } 40 41 status_t TimedText3GPPSource::read( 42 int64_t *startTimeUs, int64_t *endTimeUs, Parcel *parcel, 43 const MediaSource::ReadOptions *options) { 44 MediaBuffer *textBuffer = NULL; 45 status_t err = mSource->read(&textBuffer, options); 46 if (err != OK) { 47 return err; 48 } 49 CHECK(textBuffer != NULL); 50 textBuffer->meta_data()->findInt64(kKeyTime, startTimeUs); 51 CHECK_GE(*startTimeUs, 0); 52 extractAndAppendLocalDescriptions(*startTimeUs, textBuffer, parcel); 53 textBuffer->release(); 54 // endTimeUs is a dummy parameter for 3gpp timed text format. 55 // Set a negative value to it to mark it is unavailable. 56 *endTimeUs = -1; 57 return OK; 58 } 59 60 // Each text sample consists of a string of text, optionally with sample 61 // modifier description. The modifier description could specify a new 62 // text style for the string of text. These descriptions are present only 63 // if they are needed. This method is used to extract the modifier 64 // description and append it at the end of the text. 65 status_t TimedText3GPPSource::extractAndAppendLocalDescriptions( 66 int64_t timeUs, const MediaBuffer *textBuffer, Parcel *parcel) { 67 const void *data; 68 size_t size = 0; 69 int32_t flag = TextDescriptions::LOCAL_DESCRIPTIONS; 70 71 const char *mime; 72 CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 73 CHECK(strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0); 74 75 data = textBuffer->data(); 76 size = textBuffer->size(); 77 78 if (size > 0) { 79 parcel->freeData(); 80 flag |= TextDescriptions::IN_BAND_TEXT_3GPP; 81 return TextDescriptions::getParcelOfDescriptions( 82 (const uint8_t *)data, size, flag, timeUs / 1000, parcel); 83 } 84 return OK; 85 } 86 87 // To extract and send the global text descriptions for all the text samples 88 // in the text track or text file. 89 // TODO: send error message to application via notifyListener()...? 90 status_t TimedText3GPPSource::extractGlobalDescriptions(Parcel *parcel) { 91 const void *data; 92 size_t size = 0; 93 int32_t flag = TextDescriptions::GLOBAL_DESCRIPTIONS; 94 95 const char *mime; 96 CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime)); 97 CHECK(strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) == 0); 98 99 uint32_t type; 100 // get the 'tx3g' box content. This box contains the text descriptions 101 // used to render the text track 102 if (!mSource->getFormat()->findData( 103 kKeyTextFormatData, &type, &data, &size)) { 104 return ERROR_MALFORMED; 105 } 106 107 if (size > 0) { 108 flag |= TextDescriptions::IN_BAND_TEXT_3GPP; 109 return TextDescriptions::getParcelOfDescriptions( 110 (const uint8_t *)data, size, flag, 0, parcel); 111 } 112 return OK; 113 } 114 115 sp<MetaData> TimedText3GPPSource::getFormat() { 116 return mSource->getFormat(); 117 } 118 119 } // namespace android 120