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