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