PlaybackSession.cpp revision 4a114f03a79e157cab9396f986ef947df2255f1d
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 "TSPacketizer.h" 27#include "include/avc_utils.h" 28 29#include <binder/IServiceManager.h> 30#include <gui/ISurfaceComposer.h> 31#include <gui/SurfaceComposerClient.h> 32#include <media/IHDCP.h> 33#include <media/stagefright/foundation/ABitReader.h> 34#include <media/stagefright/foundation/ABuffer.h> 35#include <media/stagefright/foundation/ADebug.h> 36#include <media/stagefright/foundation/AMessage.h> 37#include <media/stagefright/foundation/hexdump.h> 38#include <media/stagefright/AudioSource.h> 39#include <media/stagefright/DataSource.h> 40#include <media/stagefright/MediaDefs.h> 41#include <media/stagefright/MediaErrors.h> 42#include <media/stagefright/MediaExtractor.h> 43#include <media/stagefright/MediaSource.h> 44#include <media/stagefright/MetaData.h> 45#include <media/stagefright/MPEG2TSWriter.h> 46#include <media/stagefright/SurfaceMediaSource.h> 47#include <media/stagefright/Utils.h> 48 49#include <OMX_IVCommon.h> 50 51namespace android { 52 53static size_t kMaxRTPPacketSize = 1500; 54static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; 55 56struct WifiDisplaySource::PlaybackSession::Track : public AHandler { 57 enum { 58 kWhatStopped, 59 }; 60 61 Track(const sp<AMessage> ¬ify, 62 const sp<ALooper> &pullLooper, 63 const sp<ALooper> &codecLooper, 64 const sp<MediaPuller> &mediaPuller, 65 const sp<Converter> &converter); 66 67 void setRepeaterSource(const sp<RepeaterSource> &source); 68 69 sp<AMessage> getFormat(); 70 bool isAudio() const; 71 72 const sp<Converter> &converter() const; 73 ssize_t packetizerTrackIndex() const; 74 75 void setPacketizerTrackIndex(size_t index); 76 77 status_t start(); 78 void stopAsync(); 79 80 void queueAccessUnit(const sp<ABuffer> &accessUnit); 81 sp<ABuffer> dequeueAccessUnit(); 82 83 void requestIDRFrame(); 84 85protected: 86 virtual void onMessageReceived(const sp<AMessage> &msg); 87 virtual ~Track(); 88 89private: 90 enum { 91 kWhatMediaPullerStopped, 92 }; 93 94 sp<AMessage> mNotify; 95 sp<ALooper> mPullLooper; 96 sp<ALooper> mCodecLooper; 97 sp<MediaPuller> mMediaPuller; 98 sp<Converter> mConverter; 99 bool mStarted; 100 ssize_t mPacketizerTrackIndex; 101 bool mIsAudio; 102 List<sp<ABuffer> > mQueuedAccessUnits; 103 sp<RepeaterSource> mRepeaterSource; 104 105 static bool IsAudioFormat(const sp<AMessage> &format); 106 107 DISALLOW_EVIL_CONSTRUCTORS(Track); 108}; 109 110WifiDisplaySource::PlaybackSession::Track::Track( 111 const sp<AMessage> ¬ify, 112 const sp<ALooper> &pullLooper, 113 const sp<ALooper> &codecLooper, 114 const sp<MediaPuller> &mediaPuller, 115 const sp<Converter> &converter) 116 : mNotify(notify), 117 mPullLooper(pullLooper), 118 mCodecLooper(codecLooper), 119 mMediaPuller(mediaPuller), 120 mConverter(converter), 121 mStarted(false), 122 mPacketizerTrackIndex(-1), 123 mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) { 124} 125 126WifiDisplaySource::PlaybackSession::Track::~Track() { 127 CHECK(!mStarted); 128} 129 130// static 131bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( 132 const sp<AMessage> &format) { 133 AString mime; 134 CHECK(format->findString("mime", &mime)); 135 136 return !strncasecmp(mime.c_str(), "audio/", 6); 137} 138 139sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 140 return mConverter->getOutputFormat(); 141} 142 143bool WifiDisplaySource::PlaybackSession::Track::isAudio() const { 144 return mIsAudio; 145} 146 147const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 148 return mConverter; 149} 150 151ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 152 return mPacketizerTrackIndex; 153} 154 155void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 156 CHECK_LT(mPacketizerTrackIndex, 0); 157 mPacketizerTrackIndex = index; 158} 159 160status_t WifiDisplaySource::PlaybackSession::Track::start() { 161 ALOGV("Track::start isAudio=%d", mIsAudio); 162 163 CHECK(!mStarted); 164 165 status_t err = OK; 166 167 if (mMediaPuller != NULL) { 168 err = mMediaPuller->start(); 169 } 170 171 if (err == OK) { 172 mStarted = true; 173 } 174 175 return err; 176} 177 178void WifiDisplaySource::PlaybackSession::Track::stopAsync() { 179 ALOGV("Track::stopAsync isAudio=%d", mIsAudio); 180 181 mConverter->shutdownAsync(); 182 183 sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id()); 184 185 if (mStarted && mMediaPuller != NULL) { 186 if (mRepeaterSource != NULL) { 187 // Let's unblock MediaPuller's MediaSource::read(). 188 mRepeaterSource->wakeUp(); 189 } 190 191 mMediaPuller->stopAsync(msg); 192 } else { 193 msg->post(); 194 } 195} 196 197void WifiDisplaySource::PlaybackSession::Track::onMessageReceived( 198 const sp<AMessage> &msg) { 199 switch (msg->what()) { 200 case kWhatMediaPullerStopped: 201 { 202 mConverter.clear(); 203 204 mStarted = false; 205 206 sp<AMessage> notify = mNotify->dup(); 207 notify->setInt32("what", kWhatStopped); 208 notify->post(); 209 210 ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video"); 211 break; 212 } 213 214 default: 215 TRESPASS(); 216 } 217} 218 219void WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( 220 const sp<ABuffer> &accessUnit) { 221 mQueuedAccessUnits.push_back(accessUnit); 222} 223 224sp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() { 225 if (mQueuedAccessUnits.empty()) { 226 return NULL; 227 } 228 229 sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin(); 230 CHECK(accessUnit != NULL); 231 232 mQueuedAccessUnits.erase(mQueuedAccessUnits.begin()); 233 234 return accessUnit; 235} 236 237void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource( 238 const sp<RepeaterSource> &source) { 239 mRepeaterSource = source; 240} 241 242void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() { 243 if (mIsAudio) { 244 return; 245 } 246 247 if (mRepeaterSource != NULL) { 248 mRepeaterSource->wakeUp(); 249 } 250 251 mConverter->requestIDRFrame(); 252} 253 254//////////////////////////////////////////////////////////////////////////////// 255 256WifiDisplaySource::PlaybackSession::PlaybackSession( 257 const sp<ANetworkSession> &netSession, 258 const sp<AMessage> ¬ify, 259 const in_addr &interfaceAddr, 260 const sp<IHDCP> &hdcp) 261 : mNetSession(netSession), 262 mNotify(notify), 263 mInterfaceAddr(interfaceAddr), 264 mHDCP(hdcp), 265 mWeAreDead(false), 266 mLastLifesignUs(), 267 mVideoTrackIndex(-1), 268 mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), 269 mPrevTimeUs(-1ll), 270 mTransportMode(TRANSPORT_UDP), 271 mAllTracksHavePacketizerIndex(false), 272 mRTPChannel(0), 273 mRTCPChannel(0), 274 mRTPPort(0), 275 mRTPSessionID(0), 276 mRTCPSessionID(0), 277#if ENABLE_RETRANSMISSION 278 mRTPRetransmissionSessionID(0), 279 mRTCPRetransmissionSessionID(0), 280#endif 281 mClientRTPPort(0), 282 mClientRTCPPort(0), 283 mRTPConnected(false), 284 mRTCPConnected(false), 285 mRTPSeqNo(0), 286#if ENABLE_RETRANSMISSION 287 mRTPRetransmissionSeqNo(0), 288#endif 289 mLastNTPTime(0), 290 mLastRTPTime(0), 291 mNumRTPSent(0), 292 mNumRTPOctetsSent(0), 293 mNumSRsSent(0), 294 mSendSRPending(false) 295#if ENABLE_RETRANSMISSION 296 ,mHistoryLength(0) 297#endif 298#if TRACK_BANDWIDTH 299 ,mFirstPacketTimeUs(-1ll) 300 ,mTotalBytesSent(0ll) 301#endif 302#if LOG_TRANSPORT_STREAM 303 ,mLogFile(NULL) 304#endif 305{ 306 mTSQueue->setRange(0, 12); 307 308#if LOG_TRANSPORT_STREAM 309 mLogFile = fopen("/system/etc/log.ts", "wb"); 310#endif 311} 312 313status_t WifiDisplaySource::PlaybackSession::init( 314 const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 315 TransportMode transportMode) { 316 mClientIP = clientIP; 317 318 status_t err = setupPacketizer(); 319 320 if (err != OK) { 321 return err; 322 } 323 324 mTransportMode = transportMode; 325 326 if (transportMode == TRANSPORT_TCP_INTERLEAVED) { 327 mRTPChannel = clientRtp; 328 mRTCPChannel = clientRtcp; 329 mRTPPort = 0; 330 mRTPSessionID = 0; 331 mRTCPSessionID = 0; 332 333 updateLiveness(); 334 return OK; 335 } 336 337 mRTPChannel = 0; 338 mRTCPChannel = 0; 339 340 if (mTransportMode == TRANSPORT_TCP) { 341 // XXX This is wrong, we need to allocate sockets here, we only 342 // need to do this because the dongles are not establishing their 343 // end until after PLAY instead of before SETUP. 344 mRTPPort = 20000; 345 mRTPSessionID = 0; 346 mRTCPSessionID = 0; 347 mClientRTPPort = clientRtp; 348 mClientRTCPPort = clientRtcp; 349 350 updateLiveness(); 351 return OK; 352 } 353 354 int serverRtp; 355 356 sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 357 sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 358 359#if ENABLE_RETRANSMISSION 360 sp<AMessage> rtpRetransmissionNotify = 361 new AMessage(kWhatRTPRetransmissionNotify, id()); 362 363 sp<AMessage> rtcpRetransmissionNotify = 364 new AMessage(kWhatRTCPRetransmissionNotify, id()); 365#endif 366 367 for (serverRtp = 15550;; serverRtp += 2) { 368 int32_t rtpSession; 369 if (mTransportMode == TRANSPORT_UDP) { 370 err = mNetSession->createUDPSession( 371 serverRtp, clientIP, clientRtp, 372 rtpNotify, &rtpSession); 373 } else { 374 err = mNetSession->createTCPDatagramSession( 375 serverRtp, clientIP, clientRtp, 376 rtpNotify, &rtpSession); 377 } 378 379 if (err != OK) { 380 ALOGI("failed to create RTP socket on port %d", serverRtp); 381 continue; 382 } 383 384 int32_t rtcpSession = 0; 385 386 if (clientRtcp >= 0) { 387 if (mTransportMode == TRANSPORT_UDP) { 388 err = mNetSession->createUDPSession( 389 serverRtp + 1, clientIP, clientRtcp, 390 rtcpNotify, &rtcpSession); 391 } else { 392 err = mNetSession->createTCPDatagramSession( 393 serverRtp + 1, clientIP, clientRtcp, 394 rtcpNotify, &rtcpSession); 395 } 396 397 if (err != OK) { 398 ALOGI("failed to create RTCP socket on port %d", serverRtp + 1); 399 400 mNetSession->destroySession(rtpSession); 401 continue; 402 } 403 } 404 405#if ENABLE_RETRANSMISSION 406 if (mTransportMode == TRANSPORT_UDP) { 407 int32_t rtpRetransmissionSession; 408 409 err = mNetSession->createUDPSession( 410 serverRtp + kRetransmissionPortOffset, 411 clientIP, 412 clientRtp + kRetransmissionPortOffset, 413 rtpRetransmissionNotify, 414 &rtpRetransmissionSession); 415 416 if (err != OK) { 417 mNetSession->destroySession(rtcpSession); 418 mNetSession->destroySession(rtpSession); 419 continue; 420 } 421 422 CHECK_GE(clientRtcp, 0); 423 424 int32_t rtcpRetransmissionSession; 425 err = mNetSession->createUDPSession( 426 serverRtp + 1 + kRetransmissionPortOffset, 427 clientIP, 428 clientRtp + 1 + kRetransmissionPortOffset, 429 rtcpRetransmissionNotify, 430 &rtcpRetransmissionSession); 431 432 if (err != OK) { 433 mNetSession->destroySession(rtpRetransmissionSession); 434 mNetSession->destroySession(rtcpSession); 435 mNetSession->destroySession(rtpSession); 436 continue; 437 } 438 439 mRTPRetransmissionSessionID = rtpRetransmissionSession; 440 mRTCPRetransmissionSessionID = rtcpRetransmissionSession; 441 442 ALOGI("rtpRetransmissionSessionID = %d, " 443 "rtcpRetransmissionSessionID = %d", 444 rtpRetransmissionSession, rtcpRetransmissionSession); 445 } 446#endif 447 448 mRTPPort = serverRtp; 449 mRTPSessionID = rtpSession; 450 mRTCPSessionID = rtcpSession; 451 452 ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession); 453 break; 454 } 455 456 if (mRTPPort == 0) { 457 return UNKNOWN_ERROR; 458 } 459 460 updateLiveness(); 461 462 return OK; 463} 464 465WifiDisplaySource::PlaybackSession::~PlaybackSession() { 466#if LOG_TRANSPORT_STREAM 467 if (mLogFile != NULL) { 468 fclose(mLogFile); 469 mLogFile = NULL; 470 } 471#endif 472} 473 474int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 475 return mRTPPort; 476} 477 478int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 479 return mLastLifesignUs; 480} 481 482void WifiDisplaySource::PlaybackSession::updateLiveness() { 483 mLastLifesignUs = ALooper::GetNowUs(); 484} 485 486status_t WifiDisplaySource::PlaybackSession::play() { 487 updateLiveness(); 488 489 return OK; 490} 491 492status_t WifiDisplaySource::PlaybackSession::finishPlay() { 493 // XXX Give the dongle a second to bind its sockets. 494 (new AMessage(kWhatFinishPlay, id()))->post(1000000ll); 495 return OK; 496} 497 498status_t WifiDisplaySource::PlaybackSession::onFinishPlay() { 499 if (mTransportMode != TRANSPORT_TCP) { 500 return onFinishPlay2(); 501 } 502 503 sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 504 505 status_t err = mNetSession->createTCPDatagramSession( 506 mRTPPort, mClientIP.c_str(), mClientRTPPort, 507 rtpNotify, &mRTPSessionID); 508 509 if (err != OK) { 510 return err; 511 } 512 513 if (mClientRTCPPort >= 0) { 514 sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 515 516 err = mNetSession->createTCPDatagramSession( 517 mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort, 518 rtcpNotify, &mRTCPSessionID); 519 } 520 521 return err; 522} 523 524status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { 525 if (mRTCPSessionID != 0) { 526 scheduleSendSR(); 527 } 528 529 for (size_t i = 0; i < mTracks.size(); ++i) { 530 CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start()); 531 } 532 533 sp<AMessage> notify = mNotify->dup(); 534 notify->setInt32("what", kWhatSessionEstablished); 535 notify->post(); 536 537 return OK; 538} 539 540status_t WifiDisplaySource::PlaybackSession::pause() { 541 updateLiveness(); 542 543 return OK; 544} 545 546void WifiDisplaySource::PlaybackSession::destroyAsync() { 547 ALOGI("destroyAsync"); 548 549 for (size_t i = 0; i < mTracks.size(); ++i) { 550 mTracks.valueAt(i)->stopAsync(); 551 } 552} 553 554void WifiDisplaySource::PlaybackSession::onMessageReceived( 555 const sp<AMessage> &msg) { 556 switch (msg->what()) { 557 case kWhatRTPNotify: 558 case kWhatRTCPNotify: 559#if ENABLE_RETRANSMISSION 560 case kWhatRTPRetransmissionNotify: 561 case kWhatRTCPRetransmissionNotify: 562#endif 563 { 564 int32_t reason; 565 CHECK(msg->findInt32("reason", &reason)); 566 567 switch (reason) { 568 case ANetworkSession::kWhatError: 569 { 570 int32_t sessionID; 571 CHECK(msg->findInt32("sessionID", &sessionID)); 572 573 int32_t err; 574 CHECK(msg->findInt32("err", &err)); 575 576 int32_t errorOccuredDuringSend; 577 CHECK(msg->findInt32("send", &errorOccuredDuringSend)); 578 579 AString detail; 580 CHECK(msg->findString("detail", &detail)); 581 582 if ((msg->what() == kWhatRTPNotify 583#if ENABLE_RETRANSMISSION 584 || msg->what() == kWhatRTPRetransmissionNotify 585#endif 586 ) && !errorOccuredDuringSend) { 587 // This is ok, we don't expect to receive anything on 588 // the RTP socket. 589 break; 590 } 591 592 ALOGE("An error occurred during %s in session %d " 593 "(%d, '%s' (%s)).", 594 errorOccuredDuringSend ? "send" : "receive", 595 sessionID, 596 err, 597 detail.c_str(), 598 strerror(-err)); 599 600 mNetSession->destroySession(sessionID); 601 602 if (sessionID == mRTPSessionID) { 603 mRTPSessionID = 0; 604 } else if (sessionID == mRTCPSessionID) { 605 mRTCPSessionID = 0; 606 } 607#if ENABLE_RETRANSMISSION 608 else if (sessionID == mRTPRetransmissionSessionID) { 609 mRTPRetransmissionSessionID = 0; 610 } else if (sessionID == mRTCPRetransmissionSessionID) { 611 mRTCPRetransmissionSessionID = 0; 612 } 613#endif 614 615 notifySessionDead(); 616 break; 617 } 618 619 case ANetworkSession::kWhatDatagram: 620 { 621 int32_t sessionID; 622 CHECK(msg->findInt32("sessionID", &sessionID)); 623 624 sp<ABuffer> data; 625 CHECK(msg->findBuffer("data", &data)); 626 627 status_t err; 628 if (msg->what() == kWhatRTCPNotify 629#if ENABLE_RETRANSMISSION 630 || msg->what() == kWhatRTCPRetransmissionNotify 631#endif 632 ) 633 { 634 err = parseRTCP(data); 635 } 636 break; 637 } 638 639 case ANetworkSession::kWhatConnected: 640 { 641 CHECK_EQ(mTransportMode, TRANSPORT_TCP); 642 643 int32_t sessionID; 644 CHECK(msg->findInt32("sessionID", &sessionID)); 645 646 if (sessionID == mRTPSessionID) { 647 CHECK(!mRTPConnected); 648 mRTPConnected = true; 649 ALOGI("RTP Session now connected."); 650 } else if (sessionID == mRTCPSessionID) { 651 CHECK(!mRTCPConnected); 652 mRTCPConnected = true; 653 ALOGI("RTCP Session now connected."); 654 } else { 655 TRESPASS(); 656 } 657 658 if (mRTPConnected 659 && (mClientRTCPPort < 0 || mRTCPConnected)) { 660 onFinishPlay2(); 661 } 662 break; 663 } 664 665 default: 666 TRESPASS(); 667 } 668 break; 669 } 670 671 case kWhatSendSR: 672 { 673 mSendSRPending = false; 674 675 if (mRTCPSessionID == 0) { 676 break; 677 } 678 679 onSendSR(); 680 681 scheduleSendSR(); 682 break; 683 } 684 685 case kWhatConverterNotify: 686 { 687 if (mWeAreDead) { 688 ALOGV("dropping msg '%s' because we're dead", 689 msg->debugString().c_str()); 690 691 break; 692 } 693 694 int32_t what; 695 CHECK(msg->findInt32("what", &what)); 696 697 size_t trackIndex; 698 CHECK(msg->findSize("trackIndex", &trackIndex)); 699 700 if (what == Converter::kWhatAccessUnit) { 701 const sp<Track> &track = mTracks.valueFor(trackIndex); 702 703 ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 704 705 if (packetizerTrackIndex < 0) { 706 packetizerTrackIndex = 707 mPacketizer->addTrack(track->getFormat()); 708 709 CHECK_GE(packetizerTrackIndex, 0); 710 711 track->setPacketizerTrackIndex(packetizerTrackIndex); 712 713 if (allTracksHavePacketizerIndex()) { 714 status_t err = packetizeQueuedAccessUnits(); 715 716 if (err != OK) { 717 notifySessionDead(); 718 break; 719 } 720 } 721 } 722 723 sp<ABuffer> accessUnit; 724 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 725 726 if (!allTracksHavePacketizerIndex()) { 727 track->queueAccessUnit(accessUnit); 728 break; 729 } 730 731 status_t err = packetizeAccessUnit(trackIndex, accessUnit); 732 733 if (err != OK) { 734 notifySessionDead(); 735 } 736 break; 737 } else if (what == Converter::kWhatEOS) { 738 CHECK_EQ(what, Converter::kWhatEOS); 739 740 ALOGI("output EOS on track %d", trackIndex); 741 742 ssize_t index = mTracks.indexOfKey(trackIndex); 743 CHECK_GE(index, 0); 744 745 const sp<Converter> &converter = 746 mTracks.valueAt(index)->converter(); 747 looper()->unregisterHandler(converter->id()); 748 749 mTracks.removeItemsAt(index); 750 751 if (mTracks.isEmpty()) { 752 ALOGI("Reached EOS"); 753 } 754 } else { 755 CHECK_EQ(what, Converter::kWhatError); 756 757 status_t err; 758 CHECK(msg->findInt32("err", &err)); 759 760 ALOGE("converter signaled error %d", err); 761 762 notifySessionDead(); 763 } 764 break; 765 } 766 767 case kWhatFinishPlay: 768 { 769 onFinishPlay(); 770 break; 771 } 772 773 case kWhatTrackNotify: 774 { 775 int32_t what; 776 CHECK(msg->findInt32("what", &what)); 777 778 size_t trackIndex; 779 CHECK(msg->findSize("trackIndex", &trackIndex)); 780 781 if (what == Track::kWhatStopped) { 782 ALOGI("Track %d stopped", trackIndex); 783 784 sp<Track> track = mTracks.valueFor(trackIndex); 785 looper()->unregisterHandler(track->id()); 786 mTracks.removeItem(trackIndex); 787 track.clear(); 788 789 if (!mTracks.isEmpty()) { 790 ALOGI("not all tracks are stopped yet"); 791 break; 792 } 793 794 mPacketizer.clear(); 795 796#if ENABLE_RETRANSMISSION 797 if (mRTCPRetransmissionSessionID != 0) { 798 mNetSession->destroySession(mRTCPRetransmissionSessionID); 799 } 800 801 if (mRTPRetransmissionSessionID != 0) { 802 mNetSession->destroySession(mRTPRetransmissionSessionID); 803 } 804#endif 805 806 if (mRTCPSessionID != 0) { 807 mNetSession->destroySession(mRTCPSessionID); 808 } 809 810 if (mRTPSessionID != 0) { 811 mNetSession->destroySession(mRTPSessionID); 812 } 813 814 sp<AMessage> notify = mNotify->dup(); 815 notify->setInt32("what", kWhatSessionDestroyed); 816 notify->post(); 817 } 818 break; 819 } 820 821 default: 822 TRESPASS(); 823 } 824} 825 826status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { 827 mPacketizer = new TSPacketizer; 828 829 status_t err = addVideoSource(); 830 831 if (err != OK) { 832 return err; 833 } 834 835 return addAudioSource(); 836} 837 838status_t WifiDisplaySource::PlaybackSession::addSource( 839 bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, 840 size_t *numInputBuffers) { 841 sp<ALooper> pullLooper = new ALooper; 842 pullLooper->setName("pull_looper"); 843 844 pullLooper->start( 845 false /* runOnCallingThread */, 846 false /* canCallJava */, 847 PRIORITY_AUDIO); 848 849 sp<ALooper> codecLooper = new ALooper; 850 codecLooper->setName("codec_looper"); 851 852 codecLooper->start( 853 false /* runOnCallingThread */, 854 false /* canCallJava */, 855 PRIORITY_AUDIO); 856 857 size_t trackIndex; 858 859 sp<AMessage> notify; 860 861 trackIndex = mTracks.size(); 862 863 sp<AMessage> format; 864 status_t err = convertMetaDataToMessage(source->getFormat(), &format); 865 CHECK_EQ(err, (status_t)OK); 866 867 if (isVideo) { 868 format->setInt32("store-metadata-in-buffers", true); 869 870 format->setInt32( 871 "color-format", OMX_COLOR_FormatAndroidOpaque); 872 } 873 874 notify = new AMessage(kWhatConverterNotify, id()); 875 notify->setSize("trackIndex", trackIndex); 876 877 sp<Converter> converter = 878 new Converter(notify, codecLooper, format); 879 880 if (converter->initCheck() != OK) { 881 return converter->initCheck(); 882 } 883 884 looper()->registerHandler(converter); 885 886 notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id()); 887 notify->setSize("trackIndex", trackIndex); 888 889 sp<MediaPuller> puller = new MediaPuller(source, notify); 890 pullLooper->registerHandler(puller); 891 892 if (numInputBuffers != NULL) { 893 *numInputBuffers = converter->getInputBufferCount(); 894 } 895 896 notify = new AMessage(kWhatTrackNotify, id()); 897 notify->setSize("trackIndex", trackIndex); 898 899 sp<Track> track = new Track( 900 notify, pullLooper, codecLooper, puller, converter); 901 902 if (isRepeaterSource) { 903 track->setRepeaterSource(static_cast<RepeaterSource *>(source.get())); 904 } 905 906 looper()->registerHandler(track); 907 908 mTracks.add(trackIndex, track); 909 910 if (isVideo) { 911 mVideoTrackIndex = trackIndex; 912 } 913 914 return OK; 915} 916 917status_t WifiDisplaySource::PlaybackSession::addVideoSource() { 918 sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 919 920 source->setUseAbsoluteTimestamps(); 921 922#if 1 923 sp<RepeaterSource> videoSource = 924 new RepeaterSource(source, 30.0 /* rateHz */); 925#endif 926 927#if 1 928 size_t numInputBuffers; 929 status_t err = addSource( 930 true /* isVideo */, videoSource, true /* isRepeaterSource */, 931 &numInputBuffers); 932#else 933 size_t numInputBuffers; 934 status_t err = addSource( 935 true /* isVideo */, source, false /* isRepeaterSource */, 936 &numInputBuffers); 937#endif 938 939 if (err != OK) { 940 return err; 941 } 942 943 err = source->setMaxAcquiredBufferCount(numInputBuffers); 944 CHECK_EQ(err, (status_t)OK); 945 946 mBufferQueue = source->getBufferQueue(); 947 948 return OK; 949} 950 951status_t WifiDisplaySource::PlaybackSession::addAudioSource() { 952 sp<AudioSource> audioSource = new AudioSource( 953 AUDIO_SOURCE_REMOTE_SUBMIX, 954 48000 /* sampleRate */, 955 2 /* channelCount */); 956 957 if (audioSource->initCheck() == OK) { 958 return addSource( 959 false /* isVideo */, audioSource, false /* isRepeaterSource */, 960 NULL /* numInputBuffers */); 961 } 962 963 ALOGW("Unable to instantiate audio source"); 964 965 return OK; 966} 967 968sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 969 return mBufferQueue; 970} 971 972int32_t WifiDisplaySource::PlaybackSession::width() const { 973 return 1280; 974} 975 976int32_t WifiDisplaySource::PlaybackSession::height() const { 977 return 720; 978} 979 980void WifiDisplaySource::PlaybackSession::scheduleSendSR() { 981 if (mSendSRPending) { 982 return; 983 } 984 985 mSendSRPending = true; 986 (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs); 987} 988 989void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) { 990 uint8_t *data = buffer->data() + buffer->size(); 991 992 // TODO: Use macros/utility functions to clean up all the bitshifts below. 993 994 data[0] = 0x80 | 0; 995 data[1] = 200; // SR 996 data[2] = 0; 997 data[3] = 6; 998 data[4] = kSourceID >> 24; 999 data[5] = (kSourceID >> 16) & 0xff; 1000 data[6] = (kSourceID >> 8) & 0xff; 1001 data[7] = kSourceID & 0xff; 1002 1003 data[8] = mLastNTPTime >> (64 - 8); 1004 data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 1005 data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 1006 data[11] = (mLastNTPTime >> 32) & 0xff; 1007 data[12] = (mLastNTPTime >> 24) & 0xff; 1008 data[13] = (mLastNTPTime >> 16) & 0xff; 1009 data[14] = (mLastNTPTime >> 8) & 0xff; 1010 data[15] = mLastNTPTime & 0xff; 1011 1012 data[16] = (mLastRTPTime >> 24) & 0xff; 1013 data[17] = (mLastRTPTime >> 16) & 0xff; 1014 data[18] = (mLastRTPTime >> 8) & 0xff; 1015 data[19] = mLastRTPTime & 0xff; 1016 1017 data[20] = mNumRTPSent >> 24; 1018 data[21] = (mNumRTPSent >> 16) & 0xff; 1019 data[22] = (mNumRTPSent >> 8) & 0xff; 1020 data[23] = mNumRTPSent & 0xff; 1021 1022 data[24] = mNumRTPOctetsSent >> 24; 1023 data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 1024 data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 1025 data[27] = mNumRTPOctetsSent & 0xff; 1026 1027 buffer->setRange(buffer->offset(), buffer->size() + 28); 1028} 1029 1030void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) { 1031 uint8_t *data = buffer->data() + buffer->size(); 1032 data[0] = 0x80 | 1; 1033 data[1] = 202; // SDES 1034 data[4] = kSourceID >> 24; 1035 data[5] = (kSourceID >> 16) & 0xff; 1036 data[6] = (kSourceID >> 8) & 0xff; 1037 data[7] = kSourceID & 0xff; 1038 1039 size_t offset = 8; 1040 1041 data[offset++] = 1; // CNAME 1042 1043 static const char *kCNAME = "someone@somewhere"; 1044 data[offset++] = strlen(kCNAME); 1045 1046 memcpy(&data[offset], kCNAME, strlen(kCNAME)); 1047 offset += strlen(kCNAME); 1048 1049 data[offset++] = 7; // NOTE 1050 1051 static const char *kNOTE = "Hell's frozen over."; 1052 data[offset++] = strlen(kNOTE); 1053 1054 memcpy(&data[offset], kNOTE, strlen(kNOTE)); 1055 offset += strlen(kNOTE); 1056 1057 data[offset++] = 0; 1058 1059 if ((offset % 4) > 0) { 1060 size_t count = 4 - (offset % 4); 1061 switch (count) { 1062 case 3: 1063 data[offset++] = 0; 1064 case 2: 1065 data[offset++] = 0; 1066 case 1: 1067 data[offset++] = 0; 1068 } 1069 } 1070 1071 size_t numWords = (offset / 4) - 1; 1072 data[2] = numWords >> 8; 1073 data[3] = numWords & 0xff; 1074 1075 buffer->setRange(buffer->offset(), buffer->size() + offset); 1076} 1077 1078// static 1079uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() { 1080 uint64_t nowUs = ALooper::GetNowUs(); 1081 1082 nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 1083 1084 uint64_t hi = nowUs / 1000000ll; 1085 uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 1086 1087 return (hi << 32) | lo; 1088} 1089 1090void WifiDisplaySource::PlaybackSession::onSendSR() { 1091 sp<ABuffer> buffer = new ABuffer(1500); 1092 buffer->setRange(0, 0); 1093 1094 addSR(buffer); 1095 addSDES(buffer); 1096 1097 if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1098 sp<AMessage> notify = mNotify->dup(); 1099 notify->setInt32("what", kWhatBinaryData); 1100 notify->setInt32("channel", mRTCPChannel); 1101 notify->setBuffer("data", buffer); 1102 notify->post(); 1103 } else { 1104 sendPacket(mRTCPSessionID, buffer->data(), buffer->size()); 1105 } 1106 1107 ++mNumSRsSent; 1108} 1109 1110ssize_t WifiDisplaySource::PlaybackSession::appendTSData( 1111 const void *data, size_t size, bool timeDiscontinuity, bool flush) { 1112 CHECK_EQ(size, 188); 1113 1114 CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); 1115 1116 memcpy(mTSQueue->data() + mTSQueue->size(), data, size); 1117 mTSQueue->setRange(0, mTSQueue->size() + size); 1118 1119 if (flush || mTSQueue->size() == mTSQueue->capacity()) { 1120 // flush 1121 1122 int64_t nowUs = ALooper::GetNowUs(); 1123 1124#if TRACK_BANDWIDTH 1125 if (mFirstPacketTimeUs < 0ll) { 1126 mFirstPacketTimeUs = nowUs; 1127 } 1128#endif 1129 1130 // 90kHz time scale 1131 uint32_t rtpTime = (nowUs * 9ll) / 100ll; 1132 1133 uint8_t *rtp = mTSQueue->data(); 1134 rtp[0] = 0x80; 1135 rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit 1136 rtp[2] = (mRTPSeqNo >> 8) & 0xff; 1137 rtp[3] = mRTPSeqNo & 0xff; 1138 rtp[4] = rtpTime >> 24; 1139 rtp[5] = (rtpTime >> 16) & 0xff; 1140 rtp[6] = (rtpTime >> 8) & 0xff; 1141 rtp[7] = rtpTime & 0xff; 1142 rtp[8] = kSourceID >> 24; 1143 rtp[9] = (kSourceID >> 16) & 0xff; 1144 rtp[10] = (kSourceID >> 8) & 0xff; 1145 rtp[11] = kSourceID & 0xff; 1146 1147 ++mRTPSeqNo; 1148 ++mNumRTPSent; 1149 mNumRTPOctetsSent += mTSQueue->size() - 12; 1150 1151 mLastRTPTime = rtpTime; 1152 mLastNTPTime = GetNowNTP(); 1153 1154 if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1155 sp<AMessage> notify = mNotify->dup(); 1156 notify->setInt32("what", kWhatBinaryData); 1157 1158 sp<ABuffer> data = new ABuffer(mTSQueue->size()); 1159 memcpy(data->data(), rtp, mTSQueue->size()); 1160 1161 notify->setInt32("channel", mRTPChannel); 1162 notify->setBuffer("data", data); 1163 notify->post(); 1164 } else { 1165 sendPacket(mRTPSessionID, rtp, mTSQueue->size()); 1166 1167#if TRACK_BANDWIDTH 1168 mTotalBytesSent += mTSQueue->size(); 1169 int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; 1170 1171 if (delayUs > 0ll) { 1172 ALOGI("approx. net bandwidth used: %.2f Mbit/sec", 1173 mTotalBytesSent * 8.0 / delayUs); 1174 } 1175#endif 1176 } 1177 1178#if ENABLE_RETRANSMISSION 1179 mTSQueue->setInt32Data(mRTPSeqNo - 1); 1180 1181 mHistory.push_back(mTSQueue); 1182 ++mHistoryLength; 1183 1184 if (mHistoryLength > kMaxHistoryLength) { 1185 mTSQueue = *mHistory.begin(); 1186 mHistory.erase(mHistory.begin()); 1187 1188 --mHistoryLength; 1189 } else { 1190 mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); 1191 } 1192#endif 1193 1194 mTSQueue->setRange(0, 12); 1195 } 1196 1197 return size; 1198} 1199 1200status_t WifiDisplaySource::PlaybackSession::parseRTCP( 1201 const sp<ABuffer> &buffer) { 1202 const uint8_t *data = buffer->data(); 1203 size_t size = buffer->size(); 1204 1205 while (size > 0) { 1206 if (size < 8) { 1207 // Too short to be a valid RTCP header 1208 return ERROR_MALFORMED; 1209 } 1210 1211 if ((data[0] >> 6) != 2) { 1212 // Unsupported version. 1213 return ERROR_UNSUPPORTED; 1214 } 1215 1216 if (data[0] & 0x20) { 1217 // Padding present. 1218 1219 size_t paddingLength = data[size - 1]; 1220 1221 if (paddingLength + 12 > size) { 1222 // If we removed this much padding we'd end up with something 1223 // that's too short to be a valid RTP header. 1224 return ERROR_MALFORMED; 1225 } 1226 1227 size -= paddingLength; 1228 } 1229 1230 size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 1231 1232 if (size < headerLength) { 1233 // Only received a partial packet? 1234 return ERROR_MALFORMED; 1235 } 1236 1237 switch (data[1]) { 1238 case 200: 1239 case 201: // RR 1240 case 202: // SDES 1241 case 203: 1242 case 204: // APP 1243 break; 1244 1245#if ENABLE_RETRANSMISSION 1246 case 205: // TSFB (transport layer specific feedback) 1247 parseTSFB(data, headerLength); 1248 break; 1249#endif 1250 1251 case 206: // PSFB (payload specific feedback) 1252 hexdump(data, headerLength); 1253 break; 1254 1255 default: 1256 { 1257 ALOGW("Unknown RTCP packet type %u of size %d", 1258 (unsigned)data[1], headerLength); 1259 break; 1260 } 1261 } 1262 1263 data += headerLength; 1264 size -= headerLength; 1265 } 1266 1267 return OK; 1268} 1269 1270#if ENABLE_RETRANSMISSION 1271status_t WifiDisplaySource::PlaybackSession::parseTSFB( 1272 const uint8_t *data, size_t size) { 1273 if ((data[0] & 0x1f) != 1) { 1274 return ERROR_UNSUPPORTED; // We only support NACK for now. 1275 } 1276 1277 uint32_t srcId = U32_AT(&data[8]); 1278 if (srcId != kSourceID) { 1279 return ERROR_MALFORMED; 1280 } 1281 1282 for (size_t i = 12; i < size; i += 4) { 1283 uint16_t seqNo = U16_AT(&data[i]); 1284 uint16_t blp = U16_AT(&data[i + 2]); 1285 1286 List<sp<ABuffer> >::iterator it = mHistory.begin(); 1287 bool foundSeqNo = false; 1288 while (it != mHistory.end()) { 1289 const sp<ABuffer> &buffer = *it; 1290 1291 uint16_t bufferSeqNo = buffer->int32Data() & 0xffff; 1292 1293 bool retransmit = false; 1294 if (bufferSeqNo == seqNo) { 1295 retransmit = true; 1296 } else if (blp != 0) { 1297 for (size_t i = 0; i < 16; ++i) { 1298 if ((blp & (1 << i)) 1299 && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) { 1300 blp &= ~(1 << i); 1301 retransmit = true; 1302 } 1303 } 1304 } 1305 1306 if (retransmit) { 1307 ALOGI("retransmitting seqNo %d", bufferSeqNo); 1308 1309 sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size()); 1310 uint8_t *rtp = retransRTP->data(); 1311 memcpy(rtp, buffer->data(), 12); 1312 rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff; 1313 rtp[3] = mRTPRetransmissionSeqNo & 0xff; 1314 rtp[12] = (bufferSeqNo >> 8) & 0xff; 1315 rtp[13] = bufferSeqNo & 0xff; 1316 memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12); 1317 1318 ++mRTPRetransmissionSeqNo; 1319 1320 sendPacket( 1321 mRTPRetransmissionSessionID, 1322 retransRTP->data(), retransRTP->size()); 1323 1324 if (bufferSeqNo == seqNo) { 1325 foundSeqNo = true; 1326 } 1327 1328 if (foundSeqNo && blp == 0) { 1329 break; 1330 } 1331 } 1332 1333 ++it; 1334 } 1335 1336 if (!foundSeqNo || blp != 0) { 1337 ALOGI("Some sequence numbers were no longer available for " 1338 "retransmission"); 1339 } 1340 } 1341 1342 return OK; 1343} 1344#endif 1345 1346void WifiDisplaySource::PlaybackSession::requestIDRFrame() { 1347 for (size_t i = 0; i < mTracks.size(); ++i) { 1348 const sp<Track> &track = mTracks.valueAt(i); 1349 1350 track->requestIDRFrame(); 1351 } 1352} 1353 1354status_t WifiDisplaySource::PlaybackSession::sendPacket( 1355 int32_t sessionID, const void *data, size_t size) { 1356 return mNetSession->sendRequest(sessionID, data, size); 1357} 1358 1359bool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { 1360 if (mAllTracksHavePacketizerIndex) { 1361 return true; 1362 } 1363 1364 for (size_t i = 0; i < mTracks.size(); ++i) { 1365 if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) { 1366 return false; 1367 } 1368 } 1369 1370 mAllTracksHavePacketizerIndex = true; 1371 1372 return true; 1373} 1374 1375status_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( 1376 size_t trackIndex, const sp<ABuffer> &accessUnit) { 1377 const sp<Track> &track = mTracks.valueFor(trackIndex); 1378 1379 uint32_t flags = 0; 1380 1381 bool isHDCPEncrypted = false; 1382 uint64_t inputCTR; 1383 uint8_t HDCP_private_data[16]; 1384 if (mHDCP != NULL && !track->isAudio()) { 1385 isHDCPEncrypted = true; 1386 1387 status_t err = mHDCP->encrypt( 1388 accessUnit->data(), accessUnit->size(), 1389 trackIndex /* streamCTR */, 1390 &inputCTR, 1391 accessUnit->data()); 1392 1393 if (err != OK) { 1394 ALOGE("Failed to HDCP-encrypt media data (err %d)", 1395 err); 1396 1397 return err; 1398 } 1399 1400 HDCP_private_data[0] = 0x00; 1401 1402 HDCP_private_data[1] = 1403 (((trackIndex >> 30) & 3) << 1) | 1; 1404 1405 HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 1406 1407 HDCP_private_data[3] = 1408 (((trackIndex >> 15) & 0x7f) << 1) | 1; 1409 1410 HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 1411 1412 HDCP_private_data[5] = 1413 ((trackIndex & 0x7f) << 1) | 1; 1414 1415 HDCP_private_data[6] = 0x00; 1416 1417 HDCP_private_data[7] = 1418 (((inputCTR >> 60) & 0x0f) << 1) | 1; 1419 1420 HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 1421 1422 HDCP_private_data[9] = 1423 (((inputCTR >> 45) & 0x7f) << 1) | 1; 1424 1425 HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 1426 1427 HDCP_private_data[11] = 1428 (((inputCTR >> 30) & 0x7f) << 1) | 1; 1429 1430 HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 1431 1432 HDCP_private_data[13] = 1433 (((inputCTR >> 15) & 0x7f) << 1) | 1; 1434 1435 HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 1436 1437 HDCP_private_data[15] = 1438 ((inputCTR & 0x7f) << 1) | 1; 1439 1440#if 0 1441 ALOGI("HDCP_private_data:"); 1442 hexdump(HDCP_private_data, sizeof(HDCP_private_data)); 1443 1444 ABitReader br(HDCP_private_data, sizeof(HDCP_private_data)); 1445 CHECK_EQ(br.getBits(13), 0); 1446 CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3); 1447 CHECK_EQ(br.getBits(1), 1u); 1448 CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff); 1449 CHECK_EQ(br.getBits(1), 1u); 1450 CHECK_EQ(br.getBits(15), trackIndex & 0x7fff); 1451 CHECK_EQ(br.getBits(1), 1u); 1452 CHECK_EQ(br.getBits(11), 0); 1453 CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf); 1454 CHECK_EQ(br.getBits(1), 1u); 1455 CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff); 1456 CHECK_EQ(br.getBits(1), 1u); 1457 CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff); 1458 CHECK_EQ(br.getBits(1), 1u); 1459 CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff); 1460 CHECK_EQ(br.getBits(1), 1u); 1461 CHECK_EQ(br.getBits(15), inputCTR & 0x7fff); 1462 CHECK_EQ(br.getBits(1), 1u); 1463#endif 1464 1465 flags |= TSPacketizer::IS_ENCRYPTED; 1466 } 1467 1468 int64_t timeUs = ALooper::GetNowUs(); 1469 if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 1470 flags |= TSPacketizer::EMIT_PCR; 1471 flags |= TSPacketizer::EMIT_PAT_AND_PMT; 1472 1473 mPrevTimeUs = timeUs; 1474 } 1475 1476 sp<ABuffer> packets; 1477 mPacketizer->packetize( 1478 track->packetizerTrackIndex(), accessUnit, &packets, flags, 1479 !isHDCPEncrypted ? NULL : HDCP_private_data, 1480 !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data)); 1481 1482 for (size_t offset = 0; 1483 offset < packets->size(); offset += 188) { 1484 bool lastTSPacket = (offset + 188 >= packets->size()); 1485 1486 // We're only going to flush video, audio packets are 1487 // much more frequent and would waste all that space 1488 // available in a full sized UDP packet. 1489 bool flush = 1490 lastTSPacket 1491 && ((ssize_t)trackIndex == mVideoTrackIndex); 1492 1493 appendTSData( 1494 packets->data() + offset, 1495 188, 1496 true /* timeDiscontinuity */, 1497 flush); 1498 } 1499 1500#if LOG_TRANSPORT_STREAM 1501 if (mLogFile != NULL) { 1502 fwrite(packets->data(), 1, packets->size(), mLogFile); 1503 } 1504#endif 1505 1506 return OK; 1507} 1508 1509status_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() { 1510 for (;;) { 1511 bool gotMoreData = false; 1512 for (size_t i = 0; i < mTracks.size(); ++i) { 1513 size_t trackIndex = mTracks.keyAt(i); 1514 const sp<Track> &track = mTracks.valueAt(i); 1515 1516 sp<ABuffer> accessUnit = track->dequeueAccessUnit(); 1517 if (accessUnit != NULL) { 1518 status_t err = packetizeAccessUnit(trackIndex, accessUnit); 1519 1520 if (err != OK) { 1521 return err; 1522 } 1523 1524 gotMoreData = true; 1525 } 1526 } 1527 1528 if (!gotMoreData) { 1529 break; 1530 } 1531 } 1532 1533 return OK; 1534} 1535 1536void WifiDisplaySource::PlaybackSession::notifySessionDead() { 1537 // Inform WifiDisplaySource of our premature death (wish). 1538 sp<AMessage> notify = mNotify->dup(); 1539 notify->setInt32("what", kWhatSessionDead); 1540 notify->post(); 1541 1542 mWeAreDead = true; 1543} 1544 1545} // namespace android 1546 1547