Home | History | Annotate | Download | only in mpeg2ts
      1 /*
      2  * Copyright (C) 2010 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 #include "AnotherPacketSource.h"
     18 
     19 #include <media/stagefright/foundation/ABuffer.h>
     20 #include <media/stagefright/foundation/ADebug.h>
     21 #include <media/stagefright/foundation/AMessage.h>
     22 #include <media/stagefright/foundation/AString.h>
     23 #include <media/stagefright/foundation/hexdump.h>
     24 #include <media/stagefright/MediaBuffer.h>
     25 #include <media/stagefright/MediaDefs.h>
     26 #include <media/stagefright/MetaData.h>
     27 #include <utils/Vector.h>
     28 
     29 namespace android {
     30 
     31 AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
     32     : mFormat(meta),
     33       mEOSResult(OK) {
     34 }
     35 
     36 void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
     37     CHECK(mFormat == NULL);
     38     mFormat = meta;
     39 }
     40 
     41 AnotherPacketSource::~AnotherPacketSource() {
     42 }
     43 
     44 status_t AnotherPacketSource::start(MetaData *params) {
     45     return OK;
     46 }
     47 
     48 status_t AnotherPacketSource::stop() {
     49     return OK;
     50 }
     51 
     52 sp<MetaData> AnotherPacketSource::getFormat() {
     53     return mFormat;
     54 }
     55 
     56 status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
     57     buffer->clear();
     58 
     59     Mutex::Autolock autoLock(mLock);
     60     while (mEOSResult == OK && mBuffers.empty()) {
     61         mCondition.wait(mLock);
     62     }
     63 
     64     if (!mBuffers.empty()) {
     65         *buffer = *mBuffers.begin();
     66         mBuffers.erase(mBuffers.begin());
     67 
     68         int32_t discontinuity;
     69         if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
     70 
     71             if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
     72                 mFormat.clear();
     73             }
     74 
     75             return INFO_DISCONTINUITY;
     76         }
     77 
     78         return OK;
     79     }
     80 
     81     return mEOSResult;
     82 }
     83 
     84 status_t AnotherPacketSource::read(
     85         MediaBuffer **out, const ReadOptions *) {
     86     *out = NULL;
     87 
     88     Mutex::Autolock autoLock(mLock);
     89     while (mEOSResult == OK && mBuffers.empty()) {
     90         mCondition.wait(mLock);
     91     }
     92 
     93     if (!mBuffers.empty()) {
     94         const sp<ABuffer> buffer = *mBuffers.begin();
     95         mBuffers.erase(mBuffers.begin());
     96 
     97         int32_t discontinuity;
     98         if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
     99             if (discontinuity == ATSParser::DISCONTINUITY_FORMATCHANGE) {
    100                 mFormat.clear();
    101             }
    102 
    103             return INFO_DISCONTINUITY;
    104         } else {
    105             int64_t timeUs;
    106             CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
    107 
    108             MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
    109 
    110             mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
    111 
    112             *out = mediaBuffer;
    113             return OK;
    114         }
    115     }
    116 
    117     return mEOSResult;
    118 }
    119 
    120 void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
    121     int32_t damaged;
    122     if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
    123         // LOG(VERBOSE) << "discarding damaged AU";
    124         return;
    125     }
    126 
    127     int64_t timeUs;
    128     CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
    129     LOGV("queueAccessUnit timeUs=%lld us (%.2f secs)", timeUs, timeUs / 1E6);
    130 
    131     Mutex::Autolock autoLock(mLock);
    132     mBuffers.push_back(buffer);
    133     mCondition.signal();
    134 }
    135 
    136 void AnotherPacketSource::queueDiscontinuity(
    137         ATSParser::DiscontinuityType type,
    138         const sp<AMessage> &extra) {
    139     Mutex::Autolock autoLock(mLock);
    140 
    141     // Leave only discontinuities in the queue.
    142     List<sp<ABuffer> >::iterator it = mBuffers.begin();
    143     while (it != mBuffers.end()) {
    144         sp<ABuffer> oldBuffer = *it;
    145 
    146         int32_t oldDiscontinuityType;
    147         if (!oldBuffer->meta()->findInt32(
    148                     "discontinuity", &oldDiscontinuityType)) {
    149             it = mBuffers.erase(it);
    150             continue;
    151         }
    152 
    153         ++it;
    154     }
    155 
    156     mEOSResult = OK;
    157 
    158     sp<ABuffer> buffer = new ABuffer(0);
    159     buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
    160     buffer->meta()->setMessage("extra", extra);
    161 
    162     mBuffers.push_back(buffer);
    163     mCondition.signal();
    164 }
    165 
    166 void AnotherPacketSource::signalEOS(status_t result) {
    167     CHECK(result != OK);
    168 
    169     Mutex::Autolock autoLock(mLock);
    170     mEOSResult = result;
    171     mCondition.signal();
    172 }
    173 
    174 bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) {
    175     Mutex::Autolock autoLock(mLock);
    176     if (!mBuffers.empty()) {
    177         return true;
    178     }
    179 
    180     *finalResult = mEOSResult;
    181     return false;
    182 }
    183 
    184 status_t AnotherPacketSource::nextBufferTime(int64_t *timeUs) {
    185     *timeUs = 0;
    186 
    187     Mutex::Autolock autoLock(mLock);
    188 
    189     if (mBuffers.empty()) {
    190         return mEOSResult != OK ? mEOSResult : -EWOULDBLOCK;
    191     }
    192 
    193     sp<ABuffer> buffer = *mBuffers.begin();
    194     CHECK(buffer->meta()->findInt64("timeUs", timeUs));
    195 
    196     return OK;
    197 }
    198 
    199 }  // namespace android
    200