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