10da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber/*
20da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * Copyright (C) 2010 The Android Open Source Project
30da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *
40da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
50da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * you may not use this file except in compliance with the License.
60da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * You may obtain a copy of the License at
70da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *
80da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
90da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber *
100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * Unless required by applicable law or agreed to in writing, software
110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * See the License for the specific language governing permissions and
140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber * limitations under the License.
150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber */
160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber//#define LOG_NDEBUG 0
180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#define LOG_TAG "MPEG2TSWriter"
190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/foundation/ADebug.h>
200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/foundation/hexdump.h>
220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/foundation/AMessage.h>
240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MPEG2TSWriter.h>
250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MediaBuffer.h>
260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MediaDefs.h>
270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MediaErrors.h>
280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MediaSource.h>
290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/MetaData.h>
300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include <media/stagefright/Utils.h>
31983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello#include <arpa/inet.h>
320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber#include "include/ESDS.h"
340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubernamespace android {
360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstruct MPEG2TSWriter::SourceInfo : public AHandler {
380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    SourceInfo(const sp<MediaSource> &source);
390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    void start(const sp<AMessage> &notify);
410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    void stop();
420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned streamType() const;
440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned incrementContinuityCounter();
450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
463a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    void readMore();
473a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    enum {
490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        kNotifyStartFailed,
500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        kNotifyBuffer,
510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        kNotifyReachedEOS,
520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    };
530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
543a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    sp<ABuffer> lastAccessUnit();
553a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    int64_t lastAccessUnitTimeUs();
563a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    void setLastAccessUnit(const sp<ABuffer> &accessUnit);
573a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
583a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    void setEOSReceived();
593a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    bool eosReceived() const;
603a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberprotected:
620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    virtual ~SourceInfo();
650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberprivate:
670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    enum {
680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        kWhatStart = 'strt',
690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        kWhatRead  = 'read',
700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    };
710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<MediaSource> mSource;
730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ALooper> mLooper;
740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<AMessage> mNotify;
750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    sp<ABuffer> mAACCodecSpecificData;
7759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ABuffer> mAACBuffer;
790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
803a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    sp<ABuffer> mLastAccessUnit;
813a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    bool mEOSReceived;
823a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned mStreamType;
840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned mContinuityCounter;
850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    void extractCodecSpecificData();
870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
883a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    bool appendAACFrames(MediaBuffer *buffer);
893a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    bool flushAACFrames();
900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    void postAVCFrame(MediaBuffer *buffer);
920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(SourceInfo);
940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber};
950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas HuberMPEG2TSWriter::SourceInfo::SourceInfo(const sp<MediaSource> &source)
970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    : mSource(source),
980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mLooper(new ALooper),
993a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber      mEOSReceived(false),
1000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mStreamType(0),
1010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mContinuityCounter(0) {
1020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->setName("MPEG2TSWriter source");
1030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<MetaData> meta = mSource->getFormat();
1050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const char *mime;
1060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mStreamType = 0x0f;
1100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mStreamType = 0x1b;
1120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    } else {
1130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        TRESPASS();
1140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
1150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas HuberMPEG2TSWriter::SourceInfo::~SourceInfo() {
1180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberunsigned MPEG2TSWriter::SourceInfo::streamType() const {
1210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return mStreamType;
1220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberunsigned MPEG2TSWriter::SourceInfo::incrementContinuityCounter() {
1250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (++mContinuityCounter == 16) {
1260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mContinuityCounter = 0;
1270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
1280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return mContinuityCounter;
1300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::SourceInfo::start(const sp<AMessage> &notify) {
1330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->registerHandler(this);
1340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->start();
1350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mNotify = notify;
1370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    (new AMessage(kWhatStart, id()))->post();
1390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::SourceInfo::stop() {
1420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->unregisterHandler(id());
1430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->stop();
14459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
14559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    mSource->stop();
1460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
1470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::SourceInfo::extractCodecSpecificData() {
1490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<MetaData> meta = mSource->getFormat();
1500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const char *mime;
1520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
1530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
15459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
15559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        uint32_t type;
15659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        const void *data;
15759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        size_t size;
15859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        if (!meta->findData(kKeyESDS, &type, &data, &size)) {
15959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            // Codec specific data better be in the first data buffer.
16059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber            return;
16159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        }
16259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
16359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        ESDS esds((const char *)data, size);
16459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        CHECK_EQ(esds.InitCheck(), (status_t)OK);
16559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
16659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        const uint8_t *codec_specific_data;
16759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        size_t codec_specific_data_size;
16859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        esds.getCodecSpecificInfo(
16959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                (const void **)&codec_specific_data, &codec_specific_data_size);
17059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
17159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        CHECK_GE(codec_specific_data_size, 2u);
17259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
17359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        mAACCodecSpecificData = new ABuffer(codec_specific_data_size);
17459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
17559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        memcpy(mAACCodecSpecificData->data(), codec_specific_data,
17659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber               codec_specific_data_size);
17759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
1780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        return;
1790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
1800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
18159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
18259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        return;
18359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
1840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    uint32_t type;
1860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const void *data;
1870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t size;
18859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (!meta->findData(kKeyAVCC, &type, &data, &size)) {
18959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        // Codec specific data better be part of the data stream then.
19059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber        return;
19159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
19259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
19359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    sp<ABuffer> out = new ABuffer(1024);
19459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    out->setRange(0, 0);
1950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const uint8_t *ptr = (const uint8_t *)data;
1970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t numSeqParameterSets = ptr[5] & 31;
1990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    ptr += 6;
2010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size -= 6;
2020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (size_t i = 0; i < numSeqParameterSets; ++i) {
2040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK(size >= 2);
2050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size_t length = U16_AT(ptr);
2060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ptr += 2;
2080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size -= 2;
2090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK(size >= length);
2110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK_LE(out->size() + 4 + length, out->capacity());
2130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
2140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        memcpy(out->data() + out->size() + 4, ptr, length);
2150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        out->setRange(0, out->size() + length + 4);
2160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ptr += length;
2180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size -= length;
2190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
2200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(size >= 1);
2220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t numPictureParameterSets = *ptr;
2230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    ++ptr;
2240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    --size;
2250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (size_t i = 0; i < numPictureParameterSets; ++i) {
2270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK(size >= 2);
2280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size_t length = U16_AT(ptr);
2290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ptr += 2;
2310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size -= 2;
2320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK(size >= length);
2340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK_LE(out->size() + 4 + length, out->capacity());
2360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        memcpy(out->data() + out->size(), "\x00\x00\x00\x01", 4);
2370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        memcpy(out->data() + out->size() + 4, ptr, length);
2380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        out->setRange(0, out->size() + length + 4);
2390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ptr += length;
2410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size -= length;
2420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
2430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    out->meta()->setInt64("timeUs", 0ll);
2450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<AMessage> notify = mNotify->dup();
2470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->setInt32("what", kNotifyBuffer);
2482d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", out);
2493a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    notify->setInt32("oob", true);
2500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->post();
2510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
2520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::SourceInfo::postAVCFrame(MediaBuffer *buffer) {
2540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<AMessage> notify = mNotify->dup();
2550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->setInt32("what", kNotifyBuffer);
2560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ABuffer> copy =
2580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        new ABuffer(buffer->range_length());
2590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    memcpy(copy->data(),
2600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber           (const uint8_t *)buffer->data()
2610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            + buffer->range_offset(),
2620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber           buffer->range_length());
2630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    int64_t timeUs;
2650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
2660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    copy->meta()->setInt64("timeUs", timeUs);
2670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    int32_t isSync;
2690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (buffer->meta_data()->findInt32(kKeyIsSyncFrame, &isSync)
2700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            && isSync != 0) {
2710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        copy->meta()->setInt32("isSync", true);
2720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
2730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2742d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", copy);
2750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->post();
2760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
2770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2783a1775247e26f274ef249442ef038ddf7217b68cAndreas Huberbool MPEG2TSWriter::SourceInfo::appendAACFrames(MediaBuffer *buffer) {
2793a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    bool accessUnitPosted = false;
2803a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
2810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (mAACBuffer != NULL
2820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            && mAACBuffer->size() + 7 + buffer->range_length()
2830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    > mAACBuffer->capacity()) {
2843a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber        accessUnitPosted = flushAACFrames();
2850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
2860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (mAACBuffer == NULL) {
2880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size_t alloc = 4096;
2890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (buffer->range_length() + 7 > alloc) {
2900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            alloc = 7 + buffer->range_length();
2910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
2920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mAACBuffer = new ABuffer(alloc);
2940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        int64_t timeUs;
2960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
2970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
2980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mAACBuffer->meta()->setInt64("timeUs", timeUs);
2990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mAACBuffer->meta()->setInt32("isSync", true);
3000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mAACBuffer->setRange(0, 0);
3020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
3030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
30459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    const uint8_t *codec_specific_data = mAACCodecSpecificData->data();
3050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned profile = (codec_specific_data[0] >> 3) - 1;
3070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned sampling_freq_index =
3090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ((codec_specific_data[0] & 7) << 1)
3100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        | (codec_specific_data[1] >> 7);
3110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    unsigned channel_configuration =
3130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        (codec_specific_data[1] >> 3) & 0x0f;
3140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    uint8_t *ptr = mAACBuffer->data() + mAACBuffer->size();
3160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const uint32_t aac_frame_length = buffer->range_length() + 7;
3180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0xff;
3200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0xf1;  // b11110001, ID=0, layer=0, protection_absent=1
3210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ =
3230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        profile << 6
3240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        | sampling_freq_index << 2
3250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        | ((channel_configuration >> 2) & 1);  // private_bit=0
3260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0
3280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ =
3290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        (channel_configuration & 3) << 6
3300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        | aac_frame_length >> 11;
3310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = (aac_frame_length >> 3) & 0xff;
3320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = (aac_frame_length & 7) << 5;
3330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0
3350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0;
3360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    memcpy(ptr,
3380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber           (const uint8_t *)buffer->data() + buffer->range_offset(),
3390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber           buffer->range_length());
3400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    ptr += buffer->range_length();
3420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mAACBuffer->setRange(0, ptr - mAACBuffer->data());
3443a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
3453a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    return accessUnitPosted;
3460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
3470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3483a1775247e26f274ef249442ef038ddf7217b68cAndreas Huberbool MPEG2TSWriter::SourceInfo::flushAACFrames() {
3490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (mAACBuffer == NULL) {
3503a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber        return false;
3510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
3520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<AMessage> notify = mNotify->dup();
3540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->setInt32("what", kNotifyBuffer);
3552d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", mAACBuffer);
3560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    notify->post();
3570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mAACBuffer.clear();
3593a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
3603a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    return true;
3613a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
3623a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
3633a1775247e26f274ef249442ef038ddf7217b68cAndreas Hubervoid MPEG2TSWriter::SourceInfo::readMore() {
3643a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    (new AMessage(kWhatRead, id()))->post();
3650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
3660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::SourceInfo::onMessageReceived(const sp<AMessage> &msg) {
3680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    switch (msg->what()) {
3690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        case kWhatStart:
3700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        {
3710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            status_t err = mSource->start();
3720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (err != OK) {
3730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                sp<AMessage> notify = mNotify->dup();
3740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                notify->setInt32("what", kNotifyStartFailed);
3750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                notify->post();
3760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                break;
3770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
3780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            extractCodecSpecificData();
3800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3813a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber            readMore();
3820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            break;
3830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
3840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        case kWhatRead:
3860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        {
3870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            MediaBuffer *buffer;
3880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            status_t err = mSource->read(&buffer);
3890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (err != OK && err != INFO_FORMAT_CHANGED) {
3910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                if (mStreamType == 0x0f) {
3920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    flushAACFrames();
3930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                }
3940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
3950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                sp<AMessage> notify = mNotify->dup();
3960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                notify->setInt32("what", kNotifyReachedEOS);
3970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                notify->setInt32("status", err);
3980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                notify->post();
3990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                break;
4000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
4010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
4020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (err == OK) {
40359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                if (mStreamType == 0x0f && mAACCodecSpecificData == NULL) {
40459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                    // The first buffer contains codec specific data.
40559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
40659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                    CHECK_GE(buffer->range_length(), 2u);
40759b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
40859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                    mAACCodecSpecificData = new ABuffer(buffer->range_length());
40959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
41059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                    memcpy(mAACCodecSpecificData->data(),
41159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                           (const uint8_t *)buffer->data()
41259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                            + buffer->range_offset(),
41359b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                           buffer->range_length());
41459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber                } else if (buffer->range_length() > 0) {
4150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    if (mStreamType == 0x0f) {
4163a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        if (!appendAACFrames(buffer)) {
4173a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                            msg->post();
4183a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        }
4190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    } else {
4200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                        postAVCFrame(buffer);
4210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    }
42202d18453d54a05c275c03b72a8290f3c9a964446Martin Storsjo                } else {
42302d18453d54a05c275c03b72a8290f3c9a964446Martin Storsjo                    readMore();
4240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                }
4250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
4260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                buffer->release();
4270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                buffer = NULL;
4280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
4290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
4303a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber            // Do not read more data until told to.
4310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            break;
4320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
4330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
4340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        default:
4350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            TRESPASS();
4360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
4370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
4380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
4393a1775247e26f274ef249442ef038ddf7217b68cAndreas Hubersp<ABuffer> MPEG2TSWriter::SourceInfo::lastAccessUnit() {
4403a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    return mLastAccessUnit;
4413a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
4423a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4433a1775247e26f274ef249442ef038ddf7217b68cAndreas Hubervoid MPEG2TSWriter::SourceInfo::setLastAccessUnit(
4443a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber        const sp<ABuffer> &accessUnit) {
4453a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    mLastAccessUnit = accessUnit;
4463a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
4473a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4483a1775247e26f274ef249442ef038ddf7217b68cAndreas Huberint64_t MPEG2TSWriter::SourceInfo::lastAccessUnitTimeUs() {
4493a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    if (mLastAccessUnit == NULL) {
4503a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber        return -1;
4513a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    }
4523a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4533a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    int64_t timeUs;
4543a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    CHECK(mLastAccessUnit->meta()->findInt64("timeUs", &timeUs));
4553a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4563a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    return timeUs;
4573a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
4583a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4593a1775247e26f274ef249442ef038ddf7217b68cAndreas Hubervoid MPEG2TSWriter::SourceInfo::setEOSReceived() {
4603a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    CHECK(!mEOSReceived);
4613a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    mEOSReceived = true;
4623a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
4633a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4643a1775247e26f274ef249442ef038ddf7217b68cAndreas Huberbool MPEG2TSWriter::SourceInfo::eosReceived() const {
4653a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber    return mEOSReceived;
4663a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber}
4673a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
4680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber////////////////////////////////////////////////////////////////////////////////
4690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
47059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas HuberMPEG2TSWriter::MPEG2TSWriter(int fd)
471674ebd0b4e1143e38392a4e3bb38b4679a4577bcJames Dong    : mFile(fdopen(dup(fd), "wb")),
4723e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteCookie(NULL),
4733e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteFunc(NULL),
47459b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber      mStarted(false),
47559b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber      mNumSourcesDone(0),
47659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber      mNumTSPacketsWritten(0),
477d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mNumTSPacketsBeforeMeta(0),
478d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPATContinuityCounter(0),
479d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPMTContinuityCounter(0) {
48059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    init();
48159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber}
48259b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
4830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas HuberMPEG2TSWriter::MPEG2TSWriter(const char *filename)
4840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    : mFile(fopen(filename, "wb")),
4853e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteCookie(NULL),
4863e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteFunc(NULL),
4873e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mStarted(false),
4883e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mNumSourcesDone(0),
4893e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mNumTSPacketsWritten(0),
490d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mNumTSPacketsBeforeMeta(0),
491d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPATContinuityCounter(0),
492d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPMTContinuityCounter(0) {
4933e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    init();
4943e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber}
4953e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber
4963e1763ecdf14769a534f75e94a56785f63174b47Andreas HuberMPEG2TSWriter::MPEG2TSWriter(
4973e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        void *cookie,
4983e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        ssize_t (*write)(void *cookie, const void *data, size_t size))
4993e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    : mFile(NULL),
5003e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteCookie(cookie),
5013e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber      mWriteFunc(write),
5020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mStarted(false),
5030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mNumSourcesDone(0),
5040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber      mNumTSPacketsWritten(0),
505d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mNumTSPacketsBeforeMeta(0),
506d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPATContinuityCounter(0),
507d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello      mPMTContinuityCounter(0) {
50859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    init();
50959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber}
51059b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
51159b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Hubervoid MPEG2TSWriter::init() {
5123e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    CHECK(mFile != NULL || mWriteFunc != NULL);
5130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
514983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    initCrcTable();
515983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
5160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper = new ALooper;
5170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->setName("MPEG2TSWriter");
5180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mReflector = new AHandlerReflector<MPEG2TSWriter>(this);
5200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->registerHandler(mReflector);
5220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->start();
5230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas HuberMPEG2TSWriter::~MPEG2TSWriter() {
52659b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    if (mStarted) {
5278bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dong        reset();
52859b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber    }
52959b7dc39ea8332d3418a599e51447d7edb612ac4Andreas Huber
5300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->unregisterHandler(mReflector->id());
5310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mLooper->stop();
5320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5333e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    if (mFile != NULL) {
5343e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        fclose(mFile);
5353e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        mFile = NULL;
5363e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    }
5370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatus_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
5400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(!mStarted);
5410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<MetaData> meta = source->getFormat();
5430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const char *mime;
5440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(meta->findCString(kKeyMIMEType, &mime));
5450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
5470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
5480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        return ERROR_UNSUPPORTED;
5490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
5500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<SourceInfo> info = new SourceInfo(source);
5520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mSources.push(info);
5540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return OK;
5560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatus_t MPEG2TSWriter::start(MetaData *param) {
5590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(!mStarted);
5600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mStarted = true;
5620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mNumSourcesDone = 0;
5630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mNumTSPacketsWritten = 0;
5640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mNumTSPacketsBeforeMeta = 0;
5650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (size_t i = 0; i < mSources.size(); ++i) {
5670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        sp<AMessage> notify =
5680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            new AMessage(kWhatSourceNotify, mReflector->id());
5690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        notify->setInt32("source-index", i);
5710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mSources.editItemAt(i)->start(notify);
5730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
5740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return OK;
5760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5788bcc65c753085fe3328592cceda0cf0e8f8b0a45James Dongstatus_t MPEG2TSWriter::reset() {
5790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(mStarted);
5800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (size_t i = 0; i < mSources.size(); ++i) {
5820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mSources.editItemAt(i)->stop();
5830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
5840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    mStarted = false;
5850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return OK;
5870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatus_t MPEG2TSWriter::pause() {
5900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(mStarted);
5910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return OK;
5930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberbool MPEG2TSWriter::reachedEOS() {
5960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
5970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
5980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
5990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huberstatus_t MPEG2TSWriter::dump(int fd, const Vector<String16> &args) {
6000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    return OK;
6010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
6020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
6030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::onMessageReceived(const sp<AMessage> &msg) {
6040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    switch (msg->what()) {
6050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        case kWhatSourceNotify:
6060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        {
6070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            int32_t sourceIndex;
6080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            CHECK(msg->findInt32("source-index", &sourceIndex));
6090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
6100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            int32_t what;
6110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            CHECK(msg->findInt32("what", &what));
6120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
6130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            if (what == SourceInfo::kNotifyReachedEOS
6140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                    || what == SourceInfo::kNotifyStartFailed) {
6153a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
6163a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source->setEOSReceived();
6173a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6183a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                sp<ABuffer> buffer = source->lastAccessUnit();
6193a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source->setLastAccessUnit(NULL);
6203a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6213a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                if (buffer != NULL) {
6223a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    writeTS();
6233a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    writeAccessUnit(sourceIndex, buffer);
6243a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                }
6253a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                ++mNumSourcesDone;
6270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            } else if (what == SourceInfo::kNotifyBuffer) {
6282d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                sp<ABuffer> buffer;
6292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                CHECK(msg->findBuffer("buffer", &buffer));
6303a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6313a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                int32_t oob;
6323a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                if (msg->findInt32("oob", &oob) && oob) {
6333a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    // This is codec specific data delivered out of band.
6343a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    // It can be written out immediately.
6353a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    writeTS();
6363a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    writeAccessUnit(sourceIndex, buffer);
6373a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    break;
6383a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                }
6393a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6403a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // We don't just write out data as we receive it from
6413a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // the various sources. That would essentially write them
6423a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // out in random order (as the thread scheduler determines
6433a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // how the messages are dispatched).
6443a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // Instead we gather an access unit for all tracks and
6453a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // write out the one with the smallest timestamp, then
6463a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // request more data for the written out track.
6473a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // Rinse, repeat.
6483a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // If we don't have data on any track we don't write
6493a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                // anything just yet.
6503a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6513a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                sp<SourceInfo> source = mSources.editItemAt(sourceIndex);
6523a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6533a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                CHECK(source->lastAccessUnit() == NULL);
6543a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source->setLastAccessUnit(buffer);
6553a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("lastAccessUnitTimeUs[%d] = %.2f secs",
6573a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                     sourceIndex, source->lastAccessUnitTimeUs() / 1E6);
6583a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6593a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                int64_t minTimeUs = -1;
6603a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                size_t minIndex = 0;
6613a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6623a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                for (size_t i = 0; i < mSources.size(); ++i) {
6633a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    const sp<SourceInfo> &source = mSources.editItemAt(i);
6643a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6653a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    if (source->eosReceived()) {
6663a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        continue;
6673a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    }
6683a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6693a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    int64_t timeUs = source->lastAccessUnitTimeUs();
6703a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    if (timeUs < 0) {
6713a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        minTimeUs = -1;
6723a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        break;
6733a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    } else if (minTimeUs < 0 || timeUs < minTimeUs) {
6743a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        minTimeUs = timeUs;
6753a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                        minIndex = i;
6763a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    }
6773a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                }
6783a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6793a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                if (minTimeUs < 0) {
6803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("not a all tracks have valid data.");
6813a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                    break;
6823a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                }
6833a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("writing access unit at time %.2f secs (index %d)",
6853a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                     minTimeUs / 1E6, minIndex);
6863a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6873a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source = mSources.editItemAt(minIndex);
6883a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6893a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                buffer = source->lastAccessUnit();
6903a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source->setLastAccessUnit(NULL);
6913a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber
6920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                writeTS();
6933a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                writeAccessUnit(minIndex, buffer);
6940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
6953a1775247e26f274ef249442ef038ddf7217b68cAndreas Huber                source->readMore();
6960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            }
6970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            break;
6980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
6990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        default:
7010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            TRESPASS();
7020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
7030da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
7040da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7050da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::writeProgramAssociationTable() {
7060da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // 0x47
7070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_error_indicator = b0
7080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // payload_unit_start_indicator = b1
7090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_priority = b0
7100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PID = b0000000000000 (13 bits)
7110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_scrambling_control = b00
7120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // adaptation_field_control = b01 (no adaptation field, payload only)
7130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // continuity_counter = b????
7140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // skip = 0x00
7150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // --- payload follows
7160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // table_id = 0x00
7170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_syntax_indicator = b1
7180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // must_be_zero = b0
7190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b11
7200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_length = 0x00d
7210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_stream_id = 0x0000
7220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b11
7230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // version_number = b00001
7240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // current_next_indicator = b1
7250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_number = 0x00
7260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // last_section_number = 0x00
7270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   one program follows:
7280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   program_number = 0x0001
7290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   reserved = b111
7300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   program_map_PID = 0x01e0 (13 bits!)
7310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // CRC = 0x????????
7320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    static const uint8_t kData[] = {
7340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x47,
7350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x40, 0x00, 0x10, 0x00,  // b0100 0000 0000 0000 0001 ???? 0000 0000
7360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x00, 0xb0, 0x0d, 0x00,  // b0000 0000 1011 0000 0000 1101 0000 0000
7370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x00, 0xc3, 0x00, 0x00,  // b0000 0000 1100 0011 0000 0000 0000 0000
7380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x00, 0x01, 0xe1, 0xe0,  // b0000 0000 0000 0001 1110 0001 1110 0000
7390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x00, 0x00, 0x00, 0x00   // b???? ???? ???? ???? ???? ???? ???? ????
7400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    };
7410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ABuffer> buffer = new ABuffer(188);
743983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    memset(buffer->data(), 0xff, buffer->size());
7440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    memcpy(buffer->data(), kData, sizeof(kData));
7450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
746d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    if (++mPATContinuityCounter == 16) {
747d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello        mPATContinuityCounter = 0;
748d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    }
749d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    buffer->data()[3] |= mPATContinuityCounter;
7500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
751983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    uint32_t crc = htonl(crc32(&buffer->data()[5], 12));
752983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    memcpy(&buffer->data()[17], &crc, sizeof(crc));
753983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
7543e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
7550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
7560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::writeProgramMap() {
7580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // 0x47
7590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_error_indicator = b0
7600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // payload_unit_start_indicator = b1
7610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_priority = b0
7620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PID = b0 0001 1110 0000 (13 bits) [0x1e0]
7630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_scrambling_control = b00
7640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // adaptation_field_control = b01 (no adaptation field, payload only)
7650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // continuity_counter = b????
7660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // skip = 0x00
7670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // -- payload follows
7680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // table_id = 0x02
7690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_syntax_indicator = b1
7700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // must_be_zero = b0
7710da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b11
7720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_length = 0x???
7730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // program_number = 0x0001
7740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b11
7750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // version_number = b00001
7760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // current_next_indicator = b1
7770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // section_number = 0x00
7780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // last_section_number = 0x00
7790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b111
7800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PCR_PID = b? ???? ???? ???? (13 bits)
7810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b1111
7820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // program_info_length = 0x000
7830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   one or more elementary stream descriptions follow:
7840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   stream_type = 0x??
7850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   reserved = b111
7860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   elementary_PID = b? ???? ???? ???? (13 bits)
7870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   reserved = b1111
7880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    //   ES_info_length = 0x000
7890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // CRC = 0x????????
7900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    static const uint8_t kData[] = {
7920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x47,
7930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x41, 0xe0, 0x10, 0x00,  // b0100 0001 1110 0000 0001 ???? 0000 0000
7940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x02, 0xb0, 0x00, 0x00,  // b0000 0010 1011 ???? ???? ???? 0000 0000
7950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0x01, 0xc3, 0x00, 0x00,  // b0000 0001 1100 0011 0000 0000 0000 0000
7960da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        0xe0, 0x00, 0xf0, 0x00   // b111? ???? ???? ???? 1111 0000 0000 0000
7970da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    };
7980da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
7990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ABuffer> buffer = new ABuffer(188);
800983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    memset(buffer->data(), 0xff, buffer->size());
8010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    memcpy(buffer->data(), kData, sizeof(kData));
8020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
803d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    if (++mPMTContinuityCounter == 16) {
804d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello        mPMTContinuityCounter = 0;
805d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    }
806d4e5af6bc0a012e8d43975ca8b5627631333920dPaul Fariello    buffer->data()[3] |= mPMTContinuityCounter;
8070da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8080da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t section_length = 5 * mSources.size() + 4 + 9;
8090da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    buffer->data()[6] |= section_length >> 8;
8100da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    buffer->data()[7] = section_length & 0xff;
8110da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    static const unsigned kPCR_PID = 0x1e1;
8130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    buffer->data()[13] |= (kPCR_PID >> 8) & 0x1f;
8140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    buffer->data()[14] = kPCR_PID & 0xff;
8150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    uint8_t *ptr = &buffer->data()[sizeof(kData)];
8170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    for (size_t i = 0; i < mSources.size(); ++i) {
8180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = mSources.editItemAt(i)->streamType();
8190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        const unsigned ES_PID = 0x1e0 + i + 1;
8210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = 0xe0 | (ES_PID >> 8);
8220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = ES_PID & 0xff;
8230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = 0xf0;
8240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = 0x00;
8250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
8260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
827983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    uint32_t crc = htonl(crc32(&buffer->data()[5], 12+mSources.size()*5));
828983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    memcpy(&buffer->data()[17+mSources.size()*5], &crc, sizeof(crc));
8290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8303e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
8310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
8320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::writeAccessUnit(
8340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        int32_t sourceIndex, const sp<ABuffer> &accessUnit) {
8350da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // 0x47
8360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_error_indicator = b0
8370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // payload_unit_start_indicator = b1
8380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_priority = b0
8390da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
8400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // transport_scrambling_control = b00
84199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    // adaptation_field_control = b??
8420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // continuity_counter = b????
8430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // -- payload follows
8440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // packet_startcode_prefix = 0x000001
8450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // stream_id = 0x?? (0xe0 for avc video, 0xc0 for aac audio)
8460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_packet_length = 0x????
8470da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b10
8480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_scrambling_control = b00
8490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_priority = b0
8500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // data_alignment_indicator = b1
8510da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // copyright = b0
8520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // original_or_copy = b0
8530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PTS_DTS_flags = b10  (PTS only)
8540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // ESCR_flag = b0
8550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // ES_rate_flag = b0
8560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // DSM_trick_mode_flag = b0
8570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // additional_copy_info_flag = b0
8580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_CRC_flag = b0
8590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_extension_flag = b0
8600da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PES_header_data_length = 0x05
8610da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b0010 (PTS)
8620da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PTS[32..30] = b???
8630da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b1
8640da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PTS[29..15] = b??? ???? ???? ???? (15 bits)
8650da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b1
8660da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // PTS[14..0] = b??? ???? ???? ???? (15 bits)
8670da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // reserved = b1
8680da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // the first fragment of "buffer" follows
8690da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8700da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    sp<ABuffer> buffer = new ABuffer(188);
87199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    memset(buffer->data(), 0xff, buffer->size());
8720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const unsigned PID = 0x1e0 + sourceIndex + 1;
8740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const unsigned continuity_counter =
8760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
8770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // XXX if there are multiple streams of a kind (more than 1 audio or
8790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    // more than 1 video) they need distinct stream_ids.
8800da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    const unsigned stream_id =
8810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mSources.editItemAt(sourceIndex)->streamType() == 0x0f ? 0xc0 : 0xe0;
8820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    int64_t timeUs;
8840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
8850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    uint32_t PTS = (timeUs * 9ll) / 100ll;
8870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
8880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t PES_packet_length = accessUnit->size() + 8;
88999b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    bool padding = (accessUnit->size() < (188 - 18));
8900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
891acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber    if (PES_packet_length >= 65536) {
892acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber        // This really should only happen for video.
893acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber        CHECK_EQ(stream_id, 0xe0u);
894acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber
895acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber        // It's valid to set this to 0 for video according to the specs.
896acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber        PES_packet_length = 0;
897acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber    }
898acc82a3bad22af17008a839d993e3bd7a5d9b5afAndreas Huber
8990da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    uint8_t *ptr = buffer->data();
9000da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x47;
9010da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x40 | (PID >> 8);
9020da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = PID & 0xff;
90399b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    *ptr++ = (padding ? 0x30 : 0x10) | continuity_counter;
90499b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    if (padding) {
90599b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        int paddingSize = 188 - accessUnit->size() - 18;
90699b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        *ptr++ = paddingSize - 1;
90799b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        if (paddingSize >= 2) {
90899b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            *ptr++ = 0x00;
90999b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            ptr += paddingSize - 2;
91099b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        }
91199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello    }
9120da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x00;
9130da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x00;
9140da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x01;
9150da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = stream_id;
9160da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = PES_packet_length >> 8;
9170da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = PES_packet_length & 0xff;
9180da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x84;
9190da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x80;
9200da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x05;
9210da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1;
9220da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = (PTS >> 22) & 0xff;
9230da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1;
9240da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = (PTS >> 7) & 0xff;
9250da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    *ptr++ = ((PTS & 0x7f) << 1) | 1;
9260da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9270da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t sizeLeft = buffer->data() + buffer->size() - ptr;
9280da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t copy = accessUnit->size();
9290da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (copy > sizeLeft) {
9300da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        copy = sizeLeft;
9310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
9320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9330da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    memcpy(ptr, accessUnit->data(), copy);
9340da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9353e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    CHECK_EQ(internalWrite(buffer->data(), buffer->size()), buffer->size());
9360da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9370da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    size_t offset = copy;
9380da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    while (offset < accessUnit->size()) {
939c867a50ec5317e74602798e2e8435cde313b91e9Martin Storsjo        bool lastAccessUnit = ((accessUnit->size() - offset) < 184);
9400da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // for subsequent fragments of "buffer":
9410da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // 0x47
9420da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // transport_error_indicator = b0
9430da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // payload_unit_start_indicator = b0
9440da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // transport_priority = b0
9450da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex]
9460da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // transport_scrambling_control = b00
94799b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        // adaptation_field_control = b??
9480da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // continuity_counter = b????
9490da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        // the fragment of "buffer" follows.
9500da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
95199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        memset(buffer->data(), 0xff, buffer->size());
9520da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9530da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        const unsigned continuity_counter =
9540da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            mSources.editItemAt(sourceIndex)->incrementContinuityCounter();
9550da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9560da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        ptr = buffer->data();
9570da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = 0x47;
9580da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = 0x00 | (PID >> 8);
9590da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        *ptr++ = PID & 0xff;
96099b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        *ptr++ = (lastAccessUnit ? 0x30 : 0x10) | continuity_counter;
96199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello
96299b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        if (lastAccessUnit) {
96399b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            // Pad packet using an adaptation field
96499b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            // Adaptation header all to 0 execpt size
96599b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            uint8_t paddingSize = (uint8_t)184 - (accessUnit->size() - offset);
96699b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            *ptr++ = paddingSize - 1;
96799b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            if (paddingSize >= 2) {
96899b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello                *ptr++ = 0x00;
96999b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello                ptr += paddingSize - 2;
97099b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello            }
97199b99df476b1bfb49da74fda9d6960d82b5ffd10Paul Fariello        }
9720da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9730da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size_t sizeLeft = buffer->data() + buffer->size() - ptr;
9740da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        size_t copy = accessUnit->size() - offset;
9750da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        if (copy > sizeLeft) {
9760da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber            copy = sizeLeft;
9770da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        }
9780da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9790da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        memcpy(ptr, accessUnit->data() + offset, copy);
9803e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        CHECK_EQ(internalWrite(buffer->data(), buffer->size()),
9810da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber                 buffer->size());
9820da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9830da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        offset += copy;
9840da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
9850da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
9860da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9870da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Hubervoid MPEG2TSWriter::writeTS() {
9880da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    if (mNumTSPacketsWritten >= mNumTSPacketsBeforeMeta) {
9890da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        writeProgramAssociationTable();
9900da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        writeProgramMap();
9910da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
9920da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber        mNumTSPacketsBeforeMeta = mNumTSPacketsWritten + 2500;
9930da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber    }
9940da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}
9950da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
996983995747ed3adaf25035c433df1ccbaa056a898Paul Fariellovoid MPEG2TSWriter::initCrcTable() {
997983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    uint32_t poly = 0x04C11DB7;
998983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
999983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    for (int i = 0; i < 256; i++) {
1000983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello        uint32_t crc = i << 24;
1001983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello        for (int j = 0; j < 8; j++) {
1002983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello            crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0);
1003983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello        }
1004983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello        mCrcTable[i] = crc;
1005983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    }
1006983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello}
1007983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
1008983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello/**
1009983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello * Compute CRC32 checksum for buffer starting at offset start and for length
1010983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello * bytes.
1011983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello */
1012983995747ed3adaf25035c433df1ccbaa056a898Paul Fariellouint32_t MPEG2TSWriter::crc32(const uint8_t *p_start, size_t length) {
1013983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    uint32_t crc = 0xFFFFFFFF;
1014983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    const uint8_t *p;
1015983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
1016983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    for (p = p_start; p < p_start + length; p++) {
1017983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello        crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF];
1018983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    }
1019983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
1020983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello    return crc;
1021983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello}
1022983995747ed3adaf25035c433df1ccbaa056a898Paul Fariello
10233e1763ecdf14769a534f75e94a56785f63174b47Andreas Huberssize_t MPEG2TSWriter::internalWrite(const void *data, size_t size) {
10243e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    if (mFile != NULL) {
10253e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber        return fwrite(data, 1, size, mFile);
10263e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    }
10273e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber
10283e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber    return (*mWriteFunc)(mWriteCookie, data, size);
10293e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber}
10303e1763ecdf14769a534f75e94a56785f63174b47Andreas Huber
10310da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber}  // namespace android
10320da4dab0a45a2bc1d95cbc6ef6a4850ed2569584Andreas Huber
1033