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