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