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 AnotherPacketSource::~AnotherPacketSource() {
     37 }
     38 
     39 status_t AnotherPacketSource::start(MetaData *params) {
     40     return OK;
     41 }
     42 
     43 status_t AnotherPacketSource::stop() {
     44     return OK;
     45 }
     46 
     47 sp<MetaData> AnotherPacketSource::getFormat() {
     48     return mFormat;
     49 }
     50 
     51 status_t AnotherPacketSource::read(
     52         MediaBuffer **out, const ReadOptions *) {
     53     *out = NULL;
     54 
     55     Mutex::Autolock autoLock(mLock);
     56     while (mEOSResult == OK && mBuffers.empty()) {
     57         mCondition.wait(mLock);
     58     }
     59 
     60     if (!mBuffers.empty()) {
     61         const sp<ABuffer> buffer = *mBuffers.begin();
     62         mBuffers.erase(mBuffers.begin());
     63 
     64         int32_t discontinuity;
     65         if (buffer->meta()->findInt32("discontinuity", &discontinuity)
     66                 && discontinuity) {
     67             return INFO_DISCONTINUITY;
     68         } else {
     69             uint64_t timeUs;
     70             CHECK(buffer->meta()->findInt64(
     71                         "time", (int64_t *)&timeUs));
     72 
     73             MediaBuffer *mediaBuffer = new MediaBuffer(buffer->size());
     74             mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
     75 
     76             // hexdump(buffer->data(), buffer->size());
     77 
     78             memcpy(mediaBuffer->data(), buffer->data(), buffer->size());
     79             *out = mediaBuffer;
     80             return OK;
     81         }
     82     }
     83 
     84     return mEOSResult;
     85 }
     86 
     87 void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
     88     int32_t damaged;
     89     if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
     90         // LOG(VERBOSE) << "discarding damaged AU";
     91         return;
     92     }
     93 
     94     int64_t timeUs;
     95     CHECK(buffer->meta()->findInt64("time", &timeUs));
     96     LOGV("queueAccessUnit timeUs=%lld us (%.2f secs)", timeUs, timeUs / 1E6);
     97 
     98     Mutex::Autolock autoLock(mLock);
     99     mBuffers.push_back(buffer);
    100     mCondition.signal();
    101 }
    102 
    103 void AnotherPacketSource::queueDiscontinuity() {
    104     sp<ABuffer> buffer = new ABuffer(0);
    105     buffer->meta()->setInt32("discontinuity", true);
    106 
    107     Mutex::Autolock autoLock(mLock);
    108 
    109     mBuffers.push_back(buffer);
    110     mCondition.signal();
    111 }
    112 
    113 void AnotherPacketSource::clear() {
    114     Mutex::Autolock autoLock(mLock);
    115     mBuffers.clear();
    116     mEOSResult = OK;
    117 }
    118 
    119 void AnotherPacketSource::signalEOS(status_t result) {
    120     CHECK(result != OK);
    121 
    122     Mutex::Autolock autoLock(mLock);
    123     mEOSResult = result;
    124     mCondition.signal();
    125 }
    126 
    127 bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) {
    128     Mutex::Autolock autoLock(mLock);
    129     if (!mBuffers.empty()) {
    130         return true;
    131     }
    132 
    133     *finalResult = mEOSResult;
    134     return false;
    135 }
    136 
    137 }  // namespace android
    138