1 /* 2 * Copyright 2012, 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 "PlaybackSession" 19 #include <utils/Log.h> 20 21 #include "PlaybackSession.h" 22 23 #include "Converter.h" 24 #include "MediaPuller.h" 25 #include "RepeaterSource.h" 26 #include "Sender.h" 27 #include "TSPacketizer.h" 28 #include "include/avc_utils.h" 29 30 #include <binder/IServiceManager.h> 31 #include <gui/ISurfaceComposer.h> 32 #include <gui/SurfaceComposerClient.h> 33 #include <media/IHDCP.h> 34 #include <media/stagefright/foundation/ABitReader.h> 35 #include <media/stagefright/foundation/ABuffer.h> 36 #include <media/stagefright/foundation/ADebug.h> 37 #include <media/stagefright/foundation/AMessage.h> 38 #include <media/stagefright/foundation/hexdump.h> 39 #include <media/stagefright/AudioSource.h> 40 #include <media/stagefright/DataSource.h> 41 #include <media/stagefright/MediaDefs.h> 42 #include <media/stagefright/MediaErrors.h> 43 #include <media/stagefright/MediaExtractor.h> 44 #include <media/stagefright/MediaSource.h> 45 #include <media/stagefright/MetaData.h> 46 #include <media/stagefright/MPEG2TSWriter.h> 47 #include <media/stagefright/SurfaceMediaSource.h> 48 #include <media/stagefright/Utils.h> 49 50 #include <OMX_IVCommon.h> 51 52 namespace android { 53 54 struct WifiDisplaySource::PlaybackSession::Track : public AHandler { 55 enum { 56 kWhatStopped, 57 }; 58 59 Track(const sp<AMessage> ¬ify, 60 const sp<ALooper> &pullLooper, 61 const sp<ALooper> &codecLooper, 62 const sp<MediaPuller> &mediaPuller, 63 const sp<Converter> &converter); 64 65 void setRepeaterSource(const sp<RepeaterSource> &source); 66 67 sp<AMessage> getFormat(); 68 bool isAudio() const; 69 70 const sp<Converter> &converter() const; 71 ssize_t packetizerTrackIndex() const; 72 73 void setPacketizerTrackIndex(size_t index); 74 75 status_t start(); 76 void stopAsync(); 77 78 void queueAccessUnit(const sp<ABuffer> &accessUnit); 79 sp<ABuffer> dequeueAccessUnit(); 80 81 bool hasOutputBuffer(int64_t *timeUs) const; 82 void queueOutputBuffer(const sp<ABuffer> &accessUnit); 83 sp<ABuffer> dequeueOutputBuffer(); 84 bool isSuspended() const; 85 86 size_t countQueuedOutputBuffers() const { 87 return mQueuedOutputBuffers.size(); 88 } 89 90 void requestIDRFrame(); 91 92 protected: 93 virtual void onMessageReceived(const sp<AMessage> &msg); 94 virtual ~Track(); 95 96 private: 97 enum { 98 kWhatMediaPullerStopped, 99 }; 100 101 sp<AMessage> mNotify; 102 sp<ALooper> mPullLooper; 103 sp<ALooper> mCodecLooper; 104 sp<MediaPuller> mMediaPuller; 105 sp<Converter> mConverter; 106 bool mStarted; 107 ssize_t mPacketizerTrackIndex; 108 bool mIsAudio; 109 List<sp<ABuffer> > mQueuedAccessUnits; 110 sp<RepeaterSource> mRepeaterSource; 111 List<sp<ABuffer> > mQueuedOutputBuffers; 112 int64_t mLastOutputBufferQueuedTimeUs; 113 114 static bool IsAudioFormat(const sp<AMessage> &format); 115 116 DISALLOW_EVIL_CONSTRUCTORS(Track); 117 }; 118 119 WifiDisplaySource::PlaybackSession::Track::Track( 120 const sp<AMessage> ¬ify, 121 const sp<ALooper> &pullLooper, 122 const sp<ALooper> &codecLooper, 123 const sp<MediaPuller> &mediaPuller, 124 const sp<Converter> &converter) 125 : mNotify(notify), 126 mPullLooper(pullLooper), 127 mCodecLooper(codecLooper), 128 mMediaPuller(mediaPuller), 129 mConverter(converter), 130 mStarted(false), 131 mPacketizerTrackIndex(-1), 132 mIsAudio(IsAudioFormat(mConverter->getOutputFormat())), 133 mLastOutputBufferQueuedTimeUs(-1ll) { 134 } 135 136 WifiDisplaySource::PlaybackSession::Track::~Track() { 137 CHECK(!mStarted); 138 } 139 140 // static 141 bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( 142 const sp<AMessage> &format) { 143 AString mime; 144 CHECK(format->findString("mime", &mime)); 145 146 return !strncasecmp(mime.c_str(), "audio/", 6); 147 } 148 149 sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 150 return mConverter->getOutputFormat(); 151 } 152 153 bool WifiDisplaySource::PlaybackSession::Track::isAudio() const { 154 return mIsAudio; 155 } 156 157 const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 158 return mConverter; 159 } 160 161 ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 162 return mPacketizerTrackIndex; 163 } 164 165 void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 166 CHECK_LT(mPacketizerTrackIndex, 0); 167 mPacketizerTrackIndex = index; 168 } 169 170 status_t WifiDisplaySource::PlaybackSession::Track::start() { 171 ALOGV("Track::start isAudio=%d", mIsAudio); 172 173 CHECK(!mStarted); 174 175 status_t err = OK; 176 177 if (mMediaPuller != NULL) { 178 err = mMediaPuller->start(); 179 } 180 181 if (err == OK) { 182 mStarted = true; 183 } 184 185 return err; 186 } 187 188 void WifiDisplaySource::PlaybackSession::Track::stopAsync() { 189 ALOGV("Track::stopAsync isAudio=%d", mIsAudio); 190 191 mConverter->shutdownAsync(); 192 193 sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id()); 194 195 if (mStarted && mMediaPuller != NULL) { 196 if (mRepeaterSource != NULL) { 197 // Let's unblock MediaPuller's MediaSource::read(). 198 mRepeaterSource->wakeUp(); 199 } 200 201 mMediaPuller->stopAsync(msg); 202 } else { 203 msg->post(); 204 } 205 } 206 207 void WifiDisplaySource::PlaybackSession::Track::onMessageReceived( 208 const sp<AMessage> &msg) { 209 switch (msg->what()) { 210 case kWhatMediaPullerStopped: 211 { 212 mConverter.clear(); 213 214 mStarted = false; 215 216 sp<AMessage> notify = mNotify->dup(); 217 notify->setInt32("what", kWhatStopped); 218 notify->post(); 219 220 ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video"); 221 break; 222 } 223 224 default: 225 TRESPASS(); 226 } 227 } 228 229 void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( 230 const sp<ABuffer> &accessUnit) { 231 mQueuedAccessUnits.push_back(accessUnit); 232 } 233 234 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() { 235 if (mQueuedAccessUnits.empty()) { 236 return NULL; 237 } 238 239 sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin(); 240 CHECK(accessUnit != NULL); 241 242 mQueuedAccessUnits.erase(mQueuedAccessUnits.begin()); 243 244 return accessUnit; 245 } 246 247 void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource( 248 const sp<RepeaterSource> &source) { 249 mRepeaterSource = source; 250 } 251 252 void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() { 253 if (mIsAudio) { 254 return; 255 } 256 257 if (mRepeaterSource != NULL) { 258 mRepeaterSource->wakeUp(); 259 } 260 261 mConverter->requestIDRFrame(); 262 } 263 264 bool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer( 265 int64_t *timeUs) const { 266 *timeUs = 0ll; 267 268 if (mQueuedOutputBuffers.empty()) { 269 return false; 270 } 271 272 const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin(); 273 274 CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs)); 275 276 return true; 277 } 278 279 void WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer( 280 const sp<ABuffer> &accessUnit) { 281 mQueuedOutputBuffers.push_back(accessUnit); 282 283 mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs(); 284 } 285 286 sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() { 287 CHECK(!mQueuedOutputBuffers.empty()); 288 289 sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin(); 290 mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin()); 291 292 return outputBuffer; 293 } 294 295 bool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { 296 if (!mQueuedOutputBuffers.empty()) { 297 return false; 298 } 299 300 if (mLastOutputBufferQueuedTimeUs < 0ll) { 301 // We've never seen an output buffer queued, but tracks start 302 // out live, not suspended. 303 return false; 304 } 305 306 // If we've not seen new output data for 60ms or more, we consider 307 // this track suspended for the time being. 308 return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll; 309 } 310 311 //////////////////////////////////////////////////////////////////////////////// 312 313 WifiDisplaySource::PlaybackSession::PlaybackSession( 314 const sp<ANetworkSession> &netSession, 315 const sp<AMessage> ¬ify, 316 const in_addr &interfaceAddr, 317 const sp<IHDCP> &hdcp) 318 : mNetSession(netSession), 319 mNotify(notify), 320 mInterfaceAddr(interfaceAddr), 321 mHDCP(hdcp), 322 mWeAreDead(false), 323 mLastLifesignUs(), 324 mVideoTrackIndex(-1), 325 mPrevTimeUs(-1ll), 326 mAllTracksHavePacketizerIndex(false) { 327 } 328 329 status_t WifiDisplaySource::PlaybackSession::init( 330 const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 331 Sender::TransportMode transportMode, 332 bool usePCMAudio) { 333 status_t err = setupPacketizer(usePCMAudio); 334 335 if (err != OK) { 336 return err; 337 } 338 339 sp<AMessage> notify = new AMessage(kWhatSenderNotify, id()); 340 mSender = new Sender(mNetSession, notify); 341 342 mSenderLooper = new ALooper; 343 mSenderLooper->setName("sender_looper"); 344 345 mSenderLooper->start( 346 false /* runOnCallingThread */, 347 false /* canCallJava */, 348 PRIORITY_AUDIO); 349 350 mSenderLooper->registerHandler(mSender); 351 352 err = mSender->init(clientIP, clientRtp, clientRtcp, transportMode); 353 354 if (err != OK) { 355 return err; 356 } 357 358 updateLiveness(); 359 360 return OK; 361 } 362 363 WifiDisplaySource::PlaybackSession::~PlaybackSession() { 364 } 365 366 int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 367 return mSender->getRTPPort(); 368 } 369 370 int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 371 return mLastLifesignUs; 372 } 373 374 void WifiDisplaySource::PlaybackSession::updateLiveness() { 375 mLastLifesignUs = ALooper::GetNowUs(); 376 } 377 378 status_t WifiDisplaySource::PlaybackSession::play() { 379 updateLiveness(); 380 381 return OK; 382 } 383 384 status_t WifiDisplaySource::PlaybackSession::finishPlay() { 385 // XXX Give the dongle a second to bind its sockets. 386 (new AMessage(kWhatFinishPlay, id()))->post(1000000ll); 387 return OK; 388 } 389 390 status_t WifiDisplaySource::PlaybackSession::onFinishPlay() { 391 return mSender->finishInit(); 392 } 393 394 status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { 395 mSender->scheduleSendSR(); 396 397 for (size_t i = 0; i < mTracks.size(); ++i) { 398 CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start()); 399 } 400 401 sp<AMessage> notify = mNotify->dup(); 402 notify->setInt32("what", kWhatSessionEstablished); 403 notify->post(); 404 405 return OK; 406 } 407 408 status_t WifiDisplaySource::PlaybackSession::pause() { 409 updateLiveness(); 410 411 return OK; 412 } 413 414 void WifiDisplaySource::PlaybackSession::destroyAsync() { 415 ALOGI("destroyAsync"); 416 417 for (size_t i = 0; i < mTracks.size(); ++i) { 418 mTracks.valueAt(i)->stopAsync(); 419 } 420 } 421 422 void WifiDisplaySource::PlaybackSession::onMessageReceived( 423 const sp<AMessage> &msg) { 424 switch (msg->what()) { 425 case kWhatConverterNotify: 426 { 427 if (mWeAreDead) { 428 ALOGV("dropping msg '%s' because we're dead", 429 msg->debugString().c_str()); 430 431 break; 432 } 433 434 int32_t what; 435 CHECK(msg->findInt32("what", &what)); 436 437 size_t trackIndex; 438 CHECK(msg->findSize("trackIndex", &trackIndex)); 439 440 if (what == Converter::kWhatAccessUnit) { 441 const sp<Track> &track = mTracks.valueFor(trackIndex); 442 443 ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 444 445 if (packetizerTrackIndex < 0) { 446 packetizerTrackIndex = 447 mPacketizer->addTrack(track->getFormat()); 448 449 CHECK_GE(packetizerTrackIndex, 0); 450 451 track->setPacketizerTrackIndex(packetizerTrackIndex); 452 453 if (allTracksHavePacketizerIndex()) { 454 status_t err = packetizeQueuedAccessUnits(); 455 456 if (err != OK) { 457 notifySessionDead(); 458 break; 459 } 460 } 461 } 462 463 sp<ABuffer> accessUnit; 464 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 465 466 if (!allTracksHavePacketizerIndex()) { 467 track->queueAccessUnit(accessUnit); 468 break; 469 } 470 471 track->queueOutputBuffer(accessUnit); 472 473 drainAccessUnits(); 474 break; 475 } else if (what == Converter::kWhatEOS) { 476 CHECK_EQ(what, Converter::kWhatEOS); 477 478 ALOGI("output EOS on track %d", trackIndex); 479 480 ssize_t index = mTracks.indexOfKey(trackIndex); 481 CHECK_GE(index, 0); 482 483 const sp<Converter> &converter = 484 mTracks.valueAt(index)->converter(); 485 looper()->unregisterHandler(converter->id()); 486 487 mTracks.removeItemsAt(index); 488 489 if (mTracks.isEmpty()) { 490 ALOGI("Reached EOS"); 491 } 492 } else { 493 CHECK_EQ(what, Converter::kWhatError); 494 495 status_t err; 496 CHECK(msg->findInt32("err", &err)); 497 498 ALOGE("converter signaled error %d", err); 499 500 notifySessionDead(); 501 } 502 break; 503 } 504 505 case kWhatSenderNotify: 506 { 507 int32_t what; 508 CHECK(msg->findInt32("what", &what)); 509 510 if (what == Sender::kWhatInitDone) { 511 onFinishPlay2(); 512 } else if (what == Sender::kWhatSessionDead) { 513 notifySessionDead(); 514 } else { 515 TRESPASS(); 516 } 517 518 break; 519 } 520 521 case kWhatFinishPlay: 522 { 523 onFinishPlay(); 524 break; 525 } 526 527 case kWhatTrackNotify: 528 { 529 int32_t what; 530 CHECK(msg->findInt32("what", &what)); 531 532 size_t trackIndex; 533 CHECK(msg->findSize("trackIndex", &trackIndex)); 534 535 if (what == Track::kWhatStopped) { 536 ALOGI("Track %d stopped", trackIndex); 537 538 sp<Track> track = mTracks.valueFor(trackIndex); 539 looper()->unregisterHandler(track->id()); 540 mTracks.removeItem(trackIndex); 541 track.clear(); 542 543 if (!mTracks.isEmpty()) { 544 ALOGI("not all tracks are stopped yet"); 545 break; 546 } 547 548 mSenderLooper->unregisterHandler(mSender->id()); 549 mSender.clear(); 550 mSenderLooper.clear(); 551 552 mPacketizer.clear(); 553 554 sp<AMessage> notify = mNotify->dup(); 555 notify->setInt32("what", kWhatSessionDestroyed); 556 notify->post(); 557 } 558 break; 559 } 560 561 case kWhatPacketize: 562 { 563 size_t trackIndex; 564 CHECK(msg->findSize("trackIndex", &trackIndex)); 565 566 sp<ABuffer> accessUnit; 567 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 568 569 #if 0 570 if ((ssize_t)trackIndex == mVideoTrackIndex) { 571 int64_t nowUs = ALooper::GetNowUs(); 572 static int64_t prevNowUs = 0ll; 573 574 ALOGI("sending AU, dNowUs=%lld us", nowUs - prevNowUs); 575 576 prevNowUs = nowUs; 577 } 578 #endif 579 580 break; 581 } 582 583 default: 584 TRESPASS(); 585 } 586 } 587 588 status_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) { 589 mPacketizer = new TSPacketizer; 590 591 status_t err = addVideoSource(); 592 593 if (err != OK) { 594 return err; 595 } 596 597 return addAudioSource(usePCMAudio); 598 } 599 600 status_t WifiDisplaySource::PlaybackSession::addSource( 601 bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, 602 bool usePCMAudio, size_t *numInputBuffers) { 603 CHECK(!usePCMAudio || !isVideo); 604 CHECK(!isRepeaterSource || isVideo); 605 606 sp<ALooper> pullLooper = new ALooper; 607 pullLooper->setName("pull_looper"); 608 609 pullLooper->start( 610 false /* runOnCallingThread */, 611 false /* canCallJava */, 612 PRIORITY_AUDIO); 613 614 sp<ALooper> codecLooper = new ALooper; 615 codecLooper->setName("codec_looper"); 616 617 codecLooper->start( 618 false /* runOnCallingThread */, 619 false /* canCallJava */, 620 PRIORITY_AUDIO); 621 622 size_t trackIndex; 623 624 sp<AMessage> notify; 625 626 trackIndex = mTracks.size(); 627 628 sp<AMessage> format; 629 status_t err = convertMetaDataToMessage(source->getFormat(), &format); 630 CHECK_EQ(err, (status_t)OK); 631 632 if (isVideo) { 633 format->setInt32("store-metadata-in-buffers", true); 634 635 format->setInt32( 636 "color-format", OMX_COLOR_FormatAndroidOpaque); 637 } 638 639 notify = new AMessage(kWhatConverterNotify, id()); 640 notify->setSize("trackIndex", trackIndex); 641 642 sp<Converter> converter = 643 new Converter(notify, codecLooper, format, usePCMAudio); 644 645 if (converter->initCheck() != OK) { 646 return converter->initCheck(); 647 } 648 649 looper()->registerHandler(converter); 650 651 notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id()); 652 notify->setSize("trackIndex", trackIndex); 653 654 sp<MediaPuller> puller = new MediaPuller(source, notify); 655 pullLooper->registerHandler(puller); 656 657 if (numInputBuffers != NULL) { 658 *numInputBuffers = converter->getInputBufferCount(); 659 } 660 661 notify = new AMessage(kWhatTrackNotify, id()); 662 notify->setSize("trackIndex", trackIndex); 663 664 sp<Track> track = new Track( 665 notify, pullLooper, codecLooper, puller, converter); 666 667 if (isRepeaterSource) { 668 track->setRepeaterSource(static_cast<RepeaterSource *>(source.get())); 669 } 670 671 looper()->registerHandler(track); 672 673 mTracks.add(trackIndex, track); 674 675 if (isVideo) { 676 mVideoTrackIndex = trackIndex; 677 } 678 679 return OK; 680 } 681 682 status_t WifiDisplaySource::PlaybackSession::addVideoSource() { 683 sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 684 685 source->setUseAbsoluteTimestamps(); 686 687 #if 1 688 sp<RepeaterSource> videoSource = 689 new RepeaterSource(source, 30.0 /* rateHz */); 690 #endif 691 692 #if 1 693 size_t numInputBuffers; 694 status_t err = addSource( 695 true /* isVideo */, videoSource, true /* isRepeaterSource */, 696 false /* usePCMAudio */, &numInputBuffers); 697 #else 698 size_t numInputBuffers; 699 status_t err = addSource( 700 true /* isVideo */, source, false /* isRepeaterSource */, 701 false /* usePCMAudio */, &numInputBuffers); 702 #endif 703 704 if (err != OK) { 705 return err; 706 } 707 708 err = source->setMaxAcquiredBufferCount(numInputBuffers); 709 CHECK_EQ(err, (status_t)OK); 710 711 mBufferQueue = source->getBufferQueue(); 712 713 return OK; 714 } 715 716 status_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) { 717 sp<AudioSource> audioSource = new AudioSource( 718 AUDIO_SOURCE_REMOTE_SUBMIX, 719 48000 /* sampleRate */, 720 2 /* channelCount */); 721 722 if (audioSource->initCheck() == OK) { 723 return addSource( 724 false /* isVideo */, audioSource, false /* isRepeaterSource */, 725 usePCMAudio, NULL /* numInputBuffers */); 726 } 727 728 ALOGW("Unable to instantiate audio source"); 729 730 return OK; 731 } 732 733 sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 734 return mBufferQueue; 735 } 736 737 int32_t WifiDisplaySource::PlaybackSession::width() const { 738 return 1280; 739 } 740 741 int32_t WifiDisplaySource::PlaybackSession::height() const { 742 return 720; 743 } 744 745 void WifiDisplaySource::PlaybackSession::requestIDRFrame() { 746 for (size_t i = 0; i < mTracks.size(); ++i) { 747 const sp<Track> &track = mTracks.valueAt(i); 748 749 track->requestIDRFrame(); 750 } 751 } 752 753 bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { 754 if (mAllTracksHavePacketizerIndex) { 755 return true; 756 } 757 758 for (size_t i = 0; i < mTracks.size(); ++i) { 759 if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) { 760 return false; 761 } 762 } 763 764 mAllTracksHavePacketizerIndex = true; 765 766 return true; 767 } 768 769 status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( 770 size_t trackIndex, const sp<ABuffer> &accessUnit, 771 sp<ABuffer> *packets) { 772 const sp<Track> &track = mTracks.valueFor(trackIndex); 773 774 uint32_t flags = 0; 775 776 bool isHDCPEncrypted = false; 777 uint64_t inputCTR; 778 uint8_t HDCP_private_data[16]; 779 if (mHDCP != NULL && !track->isAudio()) { 780 isHDCPEncrypted = true; 781 782 status_t err = mHDCP->encrypt( 783 accessUnit->data(), accessUnit->size(), 784 trackIndex /* streamCTR */, 785 &inputCTR, 786 accessUnit->data()); 787 788 if (err != OK) { 789 ALOGE("Failed to HDCP-encrypt media data (err %d)", 790 err); 791 792 return err; 793 } 794 795 HDCP_private_data[0] = 0x00; 796 797 HDCP_private_data[1] = 798 (((trackIndex >> 30) & 3) << 1) | 1; 799 800 HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 801 802 HDCP_private_data[3] = 803 (((trackIndex >> 15) & 0x7f) << 1) | 1; 804 805 HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 806 807 HDCP_private_data[5] = 808 ((trackIndex & 0x7f) << 1) | 1; 809 810 HDCP_private_data[6] = 0x00; 811 812 HDCP_private_data[7] = 813 (((inputCTR >> 60) & 0x0f) << 1) | 1; 814 815 HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 816 817 HDCP_private_data[9] = 818 (((inputCTR >> 45) & 0x7f) << 1) | 1; 819 820 HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 821 822 HDCP_private_data[11] = 823 (((inputCTR >> 30) & 0x7f) << 1) | 1; 824 825 HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 826 827 HDCP_private_data[13] = 828 (((inputCTR >> 15) & 0x7f) << 1) | 1; 829 830 HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 831 832 HDCP_private_data[15] = 833 ((inputCTR & 0x7f) << 1) | 1; 834 835 #if 0 836 ALOGI("HDCP_private_data:"); 837 hexdump(HDCP_private_data, sizeof(HDCP_private_data)); 838 839 ABitReader br(HDCP_private_data, sizeof(HDCP_private_data)); 840 CHECK_EQ(br.getBits(13), 0); 841 CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3); 842 CHECK_EQ(br.getBits(1), 1u); 843 CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff); 844 CHECK_EQ(br.getBits(1), 1u); 845 CHECK_EQ(br.getBits(15), trackIndex & 0x7fff); 846 CHECK_EQ(br.getBits(1), 1u); 847 CHECK_EQ(br.getBits(11), 0); 848 CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf); 849 CHECK_EQ(br.getBits(1), 1u); 850 CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff); 851 CHECK_EQ(br.getBits(1), 1u); 852 CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff); 853 CHECK_EQ(br.getBits(1), 1u); 854 CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff); 855 CHECK_EQ(br.getBits(1), 1u); 856 CHECK_EQ(br.getBits(15), inputCTR & 0x7fff); 857 CHECK_EQ(br.getBits(1), 1u); 858 #endif 859 860 flags |= TSPacketizer::IS_ENCRYPTED; 861 } 862 863 int64_t timeUs = ALooper::GetNowUs(); 864 if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 865 flags |= TSPacketizer::EMIT_PCR; 866 flags |= TSPacketizer::EMIT_PAT_AND_PMT; 867 868 mPrevTimeUs = timeUs; 869 } 870 871 mPacketizer->packetize( 872 track->packetizerTrackIndex(), accessUnit, packets, flags, 873 !isHDCPEncrypted ? NULL : HDCP_private_data, 874 !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data), 875 track->isAudio() ? 2 : 0 /* numStuffingBytes */); 876 877 return OK; 878 } 879 880 status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() { 881 for (;;) { 882 bool gotMoreData = false; 883 for (size_t i = 0; i < mTracks.size(); ++i) { 884 size_t trackIndex = mTracks.keyAt(i); 885 const sp<Track> &track = mTracks.valueAt(i); 886 887 sp<ABuffer> accessUnit = track->dequeueAccessUnit(); 888 if (accessUnit != NULL) { 889 track->queueOutputBuffer(accessUnit); 890 gotMoreData = true; 891 } 892 } 893 894 if (!gotMoreData) { 895 break; 896 } 897 } 898 899 return OK; 900 } 901 902 void WifiDisplaySource::PlaybackSession::notifySessionDead() { 903 // Inform WifiDisplaySource of our premature death (wish). 904 sp<AMessage> notify = mNotify->dup(); 905 notify->setInt32("what", kWhatSessionDead); 906 notify->post(); 907 908 mWeAreDead = true; 909 } 910 911 void WifiDisplaySource::PlaybackSession::drainAccessUnits() { 912 ALOGV("audio/video has %d/%d buffers ready.", 913 mTracks.valueFor(1)->countQueuedOutputBuffers(), 914 mTracks.valueFor(0)->countQueuedOutputBuffers()); 915 916 while (drainAccessUnit()) { 917 } 918 } 919 920 bool WifiDisplaySource::PlaybackSession::drainAccessUnit() { 921 ssize_t minTrackIndex = -1; 922 int64_t minTimeUs = -1ll; 923 924 for (size_t i = 0; i < mTracks.size(); ++i) { 925 const sp<Track> &track = mTracks.valueAt(i); 926 927 int64_t timeUs; 928 if (track->hasOutputBuffer(&timeUs)) { 929 if (minTrackIndex < 0 || timeUs < minTimeUs) { 930 minTrackIndex = mTracks.keyAt(i); 931 minTimeUs = timeUs; 932 } 933 } else if (!track->isSuspended()) { 934 // We still consider this track "live", so it should keep 935 // delivering output data whose time stamps we'll have to 936 // consider for proper interleaving. 937 return false; 938 } 939 } 940 941 if (minTrackIndex < 0) { 942 return false; 943 } 944 945 const sp<Track> &track = mTracks.valueFor(minTrackIndex); 946 sp<ABuffer> accessUnit = track->dequeueOutputBuffer(); 947 948 sp<ABuffer> packets; 949 status_t err = packetizeAccessUnit(minTrackIndex, accessUnit, &packets); 950 951 if (err != OK) { 952 notifySessionDead(); 953 } 954 955 if ((ssize_t)minTrackIndex == mVideoTrackIndex) { 956 packets->meta()->setInt32("isVideo", 1); 957 } 958 mSender->queuePackets(minTimeUs, packets); 959 960 return true; 961 } 962 963 } // namespace android 964 965