MediaSender.cpp revision 3a9682a86ead84d6f60d3f3aa01b2b4d34af983d
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        const char *remoteHost,
89        int32_t remoteRTPPort,
90        RTPSender::TransportMode rtpMode,
91        int32_t remoteRTCPPort,
92        RTPSender::TransportMode rtcpMode,
93        int32_t *localRTPPort) {
94    if (trackIndex < 0) {
95        if (mMode != MODE_UNDEFINED) {
96            return INVALID_OPERATION;
97        }
98
99        uint32_t flags = 0;
100        if (mHDCP != NULL) {
101            // XXX Determine proper HDCP version.
102            flags |= TSPacketizer::EMIT_HDCP20_DESCRIPTOR;
103        }
104        mTSPacketizer = new TSPacketizer(flags);
105
106        status_t err = OK;
107        for (size_t i = 0; i < mTrackInfos.size(); ++i) {
108            TrackInfo *info = &mTrackInfos.editItemAt(i);
109
110            ssize_t packetizerTrackIndex =
111                mTSPacketizer->addTrack(info->mFormat);
112
113            if (packetizerTrackIndex < 0) {
114                err = packetizerTrackIndex;
115                break;
116            }
117
118            info->mPacketizerTrackIndex = packetizerTrackIndex;
119        }
120
121        if (err == OK) {
122            sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
123            notify->setInt32("generation", mGeneration);
124            mTSSender = new RTPSender(mNetSession, notify);
125            looper()->registerHandler(mTSSender);
126
127            err = mTSSender->initAsync(
128                    remoteHost,
129                    remoteRTPPort,
130                    rtpMode,
131                    remoteRTCPPort,
132                    rtcpMode,
133                    localRTPPort);
134
135            if (err != OK) {
136                looper()->unregisterHandler(mTSSender->id());
137                mTSSender.clear();
138            }
139        }
140
141        if (err != OK) {
142            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
143                TrackInfo *info = &mTrackInfos.editItemAt(i);
144                info->mPacketizerTrackIndex = -1;
145            }
146
147            mTSPacketizer.clear();
148            return err;
149        }
150
151        mMode = MODE_TRANSPORT_STREAM;
152        mInitDoneCount = 1;
153
154        return OK;
155    }
156
157    if (mMode == MODE_TRANSPORT_STREAM) {
158        return INVALID_OPERATION;
159    }
160
161    if ((size_t)trackIndex >= mTrackInfos.size()) {
162        return -ERANGE;
163    }
164
165    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
166
167    if (info->mSender != NULL) {
168        return INVALID_OPERATION;
169    }
170
171    sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
172    notify->setInt32("generation", mGeneration);
173    notify->setSize("trackIndex", trackIndex);
174
175    info->mSender = new RTPSender(mNetSession, notify);
176    looper()->registerHandler(info->mSender);
177
178    status_t err = info->mSender->initAsync(
179            remoteHost,
180            remoteRTPPort,
181            rtpMode,
182            remoteRTCPPort,
183            rtcpMode,
184            localRTPPort);
185
186    if (err != OK) {
187        looper()->unregisterHandler(info->mSender->id());
188        info->mSender.clear();
189
190        return err;
191    }
192
193    if (mMode == MODE_UNDEFINED) {
194        mInitDoneCount = mTrackInfos.size();
195    }
196
197    mMode = MODE_ELEMENTARY_STREAMS;
198
199    return OK;
200}
201
202status_t MediaSender::queueAccessUnit(
203        size_t trackIndex, const sp<ABuffer> &accessUnit) {
204    if (mMode == MODE_UNDEFINED) {
205        return INVALID_OPERATION;
206    }
207
208    if (trackIndex >= mTrackInfos.size()) {
209        return -ERANGE;
210    }
211
212    if (mMode == MODE_TRANSPORT_STREAM) {
213        TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
214        info->mAccessUnits.push_back(accessUnit);
215
216        mTSPacketizer->extractCSDIfNecessary(info->mPacketizerTrackIndex);
217
218        for (;;) {
219            ssize_t minTrackIndex = -1;
220            int64_t minTimeUs = -1ll;
221
222            for (size_t i = 0; i < mTrackInfos.size(); ++i) {
223                const TrackInfo &info = mTrackInfos.itemAt(i);
224
225                if (info.mAccessUnits.empty()) {
226                    minTrackIndex = -1;
227                    minTimeUs = -1ll;
228                    break;
229                }
230
231                int64_t timeUs;
232                const sp<ABuffer> &accessUnit = *info.mAccessUnits.begin();
233                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
234
235                if (minTrackIndex < 0 || timeUs < minTimeUs) {
236                    minTrackIndex = i;
237                    minTimeUs = timeUs;
238                }
239            }
240
241            if (minTrackIndex < 0) {
242                return OK;
243            }
244
245            TrackInfo *info = &mTrackInfos.editItemAt(minTrackIndex);
246            sp<ABuffer> accessUnit = *info->mAccessUnits.begin();
247            info->mAccessUnits.erase(info->mAccessUnits.begin());
248
249            sp<ABuffer> tsPackets;
250            status_t err = packetizeAccessUnit(
251                    minTrackIndex, accessUnit, &tsPackets);
252
253            if (err == OK) {
254                if (mLogFile != NULL) {
255                    fwrite(tsPackets->data(), 1, tsPackets->size(), mLogFile);
256                }
257
258                int64_t timeUs;
259                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
260                tsPackets->meta()->setInt64("timeUs", timeUs);
261
262                err = mTSSender->queueBuffer(
263                        tsPackets,
264                        33 /* packetType */,
265                        RTPSender::PACKETIZATION_TRANSPORT_STREAM);
266            }
267
268            if (err != OK) {
269                return err;
270            }
271        }
272    }
273
274    TrackInfo *info = &mTrackInfos.editItemAt(trackIndex);
275
276    return info->mSender->queueBuffer(
277            accessUnit,
278            info->mIsAudio ? 96 : 97 /* packetType */,
279            info->mIsAudio
280                ? RTPSender::PACKETIZATION_AAC : RTPSender::PACKETIZATION_H264);
281}
282
283void MediaSender::onMessageReceived(const sp<AMessage> &msg) {
284    switch (msg->what()) {
285        case kWhatSenderNotify:
286        {
287            int32_t generation;
288            CHECK(msg->findInt32("generation", &generation));
289            if (generation != mGeneration) {
290                break;
291            }
292
293            onSenderNotify(msg);
294            break;
295        }
296
297        default:
298            TRESPASS();
299    }
300}
301
302void MediaSender::onSenderNotify(const sp<AMessage> &msg) {
303    int32_t what;
304    CHECK(msg->findInt32("what", &what));
305
306    switch (what) {
307        case RTPSender::kWhatInitDone:
308        {
309            --mInitDoneCount;
310
311            int32_t err;
312            CHECK(msg->findInt32("err", &err));
313
314            if (err != OK) {
315                notifyInitDone(err);
316                ++mGeneration;
317                break;
318            }
319
320            if (mInitDoneCount == 0) {
321                notifyInitDone(OK);
322            }
323            break;
324        }
325
326        case RTPSender::kWhatError:
327        {
328            int32_t err;
329            CHECK(msg->findInt32("err", &err));
330
331            notifyError(err);
332            break;
333        }
334
335        case kWhatNetworkStall:
336        {
337            size_t numBytesQueued;
338            CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
339
340            notifyNetworkStall(numBytesQueued);
341            break;
342        }
343
344        default:
345            TRESPASS();
346    }
347}
348
349void MediaSender::notifyInitDone(status_t err) {
350    sp<AMessage> notify = mNotify->dup();
351    notify->setInt32("what", kWhatInitDone);
352    notify->setInt32("err", err);
353    notify->post();
354}
355
356void MediaSender::notifyError(status_t err) {
357    sp<AMessage> notify = mNotify->dup();
358    notify->setInt32("what", kWhatError);
359    notify->setInt32("err", err);
360    notify->post();
361}
362
363void MediaSender::notifyNetworkStall(size_t numBytesQueued) {
364    sp<AMessage> notify = mNotify->dup();
365    notify->setInt32("what", kWhatNetworkStall);
366    notify->setSize("numBytesQueued", numBytesQueued);
367    notify->post();
368}
369
370status_t MediaSender::packetizeAccessUnit(
371        size_t trackIndex,
372        sp<ABuffer> accessUnit,
373        sp<ABuffer> *tsPackets) {
374    const TrackInfo &info = mTrackInfos.itemAt(trackIndex);
375
376    uint32_t flags = 0;
377
378    bool isHDCPEncrypted = false;
379    uint64_t inputCTR;
380    uint8_t HDCP_private_data[16];
381
382    bool manuallyPrependSPSPPS =
383        !info.mIsAudio
384        && (info.mFlags & FLAG_MANUALLY_PREPEND_SPS_PPS)
385        && IsIDR(accessUnit);
386
387    if (mHDCP != NULL && !info.mIsAudio) {
388        isHDCPEncrypted = true;
389
390        if (manuallyPrependSPSPPS) {
391            accessUnit = mTSPacketizer->prependCSD(
392                    info.mPacketizerTrackIndex, accessUnit);
393        }
394
395        status_t err = mHDCP->encrypt(
396                accessUnit->data(), accessUnit->size(),
397                trackIndex  /* streamCTR */,
398                &inputCTR,
399                accessUnit->data());
400
401        if (err != OK) {
402            ALOGE("Failed to HDCP-encrypt media data (err %d)",
403                  err);
404
405            return err;
406        }
407
408        HDCP_private_data[0] = 0x00;
409
410        HDCP_private_data[1] =
411            (((trackIndex >> 30) & 3) << 1) | 1;
412
413        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
414
415        HDCP_private_data[3] =
416            (((trackIndex >> 15) & 0x7f) << 1) | 1;
417
418        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
419
420        HDCP_private_data[5] =
421            ((trackIndex & 0x7f) << 1) | 1;
422
423        HDCP_private_data[6] = 0x00;
424
425        HDCP_private_data[7] =
426            (((inputCTR >> 60) & 0x0f) << 1) | 1;
427
428        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
429
430        HDCP_private_data[9] =
431            (((inputCTR >> 45) & 0x7f) << 1) | 1;
432
433        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
434
435        HDCP_private_data[11] =
436            (((inputCTR >> 30) & 0x7f) << 1) | 1;
437
438        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
439
440        HDCP_private_data[13] =
441            (((inputCTR >> 15) & 0x7f) << 1) | 1;
442
443        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
444
445        HDCP_private_data[15] =
446            ((inputCTR & 0x7f) << 1) | 1;
447
448        flags |= TSPacketizer::IS_ENCRYPTED;
449    } else if (manuallyPrependSPSPPS) {
450        flags |= TSPacketizer::PREPEND_SPS_PPS_TO_IDR_FRAMES;
451    }
452
453    int64_t timeUs = ALooper::GetNowUs();
454    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
455        flags |= TSPacketizer::EMIT_PCR;
456        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
457
458        mPrevTimeUs = timeUs;
459    }
460
461    mTSPacketizer->packetize(
462            info.mPacketizerTrackIndex,
463            accessUnit,
464            tsPackets,
465            flags,
466            !isHDCPEncrypted ? NULL : HDCP_private_data,
467            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
468            info.mIsAudio ? 2 : 0 /* numStuffingBytes */);
469
470    return OK;
471}
472
473}  // namespace android
474
475