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