• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
36 namespace android {
37 
MediaSender(const sp<ANetworkSession> & netSession,const sp<AMessage> & notify)38 MediaSender::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 
~MediaSender()51 MediaSender::~MediaSender() {
52     if (mLogFile != NULL) {
53         fclose(mLogFile);
54         mLogFile = NULL;
55     }
56 }
57 
setHDCP(const sp<IHDCP> & hdcp)58 status_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 
addTrack(const sp<AMessage> & format,uint32_t flags)68 ssize_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 
initAsync(ssize_t trackIndex,const char * remoteHost,int32_t remoteRTPPort,RTPSender::TransportMode rtpMode,int32_t remoteRTCPPort,RTPSender::TransportMode rtcpMode,int32_t * localRTPPort)88 status_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 
queueAccessUnit(size_t trackIndex,const sp<ABuffer> & accessUnit)204 status_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 
onMessageReceived(const sp<AMessage> & msg)285 void 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 
onSenderNotify(const sp<AMessage> & msg)304 void 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 
notifyInitDone(status_t err)367 void 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 
notifyError(status_t err)374 void 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 
notifyNetworkStall(size_t numBytesQueued)381 void 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 
packetizeAccessUnit(size_t trackIndex,sp<ABuffer> accessUnit,sp<ABuffer> * tsPackets)388 status_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