Home | History | Annotate | Download | only in libstagefright
      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 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "MPEG2TSWriter"
     19 #include <media/stagefright/foundation/ADebug.h>
     20 
     21 #include <media/stagefright/foundation/hexdump.h>
     22 #include <media/stagefright/foundation/ABuffer.h>
     23 #include <media/stagefright/foundation/AMessage.h>
     24 #include <media/stagefright/MPEG2TSWriter.h>
     25 #include <media/stagefright/MediaBuffer.h>
     26 #include <media/stagefright/MediaDefs.h>
     27 #include <media/stagefright/MediaErrors.h>
     28 #include <media/stagefright/MediaSource.h>
     29 #include <media/stagefright/MetaData.h>
     30 #include <media/stagefright/Utils.h>
     31 #include <arpa/inet.h>
     32 
     33 #include "include/ESDS.h"
     34 
     35 namespace android {
     36 
     37 struct MPEG2TSWriter::SourceInfo : public AHandler {
     38     explicit SourceInfo(const sp<IMediaSource> &source);
     39 
     40     void start(const sp<AMessage> &notify, const sp<MetaData> &params);
     41     void stop();
     42 
     43     unsigned streamType() const;
     44     unsigned incrementContinuityCounter();
     45 
     46     void readMore();
     47 
     48     enum {
     49         kNotifyStartFailed,
     50         kNotifyBuffer,
     51         kNotifyReachedEOS,
     52     };
     53 
     54     sp<ABuffer> lastAccessUnit();
     55     int64_t lastAccessUnitTimeUs();
     56     void setLastAccessUnit(const sp<ABuffer> &accessUnit);
     57 
     58     void setEOSReceived();
     59     bool eosReceived() const;
     60 
     61 protected:
     62     virtual void onMessageReceived(const sp<AMessage> &msg);
     63 
     64     virtual ~SourceInfo();
     65 
     66 private:
     67     enum {
     68         kWhatStart = 'strt',
     69         kWhatRead  = 'read',
     70     };
     71 
     72     sp<IMediaSource> mSource;
     73     sp<ALooper> mLooper;
     74     sp<AMessage> mNotify;
     75 
     76     sp<ABuffer> mAACCodecSpecificData;
     77 
     78     sp<ABuffer> mBuffer;
     79 
     80     sp<ABuffer> mLastAccessUnit;
     81     bool mEOSReceived;
     82 
     83     unsigned mStreamType;
     84     unsigned mContinuityCounter;
     85 
     86     void extractCodecSpecificData();
     87 
     88     void appendAACFrames(MediaBuffer *buffer);
     89     void appendAVCFrame(MediaBuffer *buffer);
     90 
     91     DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
     92 };
     93 
     94 MPEG2TSWriter::SourceInfo::SourceInfo(const sp<IMediaSource> &source)
     95     : mSource(source),
     96       mLooper(new ALooper),
     97       mEOSReceived(false),
     98       mStreamType(0),
     99       mContinuityCounter(0) {
    100     mLooper->setName("MPEG2TSWriter source");
    101 
    102     sp<MetaData> meta = mSource->getFormat();
    103     const char *mime;
    104     CHECK(meta->findCString(kKeyMIMEType, &mime));
    105 
    106     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    107         mStreamType = 0x0f;
    108     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
    109         mStreamType = 0x1b;
    110     } else {
    111         TRESPASS();
    112     }
    113 }
    114 
    115 MPEG2TSWriter::SourceInfo::~SourceInfo() {
    116 }
    117 
    118 unsigned MPEG2TSWriter::SourceInfo::streamType() const {
    119     return mStreamType;
    120 }
    121 
    122 unsigned MPEG2TSWriter::SourceInfo::incrementContinuityCounter() {
    123     if (++mContinuityCounter == 16) {
    124         mContinuityCounter = 0;
    125     }
    126 
    127     return mContinuityCounter;
    128 }
    129 
    130 void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> &notify, const sp<MetaData> &params) {
    131     mLooper->registerHandler(this);
    132     mLooper->start();
    133     mNotify = notify;
    134 
    135     sp<AMessage> msg = new AMessage(kWhatStart, this);
    136     msg->setObject("meta", params);
    137     msg->post();
    138 }
    139 
    140 void MPEG2TSWriter::SourceInfo::stop() {
    141     mLooper->unregisterHandler(id());
    142     mLooper->stop();
    143 
    144     mSource->stop();
    145 }
    146 
    147 void MPEG2TSWriter::SourceInfo::extractCodecSpecificData() {
    148     sp<MetaData> meta = mSource->getFormat();
    149 
    150     const char *mime;
    151     CHECK(meta->findCString(kKeyMIMEType, &mime));
    152 
    153     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    154         uint32_t type;
    155         const void *data;
    156         size_t size;
    157         if (!meta->findData(kKeyESDS, &type, &data, &size)) {
    158             // Codec specific data better be in the first data buffer.
    159             return;
    160         }
    161 
    162         ESDS esds((const char *)data, size);
    163         CHECK_EQ(esds.InitCheck(), (status_t)OK);
    164 
    165         const uint8_t *codec_specific_data;
    166         size_t codec_specific_data_size;
    167         esds.getCodecSpecificInfo(
    168                 (const void **)&codec_specific_data, &codec_specific_data_size);
    169 
    170         CHECK_GE(codec_specific_data_size, 2u);
    171 
    172         mAACCodecSpecificData = new ABuffer(codec_specific_data_size);
    173 
    174         memcpy(mAACCodecSpecificData->data(), codec_specific_data,
    175                codec_specific_data_size);
    176 
    177         return;
    178     }
    179 
    180     if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
    181         return;
    182     }
    183 
    184     uint32_t type;
    185     const void *data;
    186     size_t size;
    187     if (!meta->findData(kKeyAVCC, &type, &data, &size)) {
    188         // Codec specific data better be part of the data stream then.
    189         return;
    190     }
    191 
    192     sp<ABuffer> out = new ABuffer(1024);
    193     out->setRange(0, 0);
    194 
    195     const uint8_t *ptr = (const uint8_t *)data;
    196 
    197     size_t numSeqParameterSets = ptr[5] & 31;
    198 
    199     ptr += 6;
    200     size -= 6;
    201 
    202     for (size_t i = 0; i < numSeqParameterSets; ++i) {
    203         CHECK(size >= 2);
    204         size_t length = U16_AT(ptr);
    205 
    206         ptr += 2;
    207         size -= 2;
    208 
    209         CHECK(size >= length);
    210 
    211         CHECK_LE(out->size() + 4 + length, out->capacity());
    212         memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
    213         memcpy(out->data() + out->size() + 4, ptr, length);
    214         out->setRange(0, out->size() + length + 4);
    215 
    216         ptr += length;
    217         size -= length;
    218     }
    219 
    220     CHECK(size >= 1);
    221     size_t numPictureParameterSets = *ptr;
    222     ++ptr;
    223     --size;
    224 
    225     for (size_t i = 0; i < numPictureParameterSets; ++i) {
    226         CHECK(size >= 2);
    227         size_t length = U16_AT(ptr);
    228 
    229         ptr += 2;
    230         size -= 2;
    231 
    232         CHECK(size >= length);
    233 
    234         CHECK_LE(out->size() + 4 + length, out->capacity());
    235         memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
    236         memcpy(out->data() + out->size() + 4, ptr, length);
    237         out->setRange(0, out->size() + length + 4);
    238 
    239         ptr += length;
    240         size -= length;
    241     }
    242 
    243     out->meta()->setInt64("timeUs", 0ll);
    244 
    245     sp<AMessage> notify = mNotify->dup();
    246     notify->setInt32("what", kNotifyBuffer);
    247     notify->setBuffer("buffer", out);
    248     notify->setInt32("oob", true);
    249     notify->post();
    250 }
    251 
    252 void MPEG2TSWriter::SourceInfo::appendAVCFrame(MediaBuffer *buffer) {
    253     sp<AMessage> notify = mNotify->dup();
    254     notify->setInt32("what", kNotifyBuffer);
    255 
    256     if (mBuffer == NULL || buffer->range_length() > mBuffer->capacity()) {
    257         mBuffer = new ABuffer(buffer->range_length());
    258     }
    259     mBuffer->setRange(0, 0);
    260 
    261     memcpy(mBuffer->data(),
    262            (const uint8_t *)buffer->data()
    263             + buffer->range_offset(),
    264            buffer->range_length());
    265 
    266     int64_t timeUs;
    267     CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
    268     mBuffer->meta()->setInt64("timeUs", timeUs);
    269 
    270     int32_t isSync;
    271     if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)
    272             && isSync != 0) {
    273         mBuffer->meta()->setInt32("isSync", true);
    274     }
    275 
    276     mBuffer->setRange(0, buffer->range_length());
    277 
    278     notify->setBuffer("buffer", mBuffer);
    279     notify->post();
    280 }
    281 
    282 void MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBuffer *buffer) {
    283     sp<AMessage> notify = mNotify->dup();
    284     notify->setInt32("what", kNotifyBuffer);
    285 
    286     if (mBuffer == NULL || 7 + buffer->range_length() > mBuffer->capacity()) {
    287         mBuffer = new ABuffer(7 + buffer->range_length());
    288     }
    289 
    290     int64_t timeUs;
    291     CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
    292 
    293     mBuffer->meta()->setInt64("timeUs", timeUs);
    294     mBuffer->meta()->setInt32("isSync", true);
    295 
    296     mBuffer->setRange(0, 0);
    297 
    298     const uint8_t *codec_specific_data = mAACCodecSpecificData->data();
    299 
    300     unsigned profile = (codec_specific_data[0] >> 3) - 1;
    301 
    302     unsigned sampling_freq_index =
    303         ((codec_specific_data[0] & 7) << 1)
    304         | (codec_specific_data[1] >> 7);
    305 
    306     unsigned channel_configuration =
    307         (codec_specific_data[1] >> 3) & 0x0f;
    308 
    309     uint8_t *ptr = mBuffer->data() + mBuffer->size();
    310 
    311     const uint32_t aac_frame_length = buffer->range_length() + 7;
    312 
    313     *ptr++ = 0xff;
    314     *ptr++ = 0xf1;  // b11110001, ID=0, layer=0, protection_absent=1
    315 
    316     *ptr++ =
    317         profile << 6
    318         | sampling_freq_index << 2
    319         | ((channel_configuration >> 2) & 1);  // private_bit=0
    320 
    321     // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0
    322     *ptr++ =
    323         (channel_configuration & 3) << 6
    324         | aac_frame_length >> 11;
    325     *ptr++ = (aac_frame_length >> 3) & 0xff;
    326     *ptr++ = (aac_frame_length & 7) << 5;
    327 
    328     // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0
    329     *ptr++ = 0;
    330 
    331     memcpy(ptr,
    332            (const uint8_t *)buffer->data() + buffer->range_offset(),
    333            buffer->range_length());
    334 
    335     ptr += buffer->range_length();
    336 
    337     mBuffer->setRange(0, ptr - mBuffer->data());
    338 
    339     notify->setBuffer("buffer", mBuffer);
    340     notify->post();
    341 }
    342 
    343 void MPEG2TSWriter::SourceInfo::readMore() {
    344     (new AMessage(kWhatRead, this))->post();
    345 }
    346 
    347 void MPEG2TSWriter::SourceInfo::onMessageReceived(const sp<AMessage> &msg) {
    348     switch (msg->what()) {
    349         case kWhatStart:
    350         {
    351             sp<RefBase> obj;
    352             CHECK(msg->findObject("meta", &obj));
    353             MetaData *params = static_cast<MetaData *>(obj.get());
    354             status_t err = mSource->start(params);
    355             if (err != OK) {
    356                 sp<AMessage> notify = mNotify->dup();
    357                 notify->setInt32("what", kNotifyStartFailed);
    358                 notify->post();
    359                 break;
    360             }
    361 
    362             // Extract CSD from config format.
    363             extractCodecSpecificData();
    364 
    365             readMore();
    366             break;
    367         }
    368 
    369         case kWhatRead:
    370         {
    371             MediaBuffer *buffer;
    372             status_t err = mSource->read(&buffer);
    373 
    374             if (err != OK && err != INFO_FORMAT_CHANGED) {
    375                 sp<AMessage> notify = mNotify->dup();
    376                 notify->setInt32("what", kNotifyReachedEOS);
    377                 notify->setInt32("status", err);
    378                 notify->post();
    379                 break;
    380             }
    381 
    382             if (err == OK) {
    383                 if (mStreamType == 0x0f && mAACCodecSpecificData == NULL) {
    384                     // The first audio buffer must contain CSD if not received yet.
    385                     CHECK_GE(buffer->range_length(), 2u);
    386                     mAACCodecSpecificData = new ABuffer(buffer->range_length());
    387 
    388                     memcpy(mAACCodecSpecificData->data(),
    389                            (const uint8_t *)buffer->data()
    390                             + buffer->range_offset(),
    391                            buffer->range_length());
    392                     readMore();
    393                 } else if (buffer->range_length() > 0) {
    394                     if (mStreamType == 0x0f) {
    395                         appendAACFrames(buffer);
    396                     } else {
    397                         appendAVCFrame(buffer);
    398                     }
    399                 } else {
    400                     readMore();
    401                 }
    402 
    403                 buffer->release();
    404                 buffer = NULL;
    405             }
    406 
    407             // Do not read more data until told to.
    408             break;
    409         }
    410 
    411         default:
    412             TRESPASS();
    413     }
    414 }
    415 
    416 sp<ABuffer> MPEG2TSWriter::SourceInfo::lastAccessUnit() {
    417     return mLastAccessUnit;
    418 }
    419 
    420 void MPEG2TSWriter::SourceInfo::setLastAccessUnit(
    421         const sp<ABuffer> &accessUnit) {
    422     mLastAccessUnit = accessUnit;
    423 }
    424 
    425 int64_t MPEG2TSWriter::SourceInfo::lastAccessUnitTimeUs() {
    426     if (mLastAccessUnit == NULL) {
    427         return -1;
    428     }
    429 
    430     int64_t timeUs;
    431     CHECK(mLastAccessUnit->meta()->findInt64("timeUs", &timeUs));
    432     return timeUs;
    433 }
    434 
    435 void MPEG2TSWriter::SourceInfo::setEOSReceived() {
    436     CHECK(!mEOSReceived);
    437     mEOSReceived = true;
    438 }
    439 
    440 bool MPEG2TSWriter::SourceInfo::eosReceived() const {
    441     return mEOSReceived;
    442 }
    443 
    444 ////////////////////////////////////////////////////////////////////////////////
    445 
    446 MPEG2TSWriter::MPEG2TSWriter(int fd)
    447     : mFile(fdopen(dup(fd), "wb")),
    448       mWriteCookie(NULL),
    449       mWriteFunc(NULL),
    450       mStarted(false),
    451       mNumSourcesDone(0),
    452       mNumTSPacketsWritten(0),
    453       mNumTSPacketsBeforeMeta(0),
    454       mPATContinuityCounter(0),
    455       mPMTContinuityCounter(0) {
    456     init();
    457 }
    458 
    459 MPEG2TSWriter::MPEG2TSWriter(
    460         void *cookie,
    461         ssize_t (*write)(void *cookie, const void *data, size_t size))
    462     : mFile(NULL),
    463       mWriteCookie(cookie),
    464       mWriteFunc(write),
    465       mStarted(false),
    466       mNumSourcesDone(0),
    467       mNumTSPacketsWritten(0),
    468       mNumTSPacketsBeforeMeta(0),
    469       mPATContinuityCounter(0),
    470       mPMTContinuityCounter(0) {
    471     init();
    472 }
    473 
    474 void MPEG2TSWriter::init() {
    475     CHECK(mFile != NULL || mWriteFunc != NULL);
    476 
    477     initCrcTable();
    478 
    479     mLooper = new ALooper;
    480     mLooper->setName("MPEG2TSWriter");
    481 
    482     mReflector = new AHandlerReflector<MPEG2TSWriter>(this);
    483 
    484     mLooper->registerHandler(mReflector);
    485     mLooper->start();
    486 }
    487 
    488 MPEG2TSWriter::~MPEG2TSWriter() {
    489     if (mStarted) {
    490         reset();
    491     }
    492 
    493     mLooper->unregisterHandler(mReflector->id());
    494     mLooper->stop();
    495 
    496     if (mFile != NULL) {
    497         fclose(mFile);
    498         mFile = NULL;
    499     }
    500 }
    501 
    502 status_t MPEG2TSWriter::addSource(const sp<IMediaSource> &source) {
    503     CHECK(!mStarted);
    504 
    505     sp<MetaData> meta = source->getFormat();
    506     const char *mime;
    507     CHECK(meta->findCString(kKeyMIMEType, &mime));
    508 
    509     if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
    510             && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
    511         return ERROR_UNSUPPORTED;
    512     }
    513 
    514     sp<SourceInfo> info = new SourceInfo(source);
    515 
    516     mSources.push(info);
    517 
    518     return OK;
    519 }
    520 
    521 status_t MPEG2TSWriter::start(MetaData *param ) {
    522     CHECK(!mStarted);
    523 
    524     mStarted = true;
    525     mNumSourcesDone = 0;
    526     mNumTSPacketsWritten = 0;
    527     mNumTSPacketsBeforeMeta = 0;
    528 
    529     for (size_t i = 0; i < mSources.size(); ++i) {
    530         sp<AMessage> notify =
    531             new AMessage(kWhatSourceNotify, mReflector);
    532 
    533         notify->setInt32("source-index", i);
    534 
    535         mSources.editItemAt(i)->start(notify, param);
    536     }
    537 
    538     return OK;
    539 }
    540 
    541 status_t MPEG2TSWriter::reset() {
    542     CHECK(mStarted);
    543 
    544     for (size_t i = 0; i < mSources.size(); ++i) {
    545         mSources.editItemAt(i)->stop();
    546     }
    547     mStarted = false;
    548 
    549     return OK;
    550 }
    551 
    552 status_t MPEG2TSWriter::pause() {
    553     CHECK(mStarted);
    554 
    555     return OK;
    556 }
    557 
    558 bool MPEG2TSWriter::reachedEOS() {
    559     return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
    560 }
    561 
    562 status_t MPEG2TSWriter::dump(
    563         int /* fd */, const Vector<String16> & /* args */) {
    564     return OK;
    565 }
    566 
    567 void MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
    568     switch (msg->what()) {
    569         case kWhatSourceNotify:
    570         {
    571             int32_t sourceIndex;
    572             CHECK(msg->findInt32("source-index", &sourceIndex));
    573             sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
    574 
    575             int32_t what;
    576             CHECK(msg->findInt32("what", &what));
    577 
    578             if (what == SourceInfo::kNotifyReachedEOS
    579                     || what == SourceInfo::kNotifyStartFailed) {
    580                 source->setEOSReceived();
    581 
    582                 sp<ABuffer> buffer = source->lastAccessUnit();
    583                 source->setLastAccessUnit(NULL);
    584 
    585                 if (buffer != NULL) {
    586                     writeTS();
    587                     writeAccessUnit(sourceIndex, buffer);
    588                 }
    589 
    590                 ++mNumSourcesDone;
    591             } else if (what == SourceInfo::kNotifyBuffer) {
    592                 sp<ABuffer> buffer;
    593                 CHECK(msg->findBuffer("buffer", &buffer));
    594                 CHECK(source->lastAccessUnit() == NULL);
    595 
    596                 int32_t oob;
    597                 if (msg->findInt32("oob", &oob) && oob) {
    598                     // This is codec specific data delivered out of band.
    599                     // It can be written out immediately.
    600                     writeTS();
    601                     writeAccessUnit(sourceIndex, buffer);
    602                     break;
    603                 }
    604 
    605                 // We don't just write out data as we receive it from
    606                 // the various sources. That would essentially write them
    607                 // out in random order (as the thread scheduler determines
    608                 // how the messages are dispatched).
    609                 // Instead we gather an access unit for all tracks and
    610                 // write out the one with the smallest timestamp, then
    611                 // request more data for the written out track.
    612                 // Rinse, repeat.
    613                 // If we don't have data on any track we don't write
    614                 // anything just yet.
    615                 source->setLastAccessUnit(buffer);
    616 
    617                 ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
    618                     sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
    619                 int64_t minTimeUs = -1;
    620                 size_t minIndex = 0;
    621 
    622                 for (size_t i = 0; i < mSources.size(); ++i) {
    623                     const sp<SourceInfo> &source = mSources.editItemAt(i);
    624 
    625                     if (source->eosReceived()) {
    626                         continue;
    627                     }
    628 
    629                     int64_t timeUs = source->lastAccessUnitTimeUs();
    630                     if (timeUs < 0) {
    631                         minTimeUs = -1;
    632                         break;
    633                     } else if (minTimeUs < 0 || timeUs < minTimeUs) {
    634                         minTimeUs = timeUs;
    635                         minIndex = i;
    636                     }
    637                 }
    638 
    639                 if (minTimeUs < 0) {
    640                     ALOGV("not all tracks have valid data.");
    641                     break;
    642                 }
    643 
    644                 ALOGV("writing access unit at time %.2f secs (index %zu)",
    645                     minTimeUs / 1E6, minIndex);
    646 
    647                 source = mSources.editItemAt(minIndex);
    648                 buffer = source->lastAccessUnit();
    649                 source->setLastAccessUnit(NULL);
    650 
    651                 writeTS();
    652                 writeAccessUnit(minIndex, buffer);
    653 
    654                 source->readMore();
    655             }
    656             break;
    657         }
    658 
    659         default:
    660             TRESPASS();
    661     }
    662 }
    663 
    664 void MPEG2TSWriter::writeProgramAssociationTable() {
    665     // 0x47
    666     // transport_error_indicator = b0
    667     // payload_unit_start_indicator = b1
    668     // transport_priority = b0
    669     // PID = b0000000000000 (13 bits)
    670     // transport_scrambling_control = b00
    671     // adaptation_field_control = b01 (no adaptation field, payload only)
    672     // continuity_counter = b????
    673     // skip = 0x00
    674     // --- payload follows
    675     // table_id = 0x00
    676     // section_syntax_indicator = b1
    677     // must_be_zero = b0
    678     // reserved = b11
    679     // section_length = 0x00d
    680     // transport_stream_id = 0x0000
    681     // reserved = b11
    682     // version_number = b00001
    683     // current_next_indicator = b1
    684     // section_number = 0x00
    685     // last_section_number = 0x00
    686     //   one program follows:
    687     //   program_number = 0x0001
    688     //   reserved = b111
    689     //   program_map_PID = 0x01e0 (13 bits!)
    690     // CRC = 0x????????
    691 
    692     static const uint8_t kData[] = {
    693         0x47,
    694         0x40, 0x00, 0x10, 0x00,  // b0100 0000 0000 0000 0001 ???? 0000 0000
    695         0x00, 0xb0, 0x0d, 0x00,  // b0000 0000 1011 0000 0000 1101 0000 0000
    696         0x00, 0xc3, 0x00, 0x00,  // b0000 0000 1100 0011 0000 0000 0000 0000
    697         0x00, 0x01, 0xe1, 0xe0,  // b0000 0000 0000 0001 1110 0001 1110 0000
    698         0x00, 0x00, 0x00, 0x00   // b???? ???? ???? ???? ???? ???? ???? ????
    699     };
    700 
    701     sp<ABuffer> buffer = new ABuffer(188);
    702     memset(buffer->data(), 0xff, buffer->size());
    703     memcpy(buffer->data(), kData, sizeof(kData));
    704 
    705     if (++mPATContinuityCounter == 16) {
    706         mPATContinuityCounter = 0;
    707     }
    708     buffer->data()[3] |= mPATContinuityCounter;
    709 
    710     uint32_t crc = htonl(crc32(&buffer->data()[5], 12));
    711     memcpy(&buffer->data()[17], &crc, sizeof(crc));
    712 
    713     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
    714 }
    715 
    716 void MPEG2TSWriter::writeProgramMap() {
    717     // 0x47
    718     // transport_error_indicator = b0
    719     // payload_unit_start_indicator = b1
    720     // transport_priority = b0
    721     // PID = b0 0001 1110 0000 (13 bits) [0x1e0]
    722     // transport_scrambling_control = b00
    723     // adaptation_field_control = b01 (no adaptation field, payload only)
    724     // continuity_counter = b????
    725     // skip = 0x00
    726     // -- payload follows
    727     // table_id = 0x02
    728     // section_syntax_indicator = b1
    729     // must_be_zero = b0
    730     // reserved = b11
    731     // section_length = 0x???
    732     // program_number = 0x0001
    733     // reserved = b11
    734     // version_number = b00001
    735     // current_next_indicator = b1
    736     // section_number = 0x00
    737     // last_section_number = 0x00
    738     // reserved = b111
    739     // PCR_PID = b? ???? ???? ???? (13 bits)
    740     // reserved = b1111
    741     // program_info_length = 0x000
    742     //   one or more elementary stream descriptions follow:
    743     //   stream_type = 0x??
    744     //   reserved = b111
    745     //   elementary_PID = b? ???? ???? ???? (13 bits)
    746     //   reserved = b1111
    747     //   ES_info_length = 0x000
    748     // CRC = 0x????????
    749 
    750     static const uint8_t kData[] = {
    751         0x47,
    752         0x41, 0xe0, 0x10, 0x00,  // b0100 0001 1110 0000 0001 ???? 0000 0000
    753         0x02, 0xb0, 0x00, 0x00,  // b0000 0010 1011 ???? ???? ???? 0000 0000
    754         0x01, 0xc3, 0x00, 0x00,  // b0000 0001 1100 0011 0000 0000 0000 0000
    755         0xe0, 0x00, 0xf0, 0x00   // b111? ???? ???? ???? 1111 0000 0000 0000
    756     };
    757 
    758     sp<ABuffer> buffer = new ABuffer(188);
    759     memset(buffer->data(), 0xff, buffer->size());
    760     memcpy(buffer->data(), kData, sizeof(kData));
    761 
    762     if (++mPMTContinuityCounter == 16) {
    763         mPMTContinuityCounter = 0;
    764     }
    765     buffer->data()[3] |= mPMTContinuityCounter;
    766 
    767     size_t section_length = 5 * mSources.size() + 4 + 9;
    768     buffer->data()[6] |= section_length >> 8;
    769     buffer->data()[7] = section_length & 0xff;
    770 
    771     static const unsigned kPCR_PID = 0x1e1;
    772     buffer->data()[13] |= (kPCR_PID >> 8) & 0x1f;
    773     buffer->data()[14] = kPCR_PID & 0xff;
    774 
    775     uint8_t *ptr = &buffer->data()[sizeof(kData)];
    776     for (size_t i = 0; i < mSources.size(); ++i) {
    777         *ptr++ = mSources.editItemAt(i)->streamType();
    778 
    779         const unsigned ES_PID = 0x1e0 + i + 1;
    780         *ptr++ = 0xe0 | (ES_PID >> 8);
    781         *ptr++ = ES_PID & 0xff;
    782         *ptr++ = 0xf0;
    783         *ptr++ = 0x00;
    784     }
    785 
    786     uint32_t crc = htonl(crc32(&buffer->data()[5], 12+mSources.size()*5));
    787     memcpy(&buffer->data()[17+mSources.size()*5], &crc, sizeof(crc));
    788 
    789     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
    790 }
    791 
    792 void MPEG2TSWriter::writeAccessUnit(
    793         int32_t sourceIndex, const sp<ABuffer> &accessUnit) {
    794     // 0x47
    795     // transport_error_indicator = b0
    796     // payload_unit_start_indicator = b1
    797     // transport_priority = b0
    798     // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
    799     // transport_scrambling_control = b00
    800     // adaptation_field_control = b??
    801     // continuity_counter = b????
    802     // -- payload follows
    803     // packet_startcode_prefix = 0x000001
    804     // stream_id = 0x?? (0xe0 for avc video, 0xc0 for aac audio)
    805     // PES_packet_length = 0x????
    806     // reserved = b10
    807     // PES_scrambling_control = b00
    808     // PES_priority = b0
    809     // data_alignment_indicator = b1
    810     // copyright = b0
    811     // original_or_copy = b0
    812     // PTS_DTS_flags = b10  (PTS only)
    813     // ESCR_flag = b0
    814     // ES_rate_flag = b0
    815     // DSM_trick_mode_flag = b0
    816     // additional_copy_info_flag = b0
    817     // PES_CRC_flag = b0
    818     // PES_extension_flag = b0
    819     // PES_header_data_length = 0x05
    820     // reserved = b0010 (PTS)
    821     // PTS[32..30] = b???
    822     // reserved = b1
    823     // PTS[29..15] = b??? ???? ???? ???? (15 bits)
    824     // reserved = b1
    825     // PTS[14..0] = b??? ???? ???? ???? (15 bits)
    826     // reserved = b1
    827     // the first fragment of "buffer" follows
    828 
    829     sp<ABuffer> buffer = new ABuffer(188);
    830     memset(buffer->data(), 0xff, buffer->size());
    831 
    832     const unsigned PID = 0x1e0 + sourceIndex + 1;
    833 
    834     const unsigned continuity_counter =
    835         mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
    836 
    837     // XXX if there are multiple streams of a kind (more than 1 audio or
    838     // more than 1 video) they need distinct stream_ids.
    839     const unsigned stream_id =
    840         mSources.editItemAt(sourceIndex)->streamType() == 0x0f ? 0xc0 : 0xe0;
    841 
    842     int64_t timeUs;
    843     CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
    844 
    845     uint32_t PTS = (timeUs * 9ll) / 100ll;
    846 
    847     size_t PES_packet_length = accessUnit->size() + 8;
    848     bool padding = (accessUnit->size() < (188 - 18));
    849 
    850     if (PES_packet_length >= 65536) {
    851         // This really should only happen for video.
    852         CHECK_EQ(stream_id, 0xe0u);
    853 
    854         // It's valid to set this to 0 for video according to the specs.
    855         PES_packet_length = 0;
    856     }
    857 
    858     uint8_t *ptr = buffer->data();
    859     *ptr++ = 0x47;
    860     *ptr++ = 0x40 | (PID >> 8);
    861     *ptr++ = PID & 0xff;
    862     *ptr++ = (padding ? 0x30 : 0x10) | continuity_counter;
    863     if (padding) {
    864         int paddingSize = 188 - accessUnit->size() - 18;
    865         *ptr++ = paddingSize - 1;
    866         if (paddingSize >= 2) {
    867             *ptr++ = 0x00;
    868             ptr += paddingSize - 2;
    869         }
    870     }
    871     *ptr++ = 0x00;
    872     *ptr++ = 0x00;
    873     *ptr++ = 0x01;
    874     *ptr++ = stream_id;
    875     *ptr++ = PES_packet_length >> 8;
    876     *ptr++ = PES_packet_length & 0xff;
    877     *ptr++ = 0x84;
    878     *ptr++ = 0x80;
    879     *ptr++ = 0x05;
    880     *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
    881     *ptr++ = (PTS >> 22) & 0xff;
    882     *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
    883     *ptr++ = (PTS >> 7) & 0xff;
    884     *ptr++ = ((PTS & 0x7f) << 1) | 1;
    885 
    886     size_t sizeLeft = buffer->data() + buffer->size() - ptr;
    887     size_t copy = accessUnit->size();
    888     if (copy > sizeLeft) {
    889         copy = sizeLeft;
    890     }
    891 
    892     memcpy(ptr, accessUnit->data(), copy);
    893 
    894     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), (ssize_t)buffer->size());
    895 
    896     size_t offset = copy;
    897     while (offset < accessUnit->size()) {
    898         bool lastAccessUnit = ((accessUnit->size() - offset) < 184);
    899         // for subsequent fragments of "buffer":
    900         // 0x47
    901         // transport_error_indicator = b0
    902         // payload_unit_start_indicator = b0
    903         // transport_priority = b0
    904         // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
    905         // transport_scrambling_control = b00
    906         // adaptation_field_control = b??
    907         // continuity_counter = b????
    908         // the fragment of "buffer" follows.
    909 
    910         memset(buffer->data(), 0xff, buffer->size());
    911 
    912         const unsigned continuity_counter =
    913             mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
    914 
    915         ptr = buffer->data();
    916         *ptr++ = 0x47;
    917         *ptr++ = 0x00 | (PID >> 8);
    918         *ptr++ = PID & 0xff;
    919         *ptr++ = (lastAccessUnit ? 0x30 : 0x10) | continuity_counter;
    920 
    921         if (lastAccessUnit) {
    922             // Pad packet using an adaptation field
    923             // Adaptation header all to 0 execpt size
    924             uint8_t paddingSize = (uint8_t)184 - (accessUnit->size() - offset);
    925             *ptr++ = paddingSize - 1;
    926             if (paddingSize >= 2) {
    927                 *ptr++ = 0x00;
    928                 ptr += paddingSize - 2;
    929             }
    930         }
    931 
    932         size_t sizeLeft = buffer->data() + buffer->size() - ptr;
    933         size_t copy = accessUnit->size() - offset;
    934         if (copy > sizeLeft) {
    935             copy = sizeLeft;
    936         }
    937 
    938         memcpy(ptr, accessUnit->data() + offset, copy);
    939         CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
    940                  (ssize_t)buffer->size());
    941 
    942         offset += copy;
    943     }
    944 }
    945 
    946 void MPEG2TSWriter::writeTS() {
    947     if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
    948         writeProgramAssociationTable();
    949         writeProgramMap();
    950 
    951         mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
    952     }
    953 }
    954 
    955 void MPEG2TSWriter::initCrcTable() {
    956     uint32_t poly = 0x04C11DB7;
    957 
    958     for (int i = 0; i < 256; i++) {
    959         uint32_t crc = i << 24;
    960         for (int j = 0; j < 8; j++) {
    961             crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
    962         }
    963         mCrcTable[i] = crc;
    964     }
    965 }
    966 
    967 /**
    968  * Compute CRC32 checksum for buffer starting at offset start and for length
    969  * bytes.
    970  */
    971 uint32_t MPEG2TSWriter::crc32(const uint8_t *p_start, size_t length) {
    972     uint32_t crc = 0xFFFFFFFF;
    973     const uint8_t *p;
    974 
    975     for (p = p_start; p < p_start + length; p++) {
    976         crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
    977     }
    978 
    979     return crc;
    980 }
    981 
    982 ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
    983     if (mFile != NULL) {
    984         return fwrite(data, 1, size, mFile);
    985     }
    986 
    987     return (*mWriteFunc)(mWriteCookie, data, size);
    988 }
    989 
    990 }  // namespace android
    991 
    992