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