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<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
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<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
96MPEG2TSWriter::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
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, id()))->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, id()))->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(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
496MPEG2TSWriter::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
511void 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
525MPEG2TSWriter::~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
539status_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
558status_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
578status_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
589status_t MPEG2TSWriter::pause() {
590    CHECK(mStarted);
591
592    return OK;
593}
594
595bool MPEG2TSWriter::reachedEOS() {
596    return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
597}
598
599status_t MPEG2TSWriter::dump(
600        int /* fd */, const Vector<String16> & /* args */) {
601    return OK;
602}
603
604void 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
706void 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
758void 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
834void 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
988void MPEG2TSWriter::writeTS() {
989    if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
990        writeProgramAssociationTable();
991        writeProgramMap();
992
993        mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
994    }
995}
996
997void 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 */
1013uint32_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
1024ssize_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