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 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 51 MediaSender::~MediaSender() { 52 if (mLogFile != NULL) { 53 fclose(mLogFile); 54 mLogFile = NULL; 55 } 56 } 57 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 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 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, id()); 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, id()); 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 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 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 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 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 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 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 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