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
35namespace android {
36
37struct MPEG2TSWriter::SourceInfo : public AHandler {
38    SourceInfo(const sp<IMediaSource> &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
61protected:
62    virtual void onMessageReceived(const sp<AMessage> &msg);
63
64    virtual ~SourceInfo();
65
66private:
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> 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
96MPEG2TSWriter::SourceInfo::SourceInfo(const sp<IMediaSource> &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
117MPEG2TSWriter::SourceInfo::~SourceInfo() {
118}
119
120unsigned MPEG2TSWriter::SourceInfo::streamType() const {
121    return mStreamType;
122}
123
124unsigned MPEG2TSWriter::SourceInfo::incrementContinuityCounter() {
125    if (++mContinuityCounter == 16) {
126        mContinuityCounter = 0;
127    }
128
129    return mContinuityCounter;
130}
131
132void MPEG2TSWriter::SourceInfo::start(const sp<AMessage> &notify) {
133    mLooper->registerHandler(this);
134    mLooper->start();
135
136    mNotify = notify;
137
138    (new AMessage(kWhatStart, this))->post();
139}
140
141void MPEG2TSWriter::SourceInfo::stop() {
142    mLooper->unregisterHandler(id());
143    mLooper->stop();
144
145    mSource->stop();
146}
147
148void 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
253void 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
278bool 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
348bool 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
363void MPEG2TSWriter::SourceInfo::readMore() {
364    (new AMessage(kWhatRead, this))->post();
365}
366
367void 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
439sp<ABuffer> MPEG2TSWriter::SourceInfo::lastAccessUnit() {
440    return mLastAccessUnit;
441}
442
443void MPEG2TSWriter::SourceInfo::setLastAccessUnit(
444        const sp<ABuffer> &accessUnit) {
445    mLastAccessUnit = accessUnit;
446}
447
448int64_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
459void MPEG2TSWriter::SourceInfo::setEOSReceived() {
460    CHECK(!mEOSReceived);
461    mEOSReceived = true;
462}
463
464bool MPEG2TSWriter::SourceInfo::eosReceived() const {
465    return mEOSReceived;
466}
467
468////////////////////////////////////////////////////////////////////////////////
469
470MPEG2TSWriter::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
483MPEG2TSWriter::MPEG2TSWriter(
484        void *cookie,
485        ssize_t (*write)(void *cookie, const void *data, size_t size))
486    : mFile(NULL),
487      mWriteCookie(cookie),
488      mWriteFunc(write),
489      mStarted(false),
490      mNumSourcesDone(0),
491      mNumTSPacketsWritten(0),
492      mNumTSPacketsBeforeMeta(0),
493      mPATContinuityCounter(0),
494      mPMTContinuityCounter(0) {
495    init();
496}
497
498void MPEG2TSWriter::init() {
499    CHECK(mFile != NULL || mWriteFunc != NULL);
500
501    initCrcTable();
502
503    mLooper = new ALooper;
504    mLooper->setName("MPEG2TSWriter");
505
506    mReflector = new AHandlerReflector<MPEG2TSWriter>(this);
507
508    mLooper->registerHandler(mReflector);
509    mLooper->start();
510}
511
512MPEG2TSWriter::~MPEG2TSWriter() {
513    if (mStarted) {
514        reset();
515    }
516
517    mLooper->unregisterHandler(mReflector->id());
518    mLooper->stop();
519
520    if (mFile != NULL) {
521        fclose(mFile);
522        mFile = NULL;
523    }
524}
525
526status_t MPEG2TSWriter::addSource(const sp<IMediaSource> &source) {
527    CHECK(!mStarted);
528
529    sp<MetaData> meta = source->getFormat();
530    const char *mime;
531    CHECK(meta->findCString(kKeyMIMEType, &mime));
532
533    if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
534            && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
535        return ERROR_UNSUPPORTED;
536    }
537
538    sp<SourceInfo> info = new SourceInfo(source);
539
540    mSources.push(info);
541
542    return OK;
543}
544
545status_t MPEG2TSWriter::start(MetaData * /* param */) {
546    CHECK(!mStarted);
547
548    mStarted = true;
549    mNumSourcesDone = 0;
550    mNumTSPacketsWritten = 0;
551    mNumTSPacketsBeforeMeta = 0;
552
553    for (size_t i = 0; i < mSources.size(); ++i) {
554        sp<AMessage> notify =
555            new AMessage(kWhatSourceNotify, mReflector);
556
557        notify->setInt32("source-index", i);
558
559        mSources.editItemAt(i)->start(notify);
560    }
561
562    return OK;
563}
564
565status_t MPEG2TSWriter::reset() {
566    CHECK(mStarted);
567
568    for (size_t i = 0; i < mSources.size(); ++i) {
569        mSources.editItemAt(i)->stop();
570    }
571    mStarted = false;
572
573    return OK;
574}
575
576status_t MPEG2TSWriter::pause() {
577    CHECK(mStarted);
578
579    return OK;
580}
581
582bool MPEG2TSWriter::reachedEOS() {
583    return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
584}
585
586status_t MPEG2TSWriter::dump(
587        int /* fd */, const Vector<String16> & /* args */) {
588    return OK;
589}
590
591void MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
592    switch (msg->what()) {
593        case kWhatSourceNotify:
594        {
595            int32_t sourceIndex;
596            CHECK(msg->findInt32("source-index", &sourceIndex));
597
598            int32_t what;
599            CHECK(msg->findInt32("what", &what));
600
601            if (what == SourceInfo::kNotifyReachedEOS
602                    || what == SourceInfo::kNotifyStartFailed) {
603                sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
604                source->setEOSReceived();
605
606                sp<ABuffer> buffer = source->lastAccessUnit();
607                source->setLastAccessUnit(NULL);
608
609                if (buffer != NULL) {
610                    writeTS();
611                    writeAccessUnit(sourceIndex, buffer);
612                }
613
614                ++mNumSourcesDone;
615            } else if (what == SourceInfo::kNotifyBuffer) {
616                sp<ABuffer> buffer;
617                CHECK(msg->findBuffer("buffer", &buffer));
618
619                int32_t oob;
620                if (msg->findInt32("oob", &oob) && oob) {
621                    // This is codec specific data delivered out of band.
622                    // It can be written out immediately.
623                    writeTS();
624                    writeAccessUnit(sourceIndex, buffer);
625                    break;
626                }
627
628                // We don't just write out data as we receive it from
629                // the various sources. That would essentially write them
630                // out in random order (as the thread scheduler determines
631                // how the messages are dispatched).
632                // Instead we gather an access unit for all tracks and
633                // write out the one with the smallest timestamp, then
634                // request more data for the written out track.
635                // Rinse, repeat.
636                // If we don't have data on any track we don't write
637                // anything just yet.
638
639                sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
640
641                CHECK(source->lastAccessUnit() == NULL);
642                source->setLastAccessUnit(buffer);
643
644                ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
645                     sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
646
647                int64_t minTimeUs = -1;
648                size_t minIndex = 0;
649
650                for (size_t i = 0; i < mSources.size(); ++i) {
651                    const sp<SourceInfo> &source = mSources.editItemAt(i);
652
653                    if (source->eosReceived()) {
654                        continue;
655                    }
656
657                    int64_t timeUs = source->lastAccessUnitTimeUs();
658                    if (timeUs < 0) {
659                        minTimeUs = -1;
660                        break;
661                    } else if (minTimeUs < 0 || timeUs < minTimeUs) {
662                        minTimeUs = timeUs;
663                        minIndex = i;
664                    }
665                }
666
667                if (minTimeUs < 0) {
668                    ALOGV("not a all tracks have valid data.");
669                    break;
670                }
671
672                ALOGV("writing access unit at time %.2f secs (index %zu)",
673                     minTimeUs / 1E6, minIndex);
674
675                source = mSources.editItemAt(minIndex);
676
677                buffer = source->lastAccessUnit();
678                source->setLastAccessUnit(NULL);
679
680                writeTS();
681                writeAccessUnit(minIndex, buffer);
682
683                source->readMore();
684            }
685            break;
686        }
687
688        default:
689            TRESPASS();
690    }
691}
692
693void MPEG2TSWriter::writeProgramAssociationTable() {
694    // 0x47
695    // transport_error_indicator = b0
696    // payload_unit_start_indicator = b1
697    // transport_priority = b0
698    // PID = b0000000000000 (13 bits)
699    // transport_scrambling_control = b00
700    // adaptation_field_control = b01 (no adaptation field, payload only)
701    // continuity_counter = b????
702    // skip = 0x00
703    // --- payload follows
704    // table_id = 0x00
705    // section_syntax_indicator = b1
706    // must_be_zero = b0
707    // reserved = b11
708    // section_length = 0x00d
709    // transport_stream_id = 0x0000
710    // reserved = b11
711    // version_number = b00001
712    // current_next_indicator = b1
713    // section_number = 0x00
714    // last_section_number = 0x00
715    //   one program follows:
716    //   program_number = 0x0001
717    //   reserved = b111
718    //   program_map_PID = 0x01e0 (13 bits!)
719    // CRC = 0x????????
720
721    static const uint8_t kData[] = {
722        0x47,
723        0x40, 0x00, 0x10, 0x00,  // b0100 0000 0000 0000 0001 ???? 0000 0000
724        0x00, 0xb0, 0x0d, 0x00,  // b0000 0000 1011 0000 0000 1101 0000 0000
725        0x00, 0xc3, 0x00, 0x00,  // b0000 0000 1100 0011 0000 0000 0000 0000
726        0x00, 0x01, 0xe1, 0xe0,  // b0000 0000 0000 0001 1110 0001 1110 0000
727        0x00, 0x00, 0x00, 0x00   // b???? ???? ???? ???? ???? ???? ???? ????
728    };
729
730    sp<ABuffer> buffer = new ABuffer(188);
731    memset(buffer->data(), 0xff, buffer->size());
732    memcpy(buffer->data(), kData, sizeof(kData));
733
734    if (++mPATContinuityCounter == 16) {
735        mPATContinuityCounter = 0;
736    }
737    buffer->data()[3] |= mPATContinuityCounter;
738
739    uint32_t crc = htonl(crc32(&buffer->data()[5], 12));
740    memcpy(&buffer->data()[17], &crc, sizeof(crc));
741
742    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
743}
744
745void MPEG2TSWriter::writeProgramMap() {
746    // 0x47
747    // transport_error_indicator = b0
748    // payload_unit_start_indicator = b1
749    // transport_priority = b0
750    // PID = b0 0001 1110 0000 (13 bits) [0x1e0]
751    // transport_scrambling_control = b00
752    // adaptation_field_control = b01 (no adaptation field, payload only)
753    // continuity_counter = b????
754    // skip = 0x00
755    // -- payload follows
756    // table_id = 0x02
757    // section_syntax_indicator = b1
758    // must_be_zero = b0
759    // reserved = b11
760    // section_length = 0x???
761    // program_number = 0x0001
762    // reserved = b11
763    // version_number = b00001
764    // current_next_indicator = b1
765    // section_number = 0x00
766    // last_section_number = 0x00
767    // reserved = b111
768    // PCR_PID = b? ???? ???? ???? (13 bits)
769    // reserved = b1111
770    // program_info_length = 0x000
771    //   one or more elementary stream descriptions follow:
772    //   stream_type = 0x??
773    //   reserved = b111
774    //   elementary_PID = b? ???? ???? ???? (13 bits)
775    //   reserved = b1111
776    //   ES_info_length = 0x000
777    // CRC = 0x????????
778
779    static const uint8_t kData[] = {
780        0x47,
781        0x41, 0xe0, 0x10, 0x00,  // b0100 0001 1110 0000 0001 ???? 0000 0000
782        0x02, 0xb0, 0x00, 0x00,  // b0000 0010 1011 ???? ???? ???? 0000 0000
783        0x01, 0xc3, 0x00, 0x00,  // b0000 0001 1100 0011 0000 0000 0000 0000
784        0xe0, 0x00, 0xf0, 0x00   // b111? ???? ???? ???? 1111 0000 0000 0000
785    };
786
787    sp<ABuffer> buffer = new ABuffer(188);
788    memset(buffer->data(), 0xff, buffer->size());
789    memcpy(buffer->data(), kData, sizeof(kData));
790
791    if (++mPMTContinuityCounter == 16) {
792        mPMTContinuityCounter = 0;
793    }
794    buffer->data()[3] |= mPMTContinuityCounter;
795
796    size_t section_length = 5 * mSources.size() + 4 + 9;
797    buffer->data()[6] |= section_length >> 8;
798    buffer->data()[7] = section_length & 0xff;
799
800    static const unsigned kPCR_PID = 0x1e1;
801    buffer->data()[13] |= (kPCR_PID >> 8) & 0x1f;
802    buffer->data()[14] = kPCR_PID & 0xff;
803
804    uint8_t *ptr = &buffer->data()[sizeof(kData)];
805    for (size_t i = 0; i < mSources.size(); ++i) {
806        *ptr++ = mSources.editItemAt(i)->streamType();
807
808        const unsigned ES_PID = 0x1e0 + i + 1;
809        *ptr++ = 0xe0 | (ES_PID >> 8);
810        *ptr++ = ES_PID & 0xff;
811        *ptr++ = 0xf0;
812        *ptr++ = 0x00;
813    }
814
815    uint32_t crc = htonl(crc32(&buffer->data()[5], 12+mSources.size()*5));
816    memcpy(&buffer->data()[17+mSources.size()*5], &crc, sizeof(crc));
817
818    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
819}
820
821void MPEG2TSWriter::writeAccessUnit(
822        int32_t sourceIndex, const sp<ABuffer> &accessUnit) {
823    // 0x47
824    // transport_error_indicator = b0
825    // payload_unit_start_indicator = b1
826    // transport_priority = b0
827    // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
828    // transport_scrambling_control = b00
829    // adaptation_field_control = b??
830    // continuity_counter = b????
831    // -- payload follows
832    // packet_startcode_prefix = 0x000001
833    // stream_id = 0x?? (0xe0 for avc video, 0xc0 for aac audio)
834    // PES_packet_length = 0x????
835    // reserved = b10
836    // PES_scrambling_control = b00
837    // PES_priority = b0
838    // data_alignment_indicator = b1
839    // copyright = b0
840    // original_or_copy = b0
841    // PTS_DTS_flags = b10  (PTS only)
842    // ESCR_flag = b0
843    // ES_rate_flag = b0
844    // DSM_trick_mode_flag = b0
845    // additional_copy_info_flag = b0
846    // PES_CRC_flag = b0
847    // PES_extension_flag = b0
848    // PES_header_data_length = 0x05
849    // reserved = b0010 (PTS)
850    // PTS[32..30] = b???
851    // reserved = b1
852    // PTS[29..15] = b??? ???? ???? ???? (15 bits)
853    // reserved = b1
854    // PTS[14..0] = b??? ???? ???? ???? (15 bits)
855    // reserved = b1
856    // the first fragment of "buffer" follows
857
858    sp<ABuffer> buffer = new ABuffer(188);
859    memset(buffer->data(), 0xff, buffer->size());
860
861    const unsigned PID = 0x1e0 + sourceIndex + 1;
862
863    const unsigned continuity_counter =
864        mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
865
866    // XXX if there are multiple streams of a kind (more than 1 audio or
867    // more than 1 video) they need distinct stream_ids.
868    const unsigned stream_id =
869        mSources.editItemAt(sourceIndex)->streamType() == 0x0f ? 0xc0 : 0xe0;
870
871    int64_t timeUs;
872    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
873
874    uint32_t PTS = (timeUs * 9ll) / 100ll;
875
876    size_t PES_packet_length = accessUnit->size() + 8;
877    bool padding = (accessUnit->size() < (188 - 18));
878
879    if (PES_packet_length >= 65536) {
880        // This really should only happen for video.
881        CHECK_EQ(stream_id, 0xe0u);
882
883        // It's valid to set this to 0 for video according to the specs.
884        PES_packet_length = 0;
885    }
886
887    uint8_t *ptr = buffer->data();
888    *ptr++ = 0x47;
889    *ptr++ = 0x40 | (PID >> 8);
890    *ptr++ = PID & 0xff;
891    *ptr++ = (padding ? 0x30 : 0x10) | continuity_counter;
892    if (padding) {
893        int paddingSize = 188 - accessUnit->size() - 18;
894        *ptr++ = paddingSize - 1;
895        if (paddingSize >= 2) {
896            *ptr++ = 0x00;
897            ptr += paddingSize - 2;
898        }
899    }
900    *ptr++ = 0x00;
901    *ptr++ = 0x00;
902    *ptr++ = 0x01;
903    *ptr++ = stream_id;
904    *ptr++ = PES_packet_length >> 8;
905    *ptr++ = PES_packet_length & 0xff;
906    *ptr++ = 0x84;
907    *ptr++ = 0x80;
908    *ptr++ = 0x05;
909    *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
910    *ptr++ = (PTS >> 22) & 0xff;
911    *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
912    *ptr++ = (PTS >> 7) & 0xff;
913    *ptr++ = ((PTS & 0x7f) << 1) | 1;
914
915    size_t sizeLeft = buffer->data() + buffer->size() - ptr;
916    size_t copy = accessUnit->size();
917    if (copy > sizeLeft) {
918        copy = sizeLeft;
919    }
920
921    memcpy(ptr, accessUnit->data(), copy);
922
923    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
924
925    size_t offset = copy;
926    while (offset < accessUnit->size()) {
927        bool lastAccessUnit = ((accessUnit->size() - offset) < 184);
928        // for subsequent fragments of "buffer":
929        // 0x47
930        // transport_error_indicator = b0
931        // payload_unit_start_indicator = b0
932        // transport_priority = b0
933        // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
934        // transport_scrambling_control = b00
935        // adaptation_field_control = b??
936        // continuity_counter = b????
937        // the fragment of "buffer" follows.
938
939        memset(buffer->data(), 0xff, buffer->size());
940
941        const unsigned continuity_counter =
942            mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
943
944        ptr = buffer->data();
945        *ptr++ = 0x47;
946        *ptr++ = 0x00 | (PID >> 8);
947        *ptr++ = PID & 0xff;
948        *ptr++ = (lastAccessUnit ? 0x30 : 0x10) | continuity_counter;
949
950        if (lastAccessUnit) {
951            // Pad packet using an adaptation field
952            // Adaptation header all to 0 execpt size
953            uint8_t paddingSize = (uint8_t)184 - (accessUnit->size() - offset);
954            *ptr++ = paddingSize - 1;
955            if (paddingSize >= 2) {
956                *ptr++ = 0x00;
957                ptr += paddingSize - 2;
958            }
959        }
960
961        size_t sizeLeft = buffer->data() + buffer->size() - ptr;
962        size_t copy = accessUnit->size() - offset;
963        if (copy > sizeLeft) {
964            copy = sizeLeft;
965        }
966
967        memcpy(ptr, accessUnit->data() + offset, copy);
968        CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
969                 buffer->size());
970
971        offset += copy;
972    }
973}
974
975void MPEG2TSWriter::writeTS() {
976    if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
977        writeProgramAssociationTable();
978        writeProgramMap();
979
980        mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
981    }
982}
983
984void MPEG2TSWriter::initCrcTable() {
985    uint32_t poly = 0x04C11DB7;
986
987    for (int i = 0; i < 256; i++) {
988        uint32_t crc = i << 24;
989        for (int j = 0; j < 8; j++) {
990            crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
991        }
992        mCrcTable[i] = crc;
993    }
994}
995
996/**
997 * Compute CRC32 checksum for buffer starting at offset start and for length
998 * bytes.
999 */
1000uint32_t MPEG2TSWriter::crc32(const uint8_t *p_start, size_t length) {
1001    uint32_t crc = 0xFFFFFFFF;
1002    const uint8_t *p;
1003
1004    for (p = p_start; p < p_start + length; p++) {
1005        crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
1006    }
1007
1008    return crc;
1009}
1010
1011ssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
1012    if (mFile != NULL) {
1013        return fwrite(data, 1, size, mFile);
1014    }
1015
1016    return (*mWriteFunc)(mWriteCookie, data, size);
1017}
1018
1019}  // namespace android
1020
1021