Home | History | Annotate | Download | only in timedtext
      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