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> ¬ify); 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> ¬ify) { 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