MediaSender.cpp revision bfd79f2a8e795f304062e22756c72d995af7a0e6
1a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber/*
2a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Copyright 2013, The Android Open Source Project
3a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
4a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * you may not use this file except in compliance with the License.
6a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * You may obtain a copy of the License at
7a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
8a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber *
10a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * Unless required by applicable law or agreed to in writing, software
11a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * See the License for the specific language governing permissions and
14a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber * limitations under the License.
15a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber */
16a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
17a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber//#define LOG_NDEBUG 0
18a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#define LOG_TAG "MediaSender"
19a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <utils/Log.h>
20a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
21a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "MediaSender.h"
22a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
23a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "ANetworkSession.h"
24a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "rtp/RTPSender.h"
25a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "source/TSPacketizer.h"
26a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
27a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include "include/avc_utils.h"
28a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
29a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/IHDCP.h>
30a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
31a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/ADebug.h>
32a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber#include <media/stagefright/foundation/AMessage.h>
33a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
34a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubernamespace android {
35a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
36a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberMediaSender::MediaSender(
37a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<ANetworkSession> &netSession,
38a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const sp<AMessage> &notify)
39a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    : mNetSession(netSession),
40a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mNotify(notify),
41a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mMode(MODE_UNDEFINED),
42a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mGeneration(0),
43a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mPrevTimeUs(-1ll),
44bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber      mInitDoneCount(0),
45bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber      mLogFile(NULL) {
46bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber    // mLogFile = fopen("/data/misc/log.ts", "wb");
47a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
48a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
49a556c4822fc205db0d27834ba5b637c351d73ffaAndreas HuberMediaSender::~MediaSender() {
50bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber    if (mLogFile != NULL) {
51bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        fclose(mLogFile);
52bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        mLogFile = NULL;
53bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber    }
54a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
55a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
56a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::setHDCP(const sp<IHDCP> &hdcp) {
57a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode != MODE_UNDEFINED) {
58a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
59a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
60a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
61a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mHDCP = hdcp;
62a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
63a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
64a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
65a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
66a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberssize_t MediaSender::addTrack(const sp<AMessage> &format, uint32_t flags) {
67a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode != MODE_UNDEFINED) {
68a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
69a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
70a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
71a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    TrackInfo info;
72a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    info.mFormat = format;
73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    info.mFlags = flags;
74a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    info.mPacketizerTrackIndex = -1;
75a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
76a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    AString mime;
77a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK(format->findString("mime", &mime));
78a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    info.mIsAudio = !strncasecmp("audio/", mime.c_str(), 6);
79a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
80a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    size_t index = mTrackInfos.size();
81a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mTrackInfos.push_back(info);
82a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
83a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return index;
84a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
85a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
86a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::initAsync(
87a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        ssize_t trackIndex,
88a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        RTPSender::TransportMode transportMode,
89a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        const char *remoteHost,
90a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t remoteRTPPort,
91a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t remoteRTCPPort,
92a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        int32_t *localRTPPort) {
93a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (trackIndex < 0) {
94a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (mMode != MODE_UNDEFINED) {
95a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return INVALID_OPERATION;
96a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
97a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
98bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        uint32_t flags = 0;
99bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        if (mHDCP != NULL) {
100bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber            // XXX Determine proper HDCP version.
101bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber            flags |= TSPacketizer::EMIT_HDCP20_DESCRIPTOR;
102bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        }
103bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber        mTSPacketizer = new TSPacketizer(flags);
104a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
105a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        status_t err = OK;
106a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        for (size_t i = 0; i < mTrackInfos.size(); ++i) {
107a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TrackInfo *info = &mTrackInfos.editItemAt(i);
108a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
109a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ssize_t packetizerTrackIndex =
110bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber                mTSPacketizer->addTrack(info->mFormat);
111a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
112a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (packetizerTrackIndex < 0) {
113a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                err = packetizerTrackIndex;
114a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
115a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
116a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
117a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info->mPacketizerTrackIndex = packetizerTrackIndex;
118a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
119a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
120a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err == OK) {
121a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
122a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            notify->setInt32("generation", mGeneration);
123a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            mTSSender = new RTPSender(mNetSession, notify);
124a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            looper()->registerHandler(mTSSender);
125a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
126a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            err = mTSSender->initAsync(
127a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    transportMode,
128a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteHost,
129a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTPPort,
130a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    remoteRTCPPort,
131a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    localRTPPort);
132a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
133a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (err != OK) {
134a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                looper()->unregisterHandler(mTSSender->id());
135a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mTSSender.clear();
136a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
137a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
138a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
139a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err != OK) {
140a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
141a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                TrackInfo *info = &mTrackInfos.editItemAt(i);
142a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                info->mPacketizerTrackIndex = -1;
143a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
144a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
145a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            mTSPacketizer.clear();
146a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return err;
147a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
148a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
149a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mMode = MODE_TRANSPORT_STREAM;
150a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mInitDoneCount = 1;
151a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
152a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return OK;
153a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
154a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
155a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode == MODE_TRANSPORT_STREAM) {
156a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
157a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
158a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
159a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if ((size_t)trackIndex >= mTrackInfos.size()) {
160a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return -ERANGE;
161a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
162a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
163a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
164a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
165a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (info->mSender != NULL) {
166a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
167a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
168a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
169a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
170a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("generation", mGeneration);
171a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setSize("trackIndex", trackIndex);
172a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
173a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    info->mSender = new RTPSender(mNetSession, notify);
174a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    looper()->registerHandler(info->mSender);
175a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
176a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    status_t err = info->mSender->initAsync(
177a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            transportMode,
178a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            remoteHost,
179a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            remoteRTPPort,
180a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            remoteRTCPPort,
181a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            localRTPPort);
182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err != OK) {
184a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        looper()->unregisterHandler(info->mSender->id());
185a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        info->mSender.clear();
186a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return err;
188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
189a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
190a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode == MODE_UNDEFINED) {
191a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mInitDoneCount = mTrackInfos.size();
192a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
193a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
194a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMode = MODE_ELEMENTARY_STREAMS;
195a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
196a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
197a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
198a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
199a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::queueAccessUnit(
200a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t trackIndex, const sp<ABuffer> &accessUnit) {
201a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode == MODE_UNDEFINED) {
202a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return INVALID_OPERATION;
203a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
204a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
205a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (trackIndex >= mTrackInfos.size()) {
206a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        return -ERANGE;
207a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
208a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
209a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mMode == MODE_TRANSPORT_STREAM) {
210a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
211a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        info->mAccessUnits.push_back(accessUnit);
212a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
213a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mTSPacketizer->extractCSDIfNecessary(info->mPacketizerTrackIndex);
214a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
215a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        for (;;) {
216a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ssize_t minTrackIndex = -1;
217a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int64_t minTimeUs = -1ll;
218a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
219a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
220a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                const TrackInfo &info = mTrackInfos.itemAt(i);
221a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
222a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (info.mAccessUnits.empty()) {
223a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    minTrackIndex = -1;
224a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    minTimeUs = -1ll;
225a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    break;
226a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
227a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
228a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                int64_t timeUs;
229a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                const sp<ABuffer> &accessUnit = *info.mAccessUnits.begin();
230a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
231a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
232a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (minTrackIndex < 0 || timeUs < minTimeUs) {
233a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    minTrackIndex = i;
234a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    minTimeUs = timeUs;
235a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
236a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
237a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
238a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (minTrackIndex < 0) {
239a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                return OK;
240a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
241a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
242a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TrackInfo *info = &mTrackInfos.editItemAt(minTrackIndex);
243a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            sp<ABuffer> accessUnit = *info->mAccessUnits.begin();
244a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info->mAccessUnits.erase(info->mAccessUnits.begin());
245a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
246a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            sp<ABuffer> tsPackets;
247a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            status_t err = packetizeAccessUnit(
248a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    minTrackIndex, accessUnit, &tsPackets);
249a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
250a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (err == OK) {
251bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber                if (mLogFile != NULL) {
252bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber                    fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile);
253bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber                }
254bfd79f2a8e795f304062e22756c72d995af7a0e6Andreas Huber
255a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                err = mTSSender->queueBuffer(
256a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        tsPackets,
257a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        33 /* packetType */,
258a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        RTPSender::PACKETIZATION_TRANSPORT_STREAM);
259a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
260a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
261a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (err != OK) {
262a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                return err;
263a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
264a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
265a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
266a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
267a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
268a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
269a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return info->mSender->queueBuffer(
270a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            accessUnit,
271a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info->mIsAudio ? 96 : 97 /* packetType */,
272a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info->mIsAudio
273a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ? RTPSender::PACKETIZATION_AAC : RTPSender::PACKETIZATION_H264);
274a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
275a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
276a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::onMessageReceived(const sp<AMessage> &msg) {
277a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    switch (msg->what()) {
278a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case kWhatSenderNotify:
279a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
280a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t generation;
281a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("generation", &generation));
282a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (generation != mGeneration) {
283a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
284a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
285a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
286a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            onSenderNotify(msg);
287a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
288a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
289a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
290a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        default:
291a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TRESPASS();
292a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
293a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
294a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
295a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::onSenderNotify(const sp<AMessage> &msg) {
296a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    int32_t what;
297a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK(msg->findInt32("what", &what));
298a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
299a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    switch (what) {
300a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case RTPSender::kWhatInitDone:
301a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
302a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            --mInitDoneCount;
303a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
304a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t err;
305a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("err", &err));
306a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
307a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (err != OK) {
308a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                notifyInitDone(err);
309a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                ++mGeneration;
310a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                break;
311a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
312a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
313a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (mInitDoneCount == 0) {
314a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                notifyInitDone(OK);
315a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            }
316a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
317a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
318a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
319a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case RTPSender::kWhatError:
320a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        {
321a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            int32_t err;
322a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            CHECK(msg->findInt32("err", &err));
323a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
324a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            notifyError(err);
325a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            break;
326a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
327a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
328a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        default:
329a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            TRESPASS();
330a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
331a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
332a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
333a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::notifyInitDone(status_t err) {
334a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = mNotify->dup();
335a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("what", kWhatInitDone);
336a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("err", err);
337a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->post();
338a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
339a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
340a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid MediaSender::notifyError(status_t err) {
341a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = mNotify->dup();
342a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("what", kWhatError);
343a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->setInt32("err", err);
344a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    notify->post();
345a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
346a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
347a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t MediaSender::packetizeAccessUnit(
348a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t trackIndex,
349a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        sp<ABuffer> accessUnit,
350a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        sp<ABuffer> *tsPackets) {
351a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    const TrackInfo &info = mTrackInfos.itemAt(trackIndex);
352a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
353a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint32_t flags = 0;
354a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
355a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    bool isHDCPEncrypted = false;
356a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint64_t inputCTR;
357a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint8_t HDCP_private_data[16];
358a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
359a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    bool manuallyPrependSPSPPS =
360a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        !info.mIsAudio
361a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS)
362a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        && IsIDR(accessUnit);
363a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
364a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mHDCP != NULL && !info.mIsAudio) {
365a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        isHDCPEncrypted = true;
366a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
367a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (manuallyPrependSPSPPS) {
368a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            accessUnit = mTSPacketizer->prependCSD(
369a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    info.mPacketizerTrackIndex, accessUnit);
370a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
371a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
372a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        status_t err = mHDCP->encrypt(
373a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                accessUnit->data(), accessUnit->size(),
374a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                trackIndex  /* streamCTR */,
375a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                &inputCTR,
376a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                accessUnit->data());
377a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
378a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        if (err != OK) {
379a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ALOGE("Failed to HDCP-encrypt media data (err %d)",
380a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                  err);
381a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
382a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            return err;
383a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        }
384a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
385a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[0] = 0x00;
386a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
387a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[1] =
388a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((trackIndex >> 30) & 3) << 1) | 1;
389a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
390a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
391a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
392a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[3] =
393a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((trackIndex >> 15) & 0x7f) << 1) | 1;
394a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
395a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
396a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
397a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[5] =
398a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ((trackIndex & 0x7f) << 1) | 1;
399a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
400a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[6] = 0x00;
401a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
402a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[7] =
403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((inputCTR >> 60) & 0x0f) << 1) | 1;
404a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
405a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
406a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
407a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[9] =
408a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((inputCTR >> 45) & 0x7f) << 1) | 1;
409a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
411a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
412a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[11] =
413a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((inputCTR >> 30) & 0x7f) << 1) | 1;
414a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
415a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
416a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
417a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[13] =
418a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            (((inputCTR >> 15) & 0x7f) << 1) | 1;
419a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
420a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
421a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
422a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        HDCP_private_data[15] =
423a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            ((inputCTR & 0x7f) << 1) | 1;
424a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
425a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= TSPacketizer::IS_ENCRYPTED;
426a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    } else if (manuallyPrependSPSPPS) {
427a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
428a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
429a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
430a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    int64_t timeUs = ALooper::GetNowUs();
431a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
432a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= TSPacketizer::EMIT_PCR;
433a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
434a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
435a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mPrevTimeUs = timeUs;
436a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
437a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
438a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mTSPacketizer->packetize(
439a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info.mPacketizerTrackIndex,
440a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            accessUnit,
441a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            tsPackets,
442a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            flags,
443a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            !isHDCPEncrypted ? NULL : HDCP_private_data,
444a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
445a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            info.mIsAudio ? 2 : 0 /* numStuffingBytes */);
446a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
447a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return OK;
448a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}
449a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
450a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber}  // namespace android
451a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
452