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(
    600         int /* fd */, const Vector<String16> & /* args */) {
    601     return OK;
    602 }
    603 
    604 void MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
    605     switch (msg->what()) {
    606         case kWhatSourceNotify:
    607         {
    608             int32_t sourceIndex;
    609             CHECK(msg->findInt32("source-index", &sourceIndex));
    610 
    611             int32_t what;
    612             CHECK(msg->findInt32("what", &what));
    613 
    614             if (what == SourceInfo::kNotifyReachedEOS
    615                     || what == SourceInfo::kNotifyStartFailed) {
    616                 sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
    617                 source->setEOSReceived();
    618 
    619                 sp<ABuffer> buffer = source->lastAccessUnit();
    620                 source->setLastAccessUnit(NULL);
    621 
    622                 if (buffer != NULL) {
    623                     writeTS();
    624                     writeAccessUnit(sourceIndex, buffer);
    625                 }
    626 
    627                 ++mNumSourcesDone;
    628             } else if (what == SourceInfo::kNotifyBuffer) {
    629                 sp<ABuffer> buffer;
    630                 CHECK(msg->findBuffer("buffer", &buffer));
    631 
    632                 int32_t oob;
    633                 if (msg->findInt32("oob", &oob) && oob) {
    634                     // This is codec specific data delivered out of band.
    635                     // It can be written out immediately.
    636                     writeTS();
    637                     writeAccessUnit(sourceIndex, buffer);
    638                     break;
    639                 }
    640 
    641                 // We don't just write out data as we receive it from
    642                 // the various sources. That would essentially write them
    643                 // out in random order (as the thread scheduler determines
    644                 // how the messages are dispatched).
    645                 // Instead we gather an access unit for all tracks and
    646                 // write out the one with the smallest timestamp, then
    647                 // request more data for the written out track.
    648                 // Rinse, repeat.
    649                 // If we don't have data on any track we don't write
    650                 // anything just yet.
    651 
    652                 sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
    653 
    654                 CHECK(source->lastAccessUnit() == NULL);
    655                 source->setLastAccessUnit(buffer);
    656 
    657                 ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
    658                      sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
    659 
    660                 int64_t minTimeUs = -1;
    661                 size_t minIndex = 0;
    662 
    663                 for (size_t i = 0; i < mSources.size(); ++i) {
    664                     const sp<SourceInfo> &source = mSources.editItemAt(i);
    665 
    666                     if (source->eosReceived()) {
    667                         continue;
    668                     }
    669 
    670                     int64_t timeUs = source->lastAccessUnitTimeUs();
    671                     if (timeUs < 0) {
    672                         minTimeUs = -1;
    673                         break;
    674                     } else if (minTimeUs < 0 || timeUs < minTimeUs) {
    675                         minTimeUs = timeUs;
    676                         minIndex = i;
    677                     }
    678                 }
    679 
    680                 if (minTimeUs < 0) {
    681                     ALOGV("not a all tracks have valid data.");
    682                     break;
    683                 }
    684 
    685                 ALOGV("writing access unit at time %.2f secs (index %zu)",
    686                      minTimeUs / 1E6, minIndex);
    687 
    688                 source = mSources.editItemAt(minIndex);
    689 
    690                 buffer = source->lastAccessUnit();
    691                 source->setLastAccessUnit(NULL);
    692 
    693                 writeTS();
    694                 writeAccessUnit(minIndex, buffer);
    695 
    696                 source->readMore();
    697             }
    698             break;
    699         }
    700 
    701         default:
    702             TRESPASS();
    703     }
    704 }
    705 
    706 void MPEG2TSWriter::writeProgramAssociationTable() {
    707     // 0x47
    708     // transport_error_indicator = b0
    709     // payload_unit_start_indicator = b1
    710     // transport_priority = b0
    711     // PID = b0000000000000 (13 bits)
    712     // transport_scrambling_control = b00
    713     // adaptation_field_control = b01 (no adaptation field, payload only)
    714     // continuity_counter = b????
    715     // skip = 0x00
    716     // --- payload follows
    717     // table_id = 0x00
    718     // section_syntax_indicator = b1
    719     // must_be_zero = b0
    720     // reserved = b11
    721     // section_length = 0x00d
    722     // transport_stream_id = 0x0000
    723     // reserved = b11
    724     // version_number = b00001
    725     // current_next_indicator = b1
    726     // section_number = 0x00
    727     // last_section_number = 0x00
    728     //   one program follows:
    729     //   program_number = 0x0001
    730     //   reserved = b111
    731     //   program_map_PID = 0x01e0 (13 bits!)
    732     // CRC = 0x????????
    733 
    734     static const uint8_t kData[] = {
    735         0x47,
    736         0x40, 0x00, 0x10, 0x00,  // b0100 0000 0000 0000 0001 ???? 0000 0000
    737         0x00, 0xb0, 0x0d, 0x00,  // b0000 0000 1011 0000 0000 1101 0000 0000
    738         0x00, 0xc3, 0x00, 0x00,  // b0000 0000 1100 0011 0000 0000 0000 0000
    739         0x00, 0x01, 0xe1, 0xe0,  // b0000 0000 0000 0001 1110 0001 1110 0000
    740         0x00, 0x00, 0x00, 0x00   // b???? ???? ???? ???? ???? ???? ???? ????
    741     };
    742 
    743     sp<ABuffer> buffer = new ABuffer(188);
    744     memset(buffer->data(), 0xff, buffer->size());
    745     memcpy(buffer->data(), kData, sizeof(kData));
    746 
    747     if (++mPATContinuityCounter == 16) {
    748         mPATContinuityCounter = 0;
    749     }
    750     buffer->data()[3] |= mPATContinuityCounter;
    751 
    752     uint32_t crc = htonl(crc32(&buffer->data()[5], 12));
    753     memcpy(&buffer->data()[17], &crc, sizeof(crc));
    754 
    755     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
    756 }
    757 
    758 void MPEG2TSWriter::writeProgramMap() {
    759     // 0x47
    760     // transport_error_indicator = b0
    761     // payload_unit_start_indicator = b1
    762     // transport_priority = b0
    763     // PID = b0 0001 1110 0000 (13 bits) [0x1e0]
    764     // transport_scrambling_control = b00
    765     // adaptation_field_control = b01 (no adaptation field, payload only)
    766     // continuity_counter = b????
    767     // skip = 0x00
    768     // -- payload follows
    769     // table_id = 0x02
    770     // section_syntax_indicator = b1
    771     // must_be_zero = b0
    772     // reserved = b11
    773     // section_length = 0x???
    774     // program_number = 0x0001
    775     // reserved = b11
    776     // version_number = b00001
    777     // current_next_indicator = b1
    778     // section_number = 0x00
    779     // last_section_number = 0x00
    780     // reserved = b111
    781     // PCR_PID = b? ???? ???? ???? (13 bits)
    782     // reserved = b1111
    783     // program_info_length = 0x000
    784     //   one or more elementary stream descriptions follow:
    785     //   stream_type = 0x??
    786     //   reserved = b111
    787     //   elementary_PID = b? ???? ???? ???? (13 bits)
    788     //   reserved = b1111
    789     //   ES_info_length = 0x000
    790     // CRC = 0x????????
    791 
    792     static const uint8_t kData[] = {
    793         0x47,
    794         0x41, 0xe0, 0x10, 0x00,  // b0100 0001 1110 0000 0001 ???? 0000 0000
    795         0x02, 0xb0, 0x00, 0x00,  // b0000 0010 1011 ???? ???? ???? 0000 0000
    796         0x01, 0xc3, 0x00, 0x00,  // b0000 0001 1100 0011 0000 0000 0000 0000
    797         0xe0, 0x00, 0xf0, 0x00   // b111? ???? ???? ???? 1111 0000 0000 0000
    798     };
    799 
    800     sp<ABuffer> buffer = new ABuffer(188);
    801     memset(buffer->data(), 0xff, buffer->size());
    802     memcpy(buffer->data(), kData, sizeof(kData));
    803 
    804     if (++mPMTContinuityCounter == 16) {
    805         mPMTContinuityCounter = 0;
    806     }
    807     buffer->data()[3] |= mPMTContinuityCounter;
    808 
    809     size_t section_length = 5 * mSources.size() + 4 + 9;
    810     buffer->data()[6] |= section_length >> 8;
    811     buffer->data()[7] = section_length & 0xff;
    812 
    813     static const unsigned kPCR_PID = 0x1e1;
    814     buffer->data()[13] |= (kPCR_PID >> 8) & 0x1f;
    815     buffer->data()[14] = kPCR_PID & 0xff;
    816 
    817     uint8_t *ptr = &buffer->data()[sizeof(kData)];
    818     for (size_t i = 0; i < mSources.size(); ++i) {
    819         *ptr++ = mSources.editItemAt(i)->streamType();
    820 
    821         const unsigned ES_PID = 0x1e0 + i + 1;
    822         *ptr++ = 0xe0 | (ES_PID >> 8);
    823         *ptr++ = ES_PID & 0xff;
    824         *ptr++ = 0xf0;
    825         *ptr++ = 0x00;
    826     }
    827 
    828     uint32_t crc = htonl(crc32(&buffer->data()[5], 12+mSources.size()*5));
    829     memcpy(&buffer->data()[17+mSources.size()*5], &crc, sizeof(crc));
    830 
    831     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
    832 }
    833 
    834 void MPEG2TSWriter::writeAccessUnit(
    835         int32_t sourceIndex, const sp<ABuffer> &accessUnit) {
    836     // 0x47
    837     // transport_error_indicator = b0
    838     // payload_unit_start_indicator = b1
    839     // transport_priority = b0
    840     // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
    841     // transport_scrambling_control = b00
    842     // adaptation_field_control = b??
    843     // continuity_counter = b????
    844     // -- payload follows
    845     // packet_startcode_prefix = 0x000001
    846     // stream_id = 0x?? (0xe0 for avc video, 0xc0 for aac audio)
    847     // PES_packet_length = 0x????
    848     // reserved = b10
    849     // PES_scrambling_control = b00
    850     // PES_priority = b0
    851     // data_alignment_indicator = b1
    852     // copyright = b0
    853     // original_or_copy = b0
    854     // PTS_DTS_flags = b10  (PTS only)
    855     // ESCR_flag = b0
    856     // ES_rate_flag = b0
    857     // DSM_trick_mode_flag = b0
    858     // additional_copy_info_flag = b0
    859     // PES_CRC_flag = b0
    860     // PES_extension_flag = b0
    861     // PES_header_data_length = 0x05
    862     // reserved = b0010 (PTS)
    863     // PTS[32..30] = b???
    864     // reserved = b1
    865     // PTS[29..15] = b??? ???? ???? ???? (15 bits)
    866     // reserved = b1
    867     // PTS[14..0] = b??? ???? ???? ???? (15 bits)
    868     // reserved = b1
    869     // the first fragment of "buffer" follows
    870 
    871     sp<ABuffer> buffer = new ABuffer(188);
    872     memset(buffer->data(), 0xff, buffer->size());
    873 
    874     const unsigned PID = 0x1e0 + sourceIndex + 1;
    875 
    876     const unsigned continuity_counter =
    877         mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
    878 
    879     // XXX if there are multiple streams of a kind (more than 1 audio or
    880     // more than 1 video) they need distinct stream_ids.
    881     const unsigned stream_id =
    882         mSources.editItemAt(sourceIndex)->streamType() == 0x0f ? 0xc0 : 0xe0;
    883 
    884     int64_t timeUs;
    885     CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
    886 
    887     uint32_t PTS = (timeUs * 9ll) / 100ll;
    888 
    889     size_t PES_packet_length = accessUnit->size() + 8;
    890     bool padding = (accessUnit->size() < (188 - 18));
    891 
    892     if (PES_packet_length >= 65536) {
    893         // This really should only happen for video.
    894         CHECK_EQ(stream_id, 0xe0u);
    895 
    896         // It's valid to set this to 0 for video according to the specs.
    897         PES_packet_length = 0;
    898     }
    899 
    900     uint8_t *ptr = buffer->data();
    901     *ptr++ = 0x47;
    902     *ptr++ = 0x40 | (PID >> 8);
    903     *ptr++ = PID & 0xff;
    904     *ptr++ = (padding ? 0x30 : 0x10) | continuity_counter;
    905     if (padding) {
    906         int paddingSize = 188 - accessUnit->size() - 18;
    907         *ptr++ = paddingSize - 1;
    908         if (paddingSize >= 2) {
    909             *ptr++ = 0x00;
    910             ptr += paddingSize - 2;
    911         }
    912     }
    913     *ptr++ = 0x00;
    914     *ptr++ = 0x00;
    915     *ptr++ = 0x01;
    916     *ptr++ = stream_id;
    917     *ptr++ = PES_packet_length >> 8;
    918     *ptr++ = PES_packet_length & 0xff;
    919     *ptr++ = 0x84;
    920     *ptr++ = 0x80;
    921     *ptr++ = 0x05;
    922     *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
    923     *ptr++ = (PTS >> 22) & 0xff;
    924     *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
    925     *ptr++ = (PTS >> 7) & 0xff;
    926     *ptr++ = ((PTS & 0x7f) << 1) | 1;
    927 
    928     size_t sizeLeft = buffer->data() + buffer->size() - ptr;
    929     size_t copy = accessUnit->size();
    930     if (copy > sizeLeft) {
    931         copy = sizeLeft;
    932     }
    933 
    934     memcpy(ptr, accessUnit->data(), copy);
    935 
    936     CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
    937 
    938     size_t offset = copy;
    939     while (offset < accessUnit->size()) {
    940         bool lastAccessUnit = ((accessUnit->size() - offset) < 184);
    941         // for subsequent fragments of "buffer":
    942         // 0x47
    943         // transport_error_indicator = b0
    944         // payload_unit_start_indicator = b0
    945         // transport_priority = b0
    946         // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
    947         // transport_scrambling_control = b00
    948         // adaptation_field_control = b??
    949         // continuity_counter = b????
    950         // the fragment of "buffer" follows.
    951 
    952         memset(buffer->data(), 0xff, buffer->size());
    953 
    954         const unsigned continuity_counter =
    955             mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
    956 
    957         ptr = buffer->data();
    958         *ptr++ = 0x47;
    959         *ptr++ = 0x00 | (PID >> 8);
    960         *ptr++ = PID & 0xff;
    961         *ptr++ = (lastAccessUnit ? 0x30 : 0x10) | continuity_counter;
    962 
    963         if (lastAccessUnit) {
    964             // Pad packet using an adaptation field
    965             // Adaptation header all to 0 execpt size
    966             uint8_t paddingSize = (uint8_t)184 - (accessUnit->size() - offset);
    967             *ptr++ = paddingSize - 1;
    968             if (paddingSize >= 2) {
    969                 *ptr++ = 0x00;
    970                 ptr += paddingSize - 2;
    971             }
    972         }
    973 
    974         size_t sizeLeft = buffer->data() + buffer->size() - ptr;
    975         size_t copy = accessUnit->size() - offset;
    976         if (copy > sizeLeft) {
    977             copy = sizeLeft;
    978         }
    979 
    980         memcpy(ptr, accessUnit->data() + offset, copy);
    981         CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
    982                  buffer->size());
    983 
    984         offset += copy;
    985     }
    986 }
    987 
    988 void MPEG2TSWriter::writeTS() {
    989     if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
    990         writeProgramAssociationTable();
    991         writeProgramMap();
    992 
    993         mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
    994     }
    995 }
    996 
    997 void MPEG2TSWriter::initCrcTable() {
    998     uint32_t poly = 0x04C11DB7;
    999 
   1000     for (int i = 0; i < 256; i++) {
   1001         uint32_t crc = i << 24;
   1002         for (int j = 0; j < 8; j++) {
   1003             crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
   1004         }
   1005         mCrcTable[i] = crc;
   1006     }
   1007 }
   1008 
   1009 /**
   1010  * Compute CRC32 checksum for buffer starting at offset start and for length
   1011  * bytes.
   1012  */
   1013 uint32_t MPEG2TSWriter::crc32(const uint8_t *p_start, size_t length) {
   1014     uint32_t crc = 0xFFFFFFFF;
   1015     const uint8_t *p;
   1016 
   1017     for (p = p_start; p < p_start + length; p++) {
   1018         crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
   1019     }
   1020 
   1021     return crc;
   1022 }
   1023 
   1024 ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
   1025     if (mFile != NULL) {
   1026         return fwrite(data, 1, size, mFile);
   1027     }
   1028 
   1029     return (*mWriteFunc)(mWriteCookie, data, size);
   1030 }
   1031 
   1032 }  // namespace android
   1033 
   1034