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