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(); 6190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 62d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> mFormat; 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mPID; 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mStreamType; 70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mStreamID; 71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned mContinuityCounter; 72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString mMIME; 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Vector<sp<ABuffer> > mCSD; 75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 7690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber Vector<sp<ABuffer> > mDescriptors; 7790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 78b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool mAudioLacksATDSHeaders; 7990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber bool mFinalized; 80b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::Track::Track( 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &format, 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID, unsigned streamType, unsigned streamID) 87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mFormat(format), 88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPID(PID), 89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStreamType(streamType), 90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mStreamID(streamID), 91b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mContinuityCounter(0), 9290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mAudioLacksATDSHeaders(false), 9390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mFinalized(false) { 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(format->findString("mime", &mMIME)); 95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC) 97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber || !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0;; ++i) { 99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> csd; 100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!format->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) { 101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCSD.push(csd); 105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 106b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 107b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (!strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 108b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber int32_t isADTS; 109b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (!mFormat->findInt32("is-adts", &isADTS) || isADTS == 0) { 110b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mAudioLacksATDSHeaders = true; 111b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 112b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::Track::~Track() { 117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::PID() const { 120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mPID; 121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::streamType() const { 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mStreamType; 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::streamID() const { 128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mStreamID; 129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberunsigned TSPacketizer::Track::incrementContinuityCounter() { 132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned prevCounter = mContinuityCounter; 133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mContinuityCounter == 16) { 135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mContinuityCounter = 0; 136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return prevCounter; 139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isAudio() const { 142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strncasecmp("audio/", mMIME.c_str(), 6); 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isVideo() const { 146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strncasecmp("video/", mMIME.c_str(), 6); 147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::isH264() const { 150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_VIDEO_AVC); 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 153e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberbool TSPacketizer::Track::isAAC() const { 154e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_AAC); 155e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber} 156e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 15790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool TSPacketizer::Track::isPCMAudio() const { 15890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return !strcasecmp(mMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW); 15990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 16090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberbool TSPacketizer::Track::lacksADTSHeader() const { 162b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return mAudioLacksATDSHeaders; 163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<ABuffer> TSPacketizer::Track::prependCSD( 166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &accessUnit) const { 167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t size = 0; 168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mCSD.size(); ++i) { 169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size += mCSD.itemAt(i)->size(); 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> dup = new ABuffer(accessUnit->size() + size); 173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = 0; 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mCSD.size(); ++i) { 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &csd = mCSD.itemAt(i); 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(dup->data() + offset, csd->data(), csd->size()); 178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += csd->size(); 179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(dup->data() + offset, accessUnit->data(), accessUnit->size()); 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return dup; 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<ABuffer> TSPacketizer::Track::prependADTSHeader( 187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &accessUnit) const { 188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(mCSD.size(), 1u); 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *codec_specific_data = mCSD.itemAt(0)->data(); 191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint32_t aac_frame_length = accessUnit->size() + 7; 193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> dup = new ABuffer(aac_frame_length); 195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned profile = (codec_specific_data[0] >> 3) - 1; 197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned sampling_freq_index = 199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ((codec_specific_data[0] & 7) << 1) 200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | (codec_specific_data[1] >> 7); 201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned channel_configuration = 203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (codec_specific_data[1] >> 3) & 0x0f; 204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = dup->data(); 206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xff; 208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1 209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber profile << 6 212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | sampling_freq_index << 2 213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | ((channel_configuration >> 2) & 1); // private_bit=0 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // original_copy=0, home=0, copyright_id_bit=0, copyright_id_start=0 216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (channel_configuration & 3) << 6 218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber | aac_frame_length >> 11; 219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (aac_frame_length >> 3) & 0xff; 220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (aac_frame_length & 7) << 5; 221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adts_buffer_fullness=0, number_of_raw_data_blocks_in_frame=0 223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0; 224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data(), accessUnit->size()); 226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return dup; 228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 23090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersize_t TSPacketizer::Track::countDescriptors() const { 23190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return mDescriptors.size(); 23290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 23390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 23490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> TSPacketizer::Track::descriptorAt(size_t index) const { 23590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_LT(index, mDescriptors.size()); 23690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return mDescriptors.itemAt(index); 23790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 23890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 23990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid TSPacketizer::Track::finalize() { 24090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mFinalized) { 24190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return; 24290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 24390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 24490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (isH264()) { 24590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber { 24690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC video descriptor (40) 24790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 24890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(6); 24990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 25090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 40; // descriptor_tag 25190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 4; // descriptor_length 25290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 25390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_EQ(mCSD.size(), 1u); 25490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &sps = mCSD.itemAt(0); 25590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(!memcmp("\x00\x00\x00\x01", sps->data(), 4)); 25690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_GE(sps->size(), 7u); 25790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // profile_idc, constraint_set*, level_idc 25890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber memcpy(&data[2], sps->data() + 4, 3); 25990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 26090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC_still_present=0, AVC_24_hour_picture_flag=0, reserved 26190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[5] = 0x3f; 26290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 26390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 26490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 26590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 26690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber { 26790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // AVC timing and HRD descriptor (42) 26890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 26990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(4); 27090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 27190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 42; // descriptor_tag 27290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 2; // descriptor_length 27390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 27490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // hrd_management_valid_flag = 0 27590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // reserved = 111111b 27690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // picture_and_timing_info_present = 0 27790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 27890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[2] = 0x7e; 27990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 28090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // fixed_frame_rate_flag = 0 28190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // temporal_poc_flag = 0 28290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // picture_to_display_conversion_flag = 0 28390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // reserved = 11111b 28490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[3] = 0x1f; 28590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 28690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 28790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 28890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } else if (isPCMAudio()) { 28990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // LPCM audio stream descriptor (0x83) 29090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 29190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int32_t channelCount; 29290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mFormat->findInt32("channel-count", &channelCount)); 29390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_EQ(channelCount, 2); 29490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 29590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int32_t sampleRate; 29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(mFormat->findInt32("sample-rate", &sampleRate)); 29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(sampleRate == 44100 || sampleRate == 48000); 29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> descriptor = new ABuffer(4); 30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *data = descriptor->data(); 30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[0] = 0x83; // descriptor_tag 30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[1] = 2; // descriptor_length 30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber unsigned sampling_frequency = (sampleRate == 44100) ? 1 : 2; 30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[2] = (sampling_frequency << 5) 30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | (3 /* reserved */ << 1) 30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | 0 /* emphasis_flag */; 30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber data[3] = 31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber (1 /* number_of_channels = stereo */ << 5) 31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber | 0xf /* reserved */; 31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mDescriptors.push_back(descriptor); 31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mFinalized = true; 31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::TSPacketizer() 323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mPATContinuityCounter(0), 324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPMTContinuityCounter(0) { 325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber initCrcTable(); 326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberTSPacketizer::~TSPacketizer() { 329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t TSPacketizer::addTrack(const sp<AMessage> &format) { 332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString mime; 333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(format->findString("mime", &mime)); 334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PIDStart; 336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isVideo = !strncasecmp("video/", mime.c_str(), 6); 337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool isAudio = !strncasecmp("audio/", mime.c_str(), 6); 338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (isVideo) { 340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PIDStart = 0x1011; 341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (isAudio) { 342d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PIDStart = 0x1100; 343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamType; 348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamIDStart; 349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamIDStop; 350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamType = 0x1b; 353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStart = 0xe0; 354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStop = 0xef; 355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) { 356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamType = 0x0f; 357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStart = 0xc0; 358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber streamIDStop = 0xdf; 359e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { 360e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamType = 0x83; 361e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamIDStart = 0xbd; 362e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber streamIDStop = 0xbd; 363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numTracksOfThisType = 0; 368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned PID = PIDStart; 369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(i); 372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (track->streamType() == streamType) { 374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++numTracksOfThisType; 375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((isAudio && track->isAudio()) || (isVideo && track->isVideo())) { 378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++PID; 379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber unsigned streamID = streamIDStart + numTracksOfThisType; 383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (streamID > streamIDStop) { 384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return -ERANGE; 385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Track> track = new Track(format, PID, streamType, streamID); 388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mTracks.add(track); 389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 390d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t TSPacketizer::packetize( 392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex, 393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &_accessUnit, 394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> *packets, 395b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber uint32_t flags, 39690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const uint8_t *PES_private_data, size_t PES_private_data_len, 39790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t numStuffingBytes) { 398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> accessUnit = _accessUnit; 399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 40028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber int64_t timeUs; 40128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 40228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packets->clear(); 404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (trackIndex >= mTracks.size()) { 406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return -ERANGE; 407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(trackIndex); 410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 411c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber if (track->isH264() && (flags & PREPEND_SPS_PPS_TO_IDR_FRAMES) 412c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber && IsIDR(accessUnit)) { 413c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber // prepend codec specific data, i.e. SPS and PPS. 414c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber accessUnit = track->prependCSD(accessUnit); 415e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber } else if (track->isAAC() && track->lacksADTSHeader()) { 416b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber CHECK(!(flags & IS_ENCRYPTED)); 417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber accessUnit = track->prependADTSHeader(accessUnit); 418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID 425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b?? 427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // -- payload follows 429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // packet_startcode_prefix = 0x000001 430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // stream_id 431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_packet_length = 0x???? 432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b10 433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_scrambling_control = b00 434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_priority = b0 435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // data_alignment_indicator = b1 436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // copyright = b0 437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // original_or_copy = b0 438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS_DTS_flags = b10 (PTS only) 439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ESCR_flag = b0 440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ES_rate_flag = b0 441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // DSM_trick_mode_flag = b0 442d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // additional_copy_info_flag = b0 443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_CRC_flag = b0 444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_extension_flag = b0 445d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PES_header_data_length = 0x05 446d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b0010 (PTS) 447d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[32..30] = b??? 448d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 449d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[29..15] = b??? ???? ???? ???? (15 bits) 450d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 451d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PTS[14..0] = b??? ???? ???? ???? (15 bits) 452d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1 453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the first fragment of "buffer" follows 454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 45590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t PES_packet_length = accessUnit->size() + 8 + numStuffingBytes; 456b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (PES_private_data_len > 0) { 457b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber PES_packet_length += PES_private_data_len + 1; 458b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 459b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numTSPackets; 461b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (PES_packet_length <= 178) { 462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber numTSPackets = 1; 463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 464b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber numTSPackets = 1 + ((PES_packet_length - 178) + 183) / 184; 465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PAT_AND_PMT) { 468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber numTSPackets += 2; 469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PCR) { 472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++numTSPackets; 473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(numTSPackets * 188); 476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *packetDataStart = buffer->data(); 477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PAT_AND_PMT) { 479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Program Association Table (PAT): 480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = b0000000000000 (13 bits) 485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b01 (no adaptation field, payload only) 487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // skip = 0x00 489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // --- payload follows 490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // table_id = 0x00 491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_syntax_indicator = b1 492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // must_be_zero = b0 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_length = 0x00d 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_stream_id = 0x0000 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // version_number = b00001 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // current_next_indicator = b1 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_number = 0x00 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // last_section_number = 0x00 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // one program follows: 502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_number = 0x0001 503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_map_PID = kPID_PMT (13 bits!) 505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // CRC = 0x???????? 506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mPATContinuityCounter == 16) { 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPATContinuityCounter = 0; 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40; 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10 | mPATContinuityCounter; 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 51890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber uint8_t *crcDataStart = ptr; 519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xb0; 521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x0d; 522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xc3; 525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (kPID_PMT >> 8); 530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PMT & 0xff; 531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(ptr - crcDataStart, 12); 533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, &crc, 4); 535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += 4; 536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 537d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 538d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 540d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Program Map (PMT): 543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = kPID_PMT (13 bits) 548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b01 (no adaptation field, payload only) 550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // skip = 0x00 552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // -- payload follows 553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // table_id = 0x02 554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_syntax_indicator = b1 555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // must_be_zero = b0 556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_length = 0x??? 558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_number = 0x0001 559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b11 560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // version_number = b00001 561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // current_next_indicator = b1 562d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // section_number = 0x00 563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // last_section_number = 0x00 564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR_PID = kPCR_PID (13 bits) 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1111 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_info_length = 0x000 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // one or more elementary stream descriptions follow: 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // stream_type = 0x?? 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // elementary_PID = b? ???? ???? ???? (13 bits) 572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b1111 573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // ES_info_length = 0x000 574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // CRC = 0x???????? 575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (++mPMTContinuityCounter == 16) { 577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPMTContinuityCounter = 0; 578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr = packetDataStart; 581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (kPID_PMT >> 8); 583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PMT & 0xff; 584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10 | mPMTContinuityCounter; 585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crcDataStart = ptr; 588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x02; 58990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 59090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0x00; // section_length to be filled in below. 59190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0x00; 59290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xc3; 596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (kPID_PCR >> 8); 599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PCR & 0xff; 600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xf0; 601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.itemAt(i); 605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 60690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // Make sure all the decriptors have been added. 60790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber track->finalize(); 60890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->streamType(); 610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xe0 | (track->PID() >> 8); 611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 61290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 61390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t ES_info_length = 0; 61490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < track->countDescriptors(); ++i) { 61590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ES_info_length += track->descriptorAt(i)->size(); 61690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 61790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK_LE(ES_info_length, 0xfff); 61890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 61990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0xf0 | (ES_info_length >> 8); 62090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = (ES_info_length & 0xff); 62190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 62290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < track->countDescriptors(); ++i) { 62390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &descriptor = track->descriptorAt(i); 62490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber memcpy(ptr, descriptor->data(), descriptor->size()); 62590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber ptr += descriptor->size(); 62690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 62990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t section_length = ptr - (crcDataStart + 3) + 4 /* CRC */; 63090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 63190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber crcDataStart[1] = 0xb0 | (section_length >> 8); 63290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber crcDataStart[2] = section_length & 0xff; 63390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = htonl(crc32(crcDataStart, ptr - crcDataStart)); 635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, &crc, 4); 636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += 4; 637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sizeLeft = packetDataStart + 188 - ptr; 639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flags & EMIT_PCR) { 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR stream 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b1 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = kPCR_PID (13 bits) 651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b10 (adaptation field only, no payload) 653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b0000 (does not increment) 654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_length = 183 655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // discontinuity_indicator = b0 656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // random_access_indicator = b0 657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // elementary_stream_priority_indicator = b0 658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PCR_flag = b1 659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // OPCR_flag = b0 660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // splicing_point_flag = b0 661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_private_data_flag = b0 662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_extension_flag = b0 663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_clock_reference_base = b????????????????????????????????? 664d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // reserved = b111111 665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // program_clock_reference_extension = b????????? 666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t PCR = nowUs * 27; // PCR based on a 27MHz clock 670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t PCR_base = PCR / 300; 671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t PCR_ext = PCR % 300; 672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (kPID_PCR >> 8); 676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = kPID_PCR & 0xff; 677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x20; 678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0xb7; // adaptation_field_length 679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x10; 680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 25) & 0xff; 681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 17) & 0xff; 682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_base >> 9) & 0xff; 683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = ((PCR_base & 1) << 7) | 0x7e | ((PCR_ext >> 8) & 1); 684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PCR_ext & 0xff); 685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft); 688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 69228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint64_t PTS = (timeUs * 9ll) / 100ll; 693d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 694b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool padding = (PES_packet_length < (188 - 10)); 695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (PES_packet_length >= 65536) { 697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // This really should only happen for video. 698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(track->isVideo()); 699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // It's valid to set this to 0 for video according to the specs. 701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber PES_packet_length = 0; 702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x40 | (track->PID() >> 8); 707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter(); 709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (padding) { 711b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber size_t paddingSize = 188 - 10 - PES_packet_length; 712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = paddingSize - 1; 713d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (paddingSize >= 2) { 714d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 715d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, paddingSize - 2); 716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += paddingSize - 2; 717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x01; 723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->streamID(); 724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = PES_packet_length >> 8; 725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = PES_packet_length & 0xff; 726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x84; 727b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber *ptr++ = (PES_private_data_len > 0) ? 0x81 : 0x80; 728b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 72990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t headerLength = 0x05 + numStuffingBytes; 73090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (PES_private_data_len > 0) { 73190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber headerLength += 1 + PES_private_data_len; 73290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 73390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 73490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = headerLength; 735b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x20 | (((PTS >> 30) & 7) << 1) | 1; 737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PTS >> 22) & 0xff; 738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (((PTS >> 15) & 0x7f) << 1) | 1; 739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (PTS >> 7) & 0xff; 740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = ((PTS & 0x7f) << 1) | 1; 741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 742b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (PES_private_data_len > 0) { 743b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber *ptr++ = 0x8e; // PES_private_data_flag, reserved. 744b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber memcpy(ptr, PES_private_data, PES_private_data_len); 745b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber ptr += PES_private_data_len; 746b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 747b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 74890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber for (size_t i = 0; i < numStuffingBytes; ++i) { 74990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *ptr++ = 0xff; 75090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 75190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 18 bytes of TS/PES header leave 188 - 18 = 170 bytes for the payload 753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t copy = accessUnit->size(); 756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (copy > sizeLeft) { 757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber copy = sizeLeft; 758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data(), copy); 761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += copy; 762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(sizeLeft, copy); 763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft - copy); 764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = copy; 768d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (offset < accessUnit->size()) { 769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool padding = (accessUnit->size() - offset) < (188 - 4); 770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // for subsequent fragments of "buffer": 772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 0x47 773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_error_indicator = b0 774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // payload_unit_start_indicator = b0 775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_priority = b0 776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // PID = b0 0001 1110 ???? (13 bits) [0x1e0 + 1 + sourceIndex] 777d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // transport_scrambling_control = b00 778d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // adaptation_field_control = b?? 779d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // continuity_counter = b???? 780d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the fragment of "buffer" follows. 781d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 782d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *ptr = packetDataStart; 783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x47; 784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00 | (track->PID() >> 8); 785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = track->PID() & 0xff; 786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = (padding ? 0x30 : 0x10) | track->incrementContinuityCounter(); 788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (padding) { 790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t paddingSize = 188 - 4 - (accessUnit->size() - offset); 791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = paddingSize - 1; 792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (paddingSize >= 2) { 793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *ptr++ = 0x00; 794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, paddingSize - 2); 795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += paddingSize - 2; 796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 4 bytes of TS header leave 188 - 4 = 184 bytes for the payload 800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t sizeLeft = packetDataStart + 188 - ptr; 802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t copy = accessUnit->size() - offset; 803d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (copy > sizeLeft) { 804d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber copy = sizeLeft; 805d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 806d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 807d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(ptr, accessUnit->data() + offset, copy); 808d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ptr += copy; 809d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(sizeLeft, copy); 810d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memset(ptr, 0xff, sizeLeft - copy); 811d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 812d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += copy; 813d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetDataStart += 188; 814d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 815d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 816d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(packetDataStart == buffer->data() + buffer->capacity()); 817d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 818d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *packets = buffer; 819d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 821d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 822d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 823d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid TSPacketizer::initCrcTable() { 824d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t poly = 0x04C11DB7; 825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (int i = 0; i < 256; i++) { 827d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = i << 24; 828d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (int j = 0; j < 8; j++) { 829d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = (crc << 1) ^ ((crc & 0x80000000) ? (poly) : 0); 830d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 831d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mCrcTable[i] = crc; 832d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 833d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 834d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 835d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint32_t TSPacketizer::crc32(const uint8_t *start, size_t size) const { 836d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t crc = 0xFFFFFFFF; 837d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *p; 838d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 839d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (p = start; p < start + size; ++p) { 840d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber crc = (crc << 8) ^ mCrcTable[((crc >> 24) ^ *p) & 0xFF]; 841d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 842d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 843d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return crc; 844d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 845d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 846e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Hubersp<ABuffer> TSPacketizer::prependCSD( 847e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber size_t trackIndex, const sp<ABuffer> &accessUnit) const { 848e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_LT(trackIndex, mTracks.size()); 849e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 850e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber const sp<Track> &track = mTracks.itemAt(trackIndex); 851e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK(track->isH264() && IsIDR(accessUnit)); 852e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 853e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber int64_t timeUs; 854e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 855e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 856e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber sp<ABuffer> accessUnit2 = track->prependCSD(accessUnit); 857e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 858e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber accessUnit2->meta()->setInt64("timeUs", timeUs); 859e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 860e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber return accessUnit2; 861e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber} 862e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 863d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 864d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 865