1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber/* 2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Copyright 2012, The Android Open Source Project 3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * you may not use this file except in compliance with the License. 6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * You may obtain a copy of the License at 7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Unless required by applicable law or agreed to in writing, software 11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * See the License for the specific language governing permissions and 14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * limitations under the License. 15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber */ 16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0 18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "TSPacketizer" 19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h> 20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "TSPacketizer.h" 22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "include/avc_utils.h" 23d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 24d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h> 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <arpa/inet.h> 32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstruct TSPacketizer::Track : public RefBase { 36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Track(const sp<AMessage> &format, 37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID, unsigned streamType, unsigned streamID); 38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID() const; 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamType() const; 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamID() const; 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Returns the previous value. 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned incrementContinuityCounter(); 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isAudio() const; 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isVideo() const; 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isH264() const; 50e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber bool isAAC() const; 51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool lacksADTSHeader() const; 5290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber bool isPCMAudio() const; 53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const; 55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> prependADTSHeader(const sp<ABuffer> &accessUnit) const; 56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t countDescriptors() const; 5890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptorAt(size_t index) const; 5990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 6090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber void finalize(); 61a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber void extractCSDIfNecessary(); 6290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> mFormat; 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mPID; 70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mStreamType; 71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mStreamID; 72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mContinuityCounter; 73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString mMIME; 75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Vector<sp<ABuffer> > mCSD; 76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 7790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber Vector<sp<ABuffer> > mDescriptors; 7890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 79b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool mAudioLacksATDSHeaders; 8090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber bool mFinalized; 81a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber bool mExtractedCSD; 82b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::Track::Track( 87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &format, 88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID, unsigned streamType, unsigned streamID) 89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mFormat(format), 90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPID(PID), 91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStreamType(streamType), 92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStreamID(streamID), 93b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mContinuityCounter(0), 9490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mAudioLacksATDSHeaders(false), 95a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mFinalized(false), 96a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mExtractedCSD(false) { 97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(format->findString("mime", &mMIME)); 98a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 99a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 100a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid TSPacketizer::Track::extractCSDIfNecessary() { 101a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (mExtractedCSD) { 102a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return; 103a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC) 106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber || !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0;; ++i) { 108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> csd; 109a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!mFormat->findBuffer(AStringPrintf("csd-%d", i).c_str(), &csd)) { 110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCSD.push(csd); 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 115b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 116b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 117b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber int32_t isADTS; 118b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (!mFormat->findInt32("is-adts", &isADTS) || isADTS == 0) { 119b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mAudioLacksATDSHeaders = true; 120b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 121b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 123a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 124a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mExtractedCSD = true; 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::Track::~Track() { 128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::PID() const { 131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mPID; 132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::streamType() const { 135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mStreamType; 136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::streamID() const { 139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mStreamID; 140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::incrementContinuityCounter() { 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned prevCounter = mContinuityCounter; 144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mContinuityCounter == 16) { 146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mContinuityCounter = 0; 147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return prevCounter; 150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isAudio() const { 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strncasecmp("audio/", mMIME.c_str(), 6); 154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isVideo() const { 157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strncasecmp("video/", mMIME.c_str(), 6); 158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isH264() const { 161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); 162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 164e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberbool TSPacketizer::Track::isAAC() const { 165e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC); 166e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber} 167e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 16890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool TSPacketizer::Track::isPCMAudio() const { 16990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW); 17090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 17190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::lacksADTSHeader() const { 173b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return mAudioLacksATDSHeaders; 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<ABuffer> TSPacketizer::Track::prependCSD( 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &accessUnit) const { 178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t size = 0; 179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mCSD.size(); ++i) { 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size += mCSD.itemAt(i)->size(); 181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> dup = new ABuffer(accessUnit->size() + size); 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = 0; 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mCSD.size(); ++i) { 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &csd = mCSD.itemAt(i); 187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(dup->data() + offset, csd->data(), csd->size()); 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += csd->size(); 190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(dup->data() + offset, accessUnit->data(), accessUnit->size()); 193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return dup; 195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<ABuffer> TSPacketizer::Track::prependADTSHeader( 198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &accessUnit) const { 199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(mCSD.size(), 1u); 200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *codec_specific_data = mCSD.itemAt(0)->data(); 202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint32_t aac_frame_length = accessUnit->size() + 7; 204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> dup = new ABuffer(aac_frame_length); 206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned profile = (codec_specific_data[0] >> 3) - 1; 208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned sampling_freq_index = 210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ((codec_specific_data[0] & 7) << 1) 211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | (codec_specific_data[1] >> 7); 212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned channel_configuration = 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (codec_specific_data[1] >> 3) & 0x0f; 215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = dup->data(); 217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xff; 2193b7ddf83db2d11c08116a6476c0f11e71bd72ba4Chong Zhang *ptr++ = 0xf9; // b11111001, ID=1(MPEG-2), layer=0, protection_absent=1 220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber profile << 6 223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | sampling_freq_index << 2 224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | ((channel_configuration >> 2) & 1); // private_bit=0 225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0 227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (channel_configuration & 3) << 6 229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | aac_frame_length >> 11; 230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (aac_frame_length >> 3) & 0xff; 231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (aac_frame_length & 7) << 5; 232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0 234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0; 235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data(), accessUnit->size()); 237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return dup; 239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 24190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersize_t TSPacketizer::Track::countDescriptors() const { 24290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return mDescriptors.size(); 24390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 24490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 24590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> TSPacketizer::Track::descriptorAt(size_t index) const { 24690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_LT(index, mDescriptors.size()); 24790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return mDescriptors.itemAt(index); 24890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 24990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 25090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid TSPacketizer::Track::finalize() { 25190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mFinalized) { 25290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return; 25390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 25490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 25590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (isH264()) { 25690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber { 25790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC video descriptor (40) 25890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 25990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(6); 26090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 26190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 40; // descriptor_tag 26290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 4; // descriptor_length 26390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 264308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang if (mCSD.size() > 0) { 265308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK_GE(mCSD.size(), 1u); 266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang const sp<ABuffer> &sps = mCSD.itemAt(0); 267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(!memcmp("\x00\x00\x00\x01", sps->data(), 4)); 268308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK_GE(sps->size(), 7u); 269308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang // profile_idc, constraint_set*, level_idc 270308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang memcpy(&data[2], sps->data() + 4, 3); 271308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } else { 272308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang int32_t profileIdc, levelIdc, constraintSet; 273308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(mFormat->findInt32("profile-idc", &profileIdc)); 274308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(mFormat->findInt32("level-idc", &levelIdc)); 275308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(mFormat->findInt32("constraint-set", &constraintSet)); 276308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK_GE(profileIdc, 0u); 277308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK_GE(levelIdc, 0u); 278308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang data[2] = profileIdc; // profile_idc 279308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang data[3] = constraintSet; // constraint_set* 280308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang data[4] = levelIdc; // level_idc 281308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang } 28290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 28390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC_still_present=0, AVC_24_hour_picture_flag=0, reserved 28490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[5] = 0x3f; 28590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 28690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 28790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 28890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 28990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber { 29090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC timing and HRD descriptor (42) 29190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 29290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(4); 29390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 29490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 42; // descriptor_tag 29590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 2; // descriptor_length 29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // hrd_management_valid_flag = 0 29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // reserved = 111111b 29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // picture_and_timing_info_present = 0 30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[2] = 0x7e; 30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // fixed_frame_rate_flag = 0 30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // temporal_poc_flag = 0 30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // picture_to_display_conversion_flag = 0 30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // reserved = 11111b 30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[3] = 0x1f; 30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } else if (isPCMAudio()) { 31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // LPCM audio stream descriptor (0x83) 31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int32_t channelCount; 31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mFormat->findInt32("channel-count", &channelCount)); 31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_EQ(channelCount, 2); 31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int32_t sampleRate; 31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mFormat->findInt32("sample-rate", &sampleRate)); 32090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(sampleRate == 44100 || sampleRate == 48000); 32190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 32290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(4); 32390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 32490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 0x83; // descriptor_tag 32590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 2; // descriptor_length 32690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 32790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber unsigned sampling_frequency = (sampleRate == 44100) ? 1 : 2; 32890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 32990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[2] = (sampling_frequency << 5) 33090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | (3 /* reserved */ << 1) 33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | 0 /* emphasis_flag */; 33290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 33390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[3] = 33490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber (1 /* number_of_channels = stereo */ << 5) 33590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | 0xf /* reserved */; 33690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 33790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 33890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 340bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber mFinalized = true; 341bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber} 3420224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 343bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber//////////////////////////////////////////////////////////////////////////////// 344bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 345bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas HuberTSPacketizer::TSPacketizer(uint32_t flags) 346bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber : mFlags(flags), 347bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber mPATContinuityCounter(0), 348bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber mPMTContinuityCounter(0) { 349bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber initCrcTable(); 3500224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 351bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber if (flags & (EMIT_HDCP20_DESCRIPTOR | EMIT_HDCP21_DESCRIPTOR)) { 352bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber int32_t hdcpVersion; 353bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber if (flags & EMIT_HDCP20_DESCRIPTOR) { 354bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber CHECK(!(flags & EMIT_HDCP21_DESCRIPTOR)); 355bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber hdcpVersion = 0x20; 356bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber } else { 357bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber CHECK(!(flags & EMIT_HDCP20_DESCRIPTOR)); 358bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 359bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // HDCP2.0 _and_ HDCP 2.1 specs say to set the version 360bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // inside the HDCP descriptor to 0x20!!! 361bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber hdcpVersion = 0x20; 362bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber } 363bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 364bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // HDCP descriptor 3650224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber sp<ABuffer> descriptor = new ABuffer(7); 3660224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber uint8_t *data = descriptor->data(); 3670224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[0] = 0x05; // descriptor_tag 3680224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[1] = 5; // descriptor_length 3690224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[2] = 'H'; 3700224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[3] = 'D'; 3710224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[4] = 'C'; 3720224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[5] = 'P'; 3730224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber data[6] = hdcpVersion; 3740224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 375bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber mProgramInfoDescriptors.push_back(descriptor); 3760224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber } 377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::~TSPacketizer() { 380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t TSPacketizer::addTrack(const sp<AMessage> &format) { 383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString mime; 384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(format->findString("mime", &mime)); 385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PIDStart; 387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isVideo = !strncasecmp("video/", mime.c_str(), 6); 388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isAudio = !strncasecmp("audio/", mime.c_str(), 6); 389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 390d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (isVideo) { 391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PIDStart = 0x1011; 392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (isAudio) { 393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PIDStart = 0x1100; 394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamType; 399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamIDStart; 400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamIDStop; 401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamType = 0x1b; 404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStart = 0xe0; 405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStop = 0xef; 406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamType = 0x0f; 408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStart = 0xc0; 409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStop = 0xdf; 410e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { 411e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamType = 0x83; 412e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamIDStart = 0xbd; 413e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamIDStop = 0xbd; 414d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numTracksOfThisType = 0; 419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID = PIDStart; 420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(i); 423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (track->streamType() == streamType) { 425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++numTracksOfThisType; 426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((isAudio && track->isAudio()) || (isVideo && track->isVideo())) { 429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++PID; 430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamID = streamIDStart + numTracksOfThisType; 434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (streamID > streamIDStop) { 435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return -ERANGE; 436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Track> track = new Track(format, PID, streamType, streamID); 439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mTracks.add(track); 440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 442a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t TSPacketizer::extractCSDIfNecessary(size_t trackIndex) { 443a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (trackIndex >= mTracks.size()) { 444a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return -ERANGE; 445a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 446a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 447a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const sp<Track> &track = mTracks.itemAt(trackIndex); 448a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber track->extractCSDIfNecessary(); 449a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 450a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return OK; 451a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber} 452a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t TSPacketizer::packetize( 454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex, 455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &_accessUnit, 456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> *packets, 457b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber uint32_t flags, 45890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const uint8_t *PES_private_data, size_t PES_private_data_len, 45990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t numStuffingBytes) { 460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> accessUnit = _accessUnit; 461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 46228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber int64_t timeUs; 46328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 46428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packets->clear(); 466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (trackIndex >= mTracks.size()) { 468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return -ERANGE; 469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(trackIndex); 472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 473c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber if (track->isH264() && (flags & PREPEND_SPS_PPS_TO_IDR_FRAMES) 474c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber && IsIDR(accessUnit)) { 475c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber // prepend codec specific data, i.e. SPS and PPS. 476c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber accessUnit = track->prependCSD(accessUnit); 477e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else if (track->isAAC() && track->lacksADTSHeader()) { 478b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber CHECK(!(flags & IS_ENCRYPTED)); 479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber accessUnit = track->prependADTSHeader(accessUnit); 480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID 487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b?? 489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // -- payload follows 491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // packet_startcode_prefix = 0x000001 492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // stream_id 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_packet_length = 0x???? 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b10 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_scrambling_control = b00 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_priority = b0 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // data_alignment_indicator = b1 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // copyright = b0 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // original_or_copy = b0 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS_DTS_flags = b10 (PTS only) 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ESCR_flag = b0 502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ES_rate_flag = b0 503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // DSM_trick_mode_flag = b0 504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // additional_copy_info_flag = b0 505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_CRC_flag = b0 506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_extension_flag = b0 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_header_data_length = 0x05 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b0010 (PTS) 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[32..30] = b??? 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[29..15] = b??? ???? ???? ???? (15 bits) 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[14..0] = b??? ???? ???? ???? (15 bits) 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the first fragment of "buffer" follows 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 517820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // Each transport packet (except for the last one contributing to the PES 518820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // payload) must contain a multiple of 16 bytes of payload per HDCP spec. 519820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber bool alignPayload = 520820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber (mFlags & (EMIT_HDCP20_DESCRIPTOR | EMIT_HDCP21_DESCRIPTOR)); 521820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 522820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber /* 523820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber a) The very first PES transport stream packet contains 524820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 525820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 4 bytes of TS header 526820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ... padding 527820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 14 bytes of static PES header 528820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber PES_private_data_len + 1 bytes (only if PES_private_data_len > 0) 529820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numStuffingBytes bytes 530820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 531820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber followed by the payload 532820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 533820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber b) Subsequent PES transport stream packets contain 534820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 535820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 4 bytes of TS header 536820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ... padding 537820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 538820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber followed by the payload 539820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber */ 540820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 54190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t PES_packet_length = accessUnit->size() + 8 + numStuffingBytes; 542b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (PES_private_data_len > 0) { 543b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber PES_packet_length += PES_private_data_len + 1; 544b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 545b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 546820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numTSPackets = 1; 547820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 548820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber { 549820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // Make sure the PES header fits into a single TS packet: 550820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t PES_header_size = 14 + numStuffingBytes; 551820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (PES_private_data_len > 0) { 552820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber PES_header_size += PES_private_data_len + 1; 553820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 554820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 555820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber CHECK_LE(PES_header_size, 188u - 4u); 556820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 557820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t sizeAvailableForPayload = 188 - 4 - PES_header_size; 558820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numBytesOfPayload = accessUnit->size(); 559820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 560820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numBytesOfPayload > sizeAvailableForPayload) { 561820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayload = sizeAvailableForPayload; 562820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 563820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (alignPayload && numBytesOfPayload > 16) { 564820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayload -= (numBytesOfPayload % 16); 565820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 566820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 567820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 56894dcc94b16cc6c2a7aa02df2d0d6b8743d738d78Colin Cross size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload; 569820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ALOGV("packet 1 contains %zd padding bytes and %zd bytes of payload", 570820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numPaddingBytes, numBytesOfPayload); 571820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 572820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numBytesOfPayloadRemaining = accessUnit->size() - numBytesOfPayload; 573820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 574820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber#if 0 575820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // The following hopefully illustrates the logic that led to the 576820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // more efficient computation in the #else block... 577820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 578820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber while (numBytesOfPayloadRemaining > 0) { 579820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t sizeAvailableForPayload = 188 - 4; 580820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 581820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numBytesOfPayload = numBytesOfPayloadRemaining; 582820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 583820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numBytesOfPayload > sizeAvailableForPayload) { 584820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayload = sizeAvailableForPayload; 585820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 586820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (alignPayload && numBytesOfPayload > 16) { 587820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayload -= (numBytesOfPayload % 16); 588820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 589820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 590820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 591820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload; 592820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ALOGI("packet %zd contains %zd padding bytes and %zd bytes of payload", 593820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numTSPackets + 1, numPaddingBytes, numBytesOfPayload); 594820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 595820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayloadRemaining -= numBytesOfPayload; 596820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ++numTSPackets; 597820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 598820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber#else 599820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // This is how many bytes of payload each subsequent TS packet 600820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // can contain at most. 601820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber sizeAvailableForPayload = 188 - 4; 602820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t sizeAvailableForAlignedPayload = sizeAvailableForPayload; 603820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (alignPayload) { 604820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // We're only going to use a subset of the available space 605820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // since we need to make each fragment a multiple of 16 in size. 606820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber sizeAvailableForAlignedPayload -= 607820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber (sizeAvailableForAlignedPayload % 16); 608820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 609820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 610820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numFullTSPackets = 611820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayloadRemaining / sizeAvailableForAlignedPayload; 612820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 613820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numTSPackets += numFullTSPackets; 614820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 615820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numBytesOfPayloadRemaining -= 616820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber numFullTSPackets * sizeAvailableForAlignedPayload; 617820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 618820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // numBytesOfPayloadRemaining < sizeAvailableForAlignedPayload 619820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numFullTSPackets == 0 && numBytesOfPayloadRemaining > 0) { 620820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // There wasn't enough payload left to form a full aligned payload, 621820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // the last packet doesn't have to be aligned. 622820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ++numTSPackets; 623820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } else if (numFullTSPackets > 0 624820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber && numBytesOfPayloadRemaining 625820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber + sizeAvailableForAlignedPayload > sizeAvailableForPayload) { 626820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // The last packet emitted had a full aligned payload and together 627820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // with the bytes remaining does exceed the unaligned payload 628820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber // size, so we need another packet. 629820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ++numTSPackets; 630820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 631820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber#endif 632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PAT_AND_PMT) { 635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber numTSPackets += 2; 636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PCR) { 639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++numTSPackets; 640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(numTSPackets * 188); 643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *packetDataStart = buffer->data(); 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PAT_AND_PMT) { 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Program Association Table (PAT): 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = b0000000000000 (13 bits) 652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b01 (no adaptation field, payload only) 654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // skip = 0x00 656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // --- payload follows 657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // table_id = 0x00 658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_syntax_indicator = b1 659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // must_be_zero = b0 660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_length = 0x00d 662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_stream_id = 0x0000 663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 664d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // version_number = b00001 665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // current_next_indicator = b1 666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_number = 0x00 667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // last_section_number = 0x00 668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // one program follows: 669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_number = 0x0001 670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_map_PID = kPID_PMT (13 bits!) 672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // CRC = 0x???????? 673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mPATContinuityCounter == 16) { 675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPATContinuityCounter = 0; 676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40; 681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10 | mPATContinuityCounter; 683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 68590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *crcDataStart = ptr; 686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xb0; 688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x0d; 689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xc3; 692d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 693d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 694d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (kPID_PMT >> 8); 697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PMT & 0xff; 698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(ptr - crcDataStart, 12); 700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, &crc, 4); 702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += 4; 703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Program Map (PMT): 710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 713d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 714d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = kPID_PMT (13 bits) 715d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b01 (no adaptation field, payload only) 717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // skip = 0x00 719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // -- payload follows 720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // table_id = 0x02 721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_syntax_indicator = b1 722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // must_be_zero = b0 723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_length = 0x??? 725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_number = 0x0001 726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // version_number = b00001 728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // current_next_indicator = b1 729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_number = 0x00 730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // last_section_number = 0x00 731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR_PID = kPCR_PID (13 bits) 733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1111 734bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // program_info_length = 0x??? 735bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // program_info_descriptors follow 736bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber // one or more elementary stream descriptions follow: 737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // stream_type = 0x?? 738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // elementary_PID = b? ???? ???? ???? (13 bits) 740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1111 741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ES_info_length = 0x000 742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // CRC = 0x???????? 743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mPMTContinuityCounter == 16) { 745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPMTContinuityCounter = 0; 746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr = packetDataStart; 749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (kPID_PMT >> 8); 751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PMT & 0xff; 752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10 | mPMTContinuityCounter; 753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crcDataStart = ptr; 756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x02; 75790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 75890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0x00; // section_length to be filled in below. 75990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0x00; 76090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xc3; 764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (kPID_PCR >> 8); 767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PCR & 0xff; 768bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 769bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber size_t program_info_length = 0; 770bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber for (size_t i = 0; i < mProgramInfoDescriptors.size(); ++i) { 771bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber program_info_length += mProgramInfoDescriptors.itemAt(i)->size(); 772bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber } 773bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 774bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber CHECK_LT(program_info_length, 0x400); 775bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber *ptr++ = 0xf0 | (program_info_length >> 8); 776bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber *ptr++ = (program_info_length & 0xff); 777bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber 778bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber for (size_t i = 0; i < mProgramInfoDescriptors.size(); ++i) { 779bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber const sp<ABuffer> &desc = mProgramInfoDescriptors.itemAt(i); 780bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber memcpy(ptr, desc->data(), desc->size()); 781bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber ptr += desc->size(); 782bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber } 783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(i); 786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 78790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // Make sure all the decriptors have been added. 78890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber track->finalize(); 78990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->streamType(); 791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (track->PID() >> 8); 792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 79390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 79490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t ES_info_length = 0; 79590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < track->countDescriptors(); ++i) { 79690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ES_info_length += track->descriptorAt(i)->size(); 79790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 79890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_LE(ES_info_length, 0xfff); 79990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 80090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0xf0 | (ES_info_length >> 8); 80190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = (ES_info_length & 0xff); 80290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 80390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < track->countDescriptors(); ++i) { 80490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &descriptor = track->descriptorAt(i); 80590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber memcpy(ptr, descriptor->data(), descriptor->size()); 80690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ptr += descriptor->size(); 80790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 808d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 809d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 81090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t section_length = ptr - (crcDataStart + 3) + 4 /* CRC */; 81190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 81290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber crcDataStart[1] = 0xb0 | (section_length >> 8); 81390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber crcDataStart[2] = section_length & 0xff; 81490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 815d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 816d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, &crc, 4); 817d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += 4; 818d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 819d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sizeLeft = packetDataStart + 188 - ptr; 820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 821d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 822d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 823d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 824d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PCR) { 826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR stream 827d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 828d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 829d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 830d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 831d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = kPCR_PID (13 bits) 832d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 833d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b10 (adaptation field only, no payload) 834d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b0000 (does not increment) 835d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_length = 183 836d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // discontinuity_indicator = b0 837d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // random_access_indicator = b0 838d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // elementary_stream_priority_indicator = b0 839d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR_flag = b1 840d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // OPCR_flag = b0 841d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // splicing_point_flag = b0 842d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_private_data_flag = b0 843d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_extension_flag = b0 844d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_clock_reference_base = b????????????????????????????????? 845d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111111 846d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_clock_reference_extension = b????????? 847d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 848d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 849d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 850d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t PCR = nowUs * 27; // PCR based on a 27MHz clock 851d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t PCR_base = PCR / 300; 852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t PCR_ext = PCR % 300; 853d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 854d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 855d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 856d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (kPID_PCR >> 8); 857d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PCR & 0xff; 858d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x20; 859d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xb7; // adaptation_field_length 860d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10; 861d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 25) & 0xff; 862d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 17) & 0xff; 863d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 9) & 0xff; 864d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = ((PCR_base & 1) << 7) | 0x7e | ((PCR_ext >> 8) & 1); 865d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_ext & 0xff); 866d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 867d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 868d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 869d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 870d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 871d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 872d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 87328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint64_t PTS = (timeUs * 9ll) / 100ll; 874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (PES_packet_length >= 65536) { 876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // This really should only happen for video. 877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(track->isVideo()); 878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // It's valid to set this to 0 for video according to the specs. 880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PES_packet_length = 0; 881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 883820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t sizeAvailableForPayload = 188 - 4 - 14 - numStuffingBytes; 884820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (PES_private_data_len > 0) { 885820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber sizeAvailableForPayload -= PES_private_data_len + 1; 886820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 887820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 888820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t copy = accessUnit->size(); 889820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 890820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (copy > sizeAvailableForPayload) { 891820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber copy = sizeAvailableForPayload; 892820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 893820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (alignPayload && copy > 16) { 894820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber copy -= (copy % 16); 895820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 896820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 897820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 898820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numPaddingBytes = sizeAvailableForPayload - copy; 899820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (track->PID() >> 8); 903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 905820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber *ptr++ = (numPaddingBytes > 0 ? 0x30 : 0x10) 906820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber | track->incrementContinuityCounter(); 907820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 908820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numPaddingBytes > 0) { 909820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber *ptr++ = numPaddingBytes - 1; 910820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numPaddingBytes >= 2) { 911d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 912820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber memset(ptr, 0xff, numPaddingBytes - 2); 913820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ptr += numPaddingBytes - 2; 914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 918d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 919d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->streamID(); 921d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = PES_packet_length >> 8; 922d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = PES_packet_length & 0xff; 923d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x84; 924b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber *ptr++ = (PES_private_data_len > 0) ? 0x81 : 0x80; 925b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 92690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t headerLength = 0x05 + numStuffingBytes; 92790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (PES_private_data_len > 0) { 92890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber headerLength += 1 + PES_private_data_len; 92990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 93090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 93190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = headerLength; 932b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1; 934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PTS >> 22) & 0xff; 935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1; 936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PTS >> 7) & 0xff; 937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = ((PTS & 0x7f) << 1) | 1; 938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 939b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (PES_private_data_len > 0) { 940b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber *ptr++ = 0x8e; // PES_private_data_flag, reserved. 941b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber memcpy(ptr, PES_private_data, PES_private_data_len); 942b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber ptr += PES_private_data_len; 943b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 944b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 94590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < numStuffingBytes; ++i) { 94690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0xff; 94790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 94890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data(), copy); 950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += copy; 951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 952820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber CHECK_EQ(ptr, packetDataStart + 188); 953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = copy; 956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (offset < accessUnit->size()) { 957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // for subsequent fragments of "buffer": 958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b0 961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex] 963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b?? 965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the fragment of "buffer" follows. 967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 968820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t sizeAvailableForPayload = 188 - 4; 969820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 970820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t copy = accessUnit->size() - offset; 971820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 972820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (copy > sizeAvailableForPayload) { 973820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber copy = sizeAvailableForPayload; 974820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 975820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (alignPayload && copy > 16) { 976820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber copy -= (copy % 16); 977820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 978820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber } 979820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 980820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber size_t numPaddingBytes = sizeAvailableForPayload - copy; 981820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber 982d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 983d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 984d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00 | (track->PID() >> 8); 985d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 987820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber *ptr++ = (numPaddingBytes > 0 ? 0x30 : 0x10) 988820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber | track->incrementContinuityCounter(); 989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 990820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numPaddingBytes > 0) { 991820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber *ptr++ = numPaddingBytes - 1; 992820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber if (numPaddingBytes >= 2) { 993d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 994820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber memset(ptr, 0xff, numPaddingBytes - 2); 995820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber ptr += numPaddingBytes - 2; 996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data() + offset, copy); 1000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += copy; 1001820ebf8d452165d9a7619e2667ffa3c0b638da39Andreas Huber CHECK_EQ(ptr, packetDataStart + 188); 1002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += copy; 1004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 1005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(packetDataStart == buffer->data() + buffer->capacity()); 1008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *packets = buffer; 1010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid TSPacketizer::initCrcTable() { 1015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t poly = 0x04C11DB7; 1016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (int i = 0; i < 256; i++) { 1018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = i << 24; 1019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (int j = 0; j < 8; j++) { 1020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0); 1021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCrcTable[i] = crc; 1023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1026d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint32_t TSPacketizer::crc32(const uint8_t *start, size_t size) const { 1027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = 0xFFFFFFFF; 1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *p; 1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (p = start; p < start + size; ++p) { 1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF]; 1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return crc; 1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1037e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Hubersp<ABuffer> TSPacketizer::prependCSD( 1038e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber size_t trackIndex, const sp<ABuffer> &accessUnit) const { 1039e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_LT(trackIndex, mTracks.size()); 1040e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1041e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber const sp<Track> &track = mTracks.itemAt(trackIndex); 1042e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK(track->isH264() && IsIDR(accessUnit)); 1043e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1044e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber int64_t timeUs; 1045e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 1046e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1047e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber sp<ABuffer> accessUnit2 = track->prependCSD(accessUnit); 1048e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1049e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber accessUnit2->meta()->setInt64("timeUs", timeUs); 1050e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1051e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber return accessUnit2; 1052e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber} 1053e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1056