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> ¬ify)
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", ¬ify)
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