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