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