PlaybackSession.cpp revision 596b4cde38b9fe18d21b4ed20dbdba909514a457
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/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 49//#define FAKE_VIDEO 1 50#define USE_SERIALIZER 0 51 52namespace android { 53 54static size_t kMaxRTPPacketSize = 1500; 55static size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; 56 57struct WifiDisplaySource::PlaybackSession::Track : public RefBase { 58 Track(const sp<ALooper> &pullLooper, 59 const sp<ALooper> &codecLooper, 60 const sp<MediaPuller> &mediaPuller, 61 const sp<Converter> &converter); 62 63 Track(const sp<AMessage> &format); 64 65 sp<AMessage> getFormat(); 66 67 const sp<Converter> &converter() const; 68 ssize_t packetizerTrackIndex() const; 69 70 void setPacketizerTrackIndex(size_t index); 71 72 status_t start(); 73 status_t stop(); 74 75protected: 76 virtual ~Track(); 77 78private: 79 sp<ALooper> mPullLooper; 80 sp<ALooper> mCodecLooper; 81 sp<MediaPuller> mMediaPuller; 82 sp<Converter> mConverter; 83 sp<AMessage> mFormat; 84 bool mStarted; 85 ssize_t mPacketizerTrackIndex; 86 87 DISALLOW_EVIL_CONSTRUCTORS(Track); 88}; 89 90WifiDisplaySource::PlaybackSession::Track::Track( 91 const sp<ALooper> &pullLooper, 92 const sp<ALooper> &codecLooper, 93 const sp<MediaPuller> &mediaPuller, 94 const sp<Converter> &converter) 95 : mPullLooper(pullLooper), 96 mCodecLooper(codecLooper), 97 mMediaPuller(mediaPuller), 98 mConverter(converter), 99 mStarted(false), 100 mPacketizerTrackIndex(-1) { 101} 102 103WifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format) 104 : mFormat(format), 105 mPacketizerTrackIndex(-1) { 106} 107 108WifiDisplaySource::PlaybackSession::Track::~Track() { 109 stop(); 110} 111 112sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 113 if (mFormat != NULL) { 114 return mFormat; 115 } 116 117 return mConverter->getOutputFormat(); 118} 119 120const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 121 return mConverter; 122} 123 124ssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 125 return mPacketizerTrackIndex; 126} 127 128void WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 129 CHECK_LT(mPacketizerTrackIndex, 0); 130 mPacketizerTrackIndex = index; 131} 132 133status_t WifiDisplaySource::PlaybackSession::Track::start() { 134 if (mStarted) { 135 return INVALID_OPERATION; 136 } 137 138 status_t err = OK; 139 140 if (mMediaPuller != NULL) { 141 err = mMediaPuller->start(); 142 } 143 144 if (err == OK) { 145 mStarted = true; 146 } 147 148 return err; 149} 150 151status_t WifiDisplaySource::PlaybackSession::Track::stop() { 152 if (!mStarted) { 153 return INVALID_OPERATION; 154 } 155 156 status_t err = OK; 157 158 if (mMediaPuller != NULL) { 159 err = mMediaPuller->stop(); 160 } 161 162 mConverter.clear(); 163 164 mStarted = false; 165 166 return err; 167} 168 169//////////////////////////////////////////////////////////////////////////////// 170 171WifiDisplaySource::PlaybackSession::PlaybackSession( 172 const sp<ANetworkSession> &netSession, 173 const sp<AMessage> ¬ify, 174 bool legacyMode) 175 : mNetSession(netSession), 176 mNotify(notify), 177 mLegacyMode(legacyMode), 178 mLastLifesignUs(), 179 mVideoTrackIndex(-1), 180 mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), 181 mPrevTimeUs(-1ll), 182 mUseInterleavedTCP(false), 183 mRTPChannel(0), 184 mRTCPChannel(0), 185 mRTPPort(0), 186 mRTPSessionID(0), 187 mRTCPSessionID(0), 188 mRTPSeqNo(0), 189 mLastNTPTime(0), 190 mLastRTPTime(0), 191 mNumRTPSent(0), 192 mNumRTPOctetsSent(0), 193 mNumSRsSent(0), 194 mSendSRPending(false), 195 mFirstPacketTimeUs(-1ll), 196 mHistoryLength(0) 197#if LOG_TRANSPORT_STREAM 198 ,mLogFile(NULL) 199#endif 200{ 201 mTSQueue->setRange(0, 12); 202 203#if LOG_TRANSPORT_STREAM 204 mLogFile = fopen("/system/etc/log.ts", "wb"); 205#endif 206} 207 208status_t WifiDisplaySource::PlaybackSession::init( 209 const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 210 bool useInterleavedTCP) { 211 status_t err = setupPacketizer(); 212 213 if (err != OK) { 214 return err; 215 } 216 217 if (useInterleavedTCP) { 218 mUseInterleavedTCP = true; 219 mRTPChannel = clientRtp; 220 mRTCPChannel = clientRtcp; 221 mRTPPort = 0; 222 mRTPSessionID = 0; 223 mRTCPSessionID = 0; 224 225 updateLiveness(); 226 return OK; 227 } 228 229 mUseInterleavedTCP = false; 230 mRTPChannel = 0; 231 mRTCPChannel = 0; 232 233 int serverRtp; 234 235 sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 236 sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 237 for (serverRtp = 15550;; serverRtp += 2) { 238 int32_t rtpSession; 239 err = mNetSession->createUDPSession( 240 serverRtp, clientIP, clientRtp, 241 rtpNotify, &rtpSession); 242 243 if (err != OK) { 244 ALOGI("failed to create RTP socket on port %d", serverRtp); 245 continue; 246 } 247 248 if (clientRtcp < 0) { 249 // No RTCP. 250 251 mRTPPort = serverRtp; 252 mRTPSessionID = rtpSession; 253 mRTCPSessionID = 0; 254 255 ALOGI("rtpSessionId = %d", rtpSession); 256 break; 257 } 258 259 int32_t rtcpSession; 260 err = mNetSession->createUDPSession( 261 serverRtp + 1, clientIP, clientRtcp, 262 rtcpNotify, &rtcpSession); 263 264 if (err == OK) { 265 mRTPPort = serverRtp; 266 mRTPSessionID = rtpSession; 267 mRTCPSessionID = rtcpSession; 268 269 ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession); 270 break; 271 } 272 273 ALOGI("failed to create RTCP socket on port %d", serverRtp + 1); 274 mNetSession->destroySession(rtpSession); 275 } 276 277 if (mRTPPort == 0) { 278 return UNKNOWN_ERROR; 279 } 280 281 updateLiveness(); 282 283 return OK; 284} 285 286WifiDisplaySource::PlaybackSession::~PlaybackSession() { 287#if LOG_TRANSPORT_STREAM 288 if (mLogFile != NULL) { 289 fclose(mLogFile); 290 mLogFile = NULL; 291 } 292#endif 293} 294 295int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 296 return mRTPPort; 297} 298 299int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 300 return mLastLifesignUs; 301} 302 303void WifiDisplaySource::PlaybackSession::updateLiveness() { 304 mLastLifesignUs = ALooper::GetNowUs(); 305} 306 307status_t WifiDisplaySource::PlaybackSession::play() { 308 updateLiveness(); 309 310 if (mRTCPSessionID != 0) { 311 scheduleSendSR(); 312 } 313 314 if (mSerializer != NULL) { 315 return mSerializer->start(); 316 } 317 318 for (size_t i = 0; i < mTracks.size(); ++i) { 319 status_t err = mTracks.editValueAt(i)->start(); 320 321 if (err != OK) { 322 for (size_t j = 0; j < i; ++j) { 323 mTracks.editValueAt(j)->stop(); 324 } 325 326 return err; 327 } 328 } 329 330 return OK; 331} 332 333status_t WifiDisplaySource::PlaybackSession::pause() { 334 updateLiveness(); 335 336 return OK; 337} 338 339status_t WifiDisplaySource::PlaybackSession::destroy() { 340 mTracks.clear(); 341 342 mPacketizer.clear(); 343 344 if (mSerializer != NULL) { 345 mSerializer->stop(); 346 347 looper()->unregisterHandler(mSerializer->id()); 348 mSerializer.clear(); 349 } 350 351 mTracks.clear(); 352 353 if (mSerializerLooper != NULL) { 354 mSerializerLooper->stop(); 355 mSerializerLooper.clear(); 356 } 357 358 if (mLegacyMode) { 359 sp<IServiceManager> sm = defaultServiceManager(); 360 sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 361 sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder); 362 CHECK(service != NULL); 363 364 service->connectDisplay(NULL); 365 } 366 367 if (mRTCPSessionID != 0) { 368 mNetSession->destroySession(mRTCPSessionID); 369 } 370 371 if (mRTPSessionID != 0) { 372 mNetSession->destroySession(mRTPSessionID); 373 } 374 375 return OK; 376} 377 378void WifiDisplaySource::PlaybackSession::onMessageReceived( 379 const sp<AMessage> &msg) { 380 switch (msg->what()) { 381 case kWhatRTPNotify: 382 case kWhatRTCPNotify: 383 { 384 int32_t reason; 385 CHECK(msg->findInt32("reason", &reason)); 386 387 switch (reason) { 388 case ANetworkSession::kWhatError: 389 { 390 int32_t sessionID; 391 CHECK(msg->findInt32("sessionID", &sessionID)); 392 393 int32_t err; 394 CHECK(msg->findInt32("err", &err)); 395 396 int32_t errorOccuredDuringSend; 397 CHECK(msg->findInt32("send", &errorOccuredDuringSend)); 398 399 AString detail; 400 CHECK(msg->findString("detail", &detail)); 401 402 if (msg->what() == kWhatRTPNotify 403 && !errorOccuredDuringSend) { 404 // This is ok, we don't expect to receive anything on 405 // the RTP socket. 406 break; 407 } 408 409 ALOGE("An error occurred during %s in session %d " 410 "(%d, '%s' (%s)).", 411 errorOccuredDuringSend ? "send" : "receive", 412 sessionID, 413 err, 414 detail.c_str(), 415 strerror(-err)); 416 417 mNetSession->destroySession(sessionID); 418 419 if (sessionID == mRTPSessionID) { 420 mRTPSessionID = 0; 421 } else if (sessionID == mRTCPSessionID) { 422 mRTCPSessionID = 0; 423 } 424 425 // Inform WifiDisplaySource of our premature death (wish). 426 sp<AMessage> notify = mNotify->dup(); 427 notify->setInt32("what", kWhatSessionDead); 428 notify->post(); 429 break; 430 } 431 432 case ANetworkSession::kWhatDatagram: 433 { 434 int32_t sessionID; 435 CHECK(msg->findInt32("sessionID", &sessionID)); 436 437 sp<ABuffer> data; 438 CHECK(msg->findBuffer("data", &data)); 439 440 status_t err; 441 if (msg->what() == kWhatRTCPNotify) { 442 err = parseRTCP(data); 443 } 444 break; 445 } 446 447 default: 448 TRESPASS(); 449 } 450 break; 451 } 452 453 case kWhatSendSR: 454 { 455 mSendSRPending = false; 456 457 if (mRTCPSessionID == 0) { 458 break; 459 } 460 461 onSendSR(); 462 463 scheduleSendSR(); 464 break; 465 } 466 467 case kWhatSerializerNotify: 468 { 469 int32_t what; 470 CHECK(msg->findInt32("what", &what)); 471 472 if (what == Serializer::kWhatEOS) { 473 ALOGI("input eos"); 474 475 for (size_t i = 0; i < mTracks.size(); ++i) { 476#if FAKE_VIDEO 477 sp<AMessage> msg = new AMessage(kWhatConverterNotify, id()); 478 msg->setInt32("what", Converter::kWhatEOS); 479 msg->setSize("trackIndex", i); 480 msg->post(); 481#else 482 mTracks.valueAt(i)->converter()->signalEOS(); 483#endif 484 } 485 } else { 486 CHECK_EQ(what, Serializer::kWhatAccessUnit); 487 488 size_t trackIndex; 489 CHECK(msg->findSize("trackIndex", &trackIndex)); 490 491 sp<ABuffer> accessUnit; 492 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 493 494#if FAKE_VIDEO 495 int64_t timeUs; 496 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 497 498 void *mbuf; 499 CHECK(accessUnit->meta()->findPointer("mediaBuffer", &mbuf)); 500 501 ((MediaBuffer *)mbuf)->release(); 502 mbuf = NULL; 503 504 sp<AMessage> msg = new AMessage(kWhatConverterNotify, id()); 505 msg->setInt32("what", Converter::kWhatAccessUnit); 506 msg->setSize("trackIndex", trackIndex); 507 msg->setBuffer("accessUnit", accessUnit); 508 msg->post(); 509#else 510 mTracks.valueFor(trackIndex)->converter() 511 ->feedAccessUnit(accessUnit); 512#endif 513 } 514 break; 515 } 516 517 case kWhatConverterNotify: 518 { 519 int32_t what; 520 CHECK(msg->findInt32("what", &what)); 521 522 size_t trackIndex; 523 CHECK(msg->findSize("trackIndex", &trackIndex)); 524 525 if (what == Converter::kWhatAccessUnit) { 526 const sp<Track> &track = mTracks.valueFor(trackIndex); 527 528 uint32_t flags = 0; 529 530 ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 531 if (packetizerTrackIndex < 0) { 532 flags = TSPacketizer::EMIT_PAT_AND_PMT; 533 534 packetizerTrackIndex = 535 mPacketizer->addTrack(track->getFormat()); 536 537 if (packetizerTrackIndex >= 0) { 538 track->setPacketizerTrackIndex(packetizerTrackIndex); 539 } 540 } 541 542 if (packetizerTrackIndex >= 0) { 543 sp<ABuffer> accessUnit; 544 CHECK(msg->findBuffer("accessUnit", &accessUnit)); 545 546 int64_t timeUs; 547 CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 548 549 if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) { 550 flags |= TSPacketizer::EMIT_PCR; 551 mPrevTimeUs = timeUs; 552 } 553 554 sp<ABuffer> packets; 555 mPacketizer->packetize( 556 packetizerTrackIndex, accessUnit, &packets, flags); 557 558 for (size_t offset = 0; 559 offset < packets->size(); offset += 188) { 560 bool lastTSPacket = (offset + 188 >= packets->size()); 561 562 // We're only going to flush video, audio packets are 563 // much more frequent and would waste all that space 564 // available in a full sized UDP packet. 565 bool flush = 566 lastTSPacket 567 && ((ssize_t)trackIndex == mVideoTrackIndex); 568 569 appendTSData( 570 packets->data() + offset, 571 188, 572 true /* timeDiscontinuity */, 573 flush); 574 } 575 576#if LOG_TRANSPORT_STREAM 577 if (mLogFile != NULL) { 578 fwrite(packets->data(), 1, packets->size(), mLogFile); 579 } 580#endif 581 } 582 } else if (what == Converter::kWhatEOS) { 583 CHECK_EQ(what, Converter::kWhatEOS); 584 585 ALOGI("output EOS on track %d", trackIndex); 586 587 ssize_t index = mTracks.indexOfKey(trackIndex); 588 CHECK_GE(index, 0); 589 590#if !FAKE_VIDEO 591 const sp<Converter> &converter = 592 mTracks.valueAt(index)->converter(); 593 looper()->unregisterHandler(converter->id()); 594#endif 595 596 mTracks.removeItemsAt(index); 597 598 if (mTracks.isEmpty()) { 599 ALOGI("Reached EOS"); 600 } 601 } else { 602 CHECK_EQ(what, Converter::kWhatError); 603 604 status_t err; 605 CHECK(msg->findInt32("err", &err)); 606 607 ALOGE("converter signaled error %d", err); 608 } 609 break; 610 } 611 612 default: 613 TRESPASS(); 614 } 615} 616 617status_t WifiDisplaySource::PlaybackSession::setupPacketizer() { 618 sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 619 620 mPacketizer = new TSPacketizer; 621 622#if FAKE_VIDEO 623 return addFakeSources(); 624#else 625 status_t err = addVideoSource(); 626 627 if (err != OK) { 628 return err; 629 } 630 631 return addAudioSource(); 632#endif 633} 634 635status_t WifiDisplaySource::PlaybackSession::addFakeSources() { 636#if FAKE_VIDEO 637 mSerializerLooper = new ALooper; 638 mSerializerLooper->setName("serializer_looper"); 639 mSerializerLooper->start(); 640 641 sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 642 mSerializer = new Serializer( 643 true /* throttled */, msg); 644 645 mSerializerLooper->registerHandler(mSerializer); 646 647 DataSource::RegisterDefaultSniffers(); 648 649 sp<DataSource> dataSource = 650 DataSource::CreateFromURI( 651 "/system/etc/inception_1500.mp4"); 652 653 CHECK(dataSource != NULL); 654 655 sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 656 CHECK(extractor != NULL); 657 658 bool haveAudio = false; 659 bool haveVideo = false; 660 for (size_t i = 0; i < extractor->countTracks(); ++i) { 661 sp<MetaData> meta = extractor->getTrackMetaData(i); 662 663 const char *mime; 664 CHECK(meta->findCString(kKeyMIMEType, &mime)); 665 666 bool useTrack = false; 667 if (!strncasecmp(mime, "audio/", 6) && !haveAudio) { 668 useTrack = true; 669 haveAudio = true; 670 } else if (!strncasecmp(mime, "video/", 6) && !haveVideo) { 671 useTrack = true; 672 haveVideo = true; 673 } 674 675 if (!useTrack) { 676 continue; 677 } 678 679 sp<MediaSource> source = extractor->getTrack(i); 680 681 ssize_t index = mSerializer->addSource(source); 682 CHECK_GE(index, 0); 683 684 sp<AMessage> format; 685 status_t err = convertMetaDataToMessage(source->getFormat(), &format); 686 CHECK_EQ(err, (status_t)OK); 687 688 mTracks.add(index, new Track(format)); 689 } 690 CHECK(haveAudio || haveVideo); 691#endif 692 693 return OK; 694} 695 696status_t WifiDisplaySource::PlaybackSession::addSource( 697 bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) { 698#if USE_SERIALIZER 699 if (mSerializer == NULL) { 700 mSerializerLooper = new ALooper; 701 mSerializerLooper->setName("serializer_looper"); 702 mSerializerLooper->start(); 703 704 sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 705 mSerializer = new Serializer( 706 false /* throttled */, msg); 707 708 mSerializerLooper->registerHandler(mSerializer); 709 } 710#else 711 sp<ALooper> pullLooper = new ALooper; 712 pullLooper->setName("pull_looper"); 713 714 pullLooper->start( 715 false /* runOnCallingThread */, 716 false /* canCallJava */, 717 PRIORITY_DEFAULT); 718#endif 719 720 sp<ALooper> codecLooper = new ALooper; 721 codecLooper->setName("codec_looper"); 722 723 codecLooper->start( 724 false /* runOnCallingThread */, 725 false /* canCallJava */, 726 PRIORITY_DEFAULT); 727 728 size_t trackIndex; 729 730 sp<AMessage> notify; 731 732#if USE_SERIALIZER 733 trackIndex = mSerializer->addSource(source); 734#else 735 trackIndex = mTracks.size(); 736 737 notify = new AMessage(kWhatSerializerNotify, id()); 738 notify->setSize("trackIndex", trackIndex); 739 sp<MediaPuller> puller = new MediaPuller(source, notify); 740 pullLooper->registerHandler(puller); 741#endif 742 743 sp<AMessage> format; 744 status_t err = convertMetaDataToMessage(source->getFormat(), &format); 745 CHECK_EQ(err, (status_t)OK); 746 747 if (isVideo) { 748 format->setInt32("store-metadata-in-buffers", true); 749 750 format->setInt32( 751 "color-format", OMX_COLOR_FormatAndroidOpaque); 752 } 753 754 notify = new AMessage(kWhatConverterNotify, id()); 755 notify->setSize("trackIndex", trackIndex); 756 757 sp<Converter> converter = 758 new Converter(notify, codecLooper, format); 759 CHECK_EQ(converter->initCheck(), (status_t)OK); 760 761 looper()->registerHandler(converter); 762 763 if (numInputBuffers != NULL) { 764 *numInputBuffers = converter->getInputBufferCount(); 765 } 766 767#if USE_SERIALIZER 768 mTracks.add(trackIndex, new Track(NULL, codecLooper, NULL, converter)); 769#else 770 mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter)); 771#endif 772 773 if (isVideo) { 774 mVideoTrackIndex = trackIndex; 775 } 776 777 return OK; 778} 779 780status_t WifiDisplaySource::PlaybackSession::addVideoSource() { 781 sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 782 783 sp<MediaSource> videoSource = 784 new RepeaterSource(source, 30.0 /* rateHz */); 785 786 size_t numInputBuffers; 787 status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers); 788 789 if (err != OK) { 790 return err; 791 } 792 793 // Add one reference to account for the serializer. 794 err = source->setMaxAcquiredBufferCount(numInputBuffers); 795 CHECK_EQ(err, (status_t)OK); 796 797 mBufferQueue = source->getBufferQueue(); 798 799 if (mLegacyMode) { 800 sp<IServiceManager> sm = defaultServiceManager(); 801 sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 802 sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder); 803 CHECK(service != NULL); 804 805 service->connectDisplay(mBufferQueue); 806 } 807 808 return OK; 809} 810 811status_t WifiDisplaySource::PlaybackSession::addAudioSource() { 812 sp<AudioSource> audioSource = new AudioSource( 813 AUDIO_SOURCE_REMOTE_SUBMIX, 814 48000 /* sampleRate */, 815 2 /* channelCount */); 816 817 if (audioSource->initCheck() == OK) { 818 audioSource->setUseLooperTime(true); 819 820 return addSource( 821 false /* isVideo */, audioSource, NULL /* numInputBuffers */); 822 } 823 824 ALOGW("Unable to instantiate audio source"); 825 826 return OK; 827} 828 829sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 830 return mBufferQueue; 831} 832 833int32_t WifiDisplaySource::PlaybackSession::width() const { 834 return mLegacyMode ? 720 : 1280; 835} 836 837int32_t WifiDisplaySource::PlaybackSession::height() const { 838 return mLegacyMode ? 1280 : 720; 839} 840 841void WifiDisplaySource::PlaybackSession::scheduleSendSR() { 842 if (mSendSRPending) { 843 return; 844 } 845 846 mSendSRPending = true; 847 (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs); 848} 849 850void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) { 851 uint8_t *data = buffer->data() + buffer->size(); 852 853 // TODO: Use macros/utility functions to clean up all the bitshifts below. 854 855 data[0] = 0x80 | 0; 856 data[1] = 200; // SR 857 data[2] = 0; 858 data[3] = 6; 859 data[4] = kSourceID >> 24; 860 data[5] = (kSourceID >> 16) & 0xff; 861 data[6] = (kSourceID >> 8) & 0xff; 862 data[7] = kSourceID & 0xff; 863 864 data[8] = mLastNTPTime >> (64 - 8); 865 data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 866 data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 867 data[11] = (mLastNTPTime >> 32) & 0xff; 868 data[12] = (mLastNTPTime >> 24) & 0xff; 869 data[13] = (mLastNTPTime >> 16) & 0xff; 870 data[14] = (mLastNTPTime >> 8) & 0xff; 871 data[15] = mLastNTPTime & 0xff; 872 873 data[16] = (mLastRTPTime >> 24) & 0xff; 874 data[17] = (mLastRTPTime >> 16) & 0xff; 875 data[18] = (mLastRTPTime >> 8) & 0xff; 876 data[19] = mLastRTPTime & 0xff; 877 878 data[20] = mNumRTPSent >> 24; 879 data[21] = (mNumRTPSent >> 16) & 0xff; 880 data[22] = (mNumRTPSent >> 8) & 0xff; 881 data[23] = mNumRTPSent & 0xff; 882 883 data[24] = mNumRTPOctetsSent >> 24; 884 data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 885 data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 886 data[27] = mNumRTPOctetsSent & 0xff; 887 888 buffer->setRange(buffer->offset(), buffer->size() + 28); 889} 890 891void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) { 892 uint8_t *data = buffer->data() + buffer->size(); 893 data[0] = 0x80 | 1; 894 data[1] = 202; // SDES 895 data[4] = kSourceID >> 24; 896 data[5] = (kSourceID >> 16) & 0xff; 897 data[6] = (kSourceID >> 8) & 0xff; 898 data[7] = kSourceID & 0xff; 899 900 size_t offset = 8; 901 902 data[offset++] = 1; // CNAME 903 904 static const char *kCNAME = "someone@somewhere"; 905 data[offset++] = strlen(kCNAME); 906 907 memcpy(&data[offset], kCNAME, strlen(kCNAME)); 908 offset += strlen(kCNAME); 909 910 data[offset++] = 7; // NOTE 911 912 static const char *kNOTE = "Hell's frozen over."; 913 data[offset++] = strlen(kNOTE); 914 915 memcpy(&data[offset], kNOTE, strlen(kNOTE)); 916 offset += strlen(kNOTE); 917 918 data[offset++] = 0; 919 920 if ((offset % 4) > 0) { 921 size_t count = 4 - (offset % 4); 922 switch (count) { 923 case 3: 924 data[offset++] = 0; 925 case 2: 926 data[offset++] = 0; 927 case 1: 928 data[offset++] = 0; 929 } 930 } 931 932 size_t numWords = (offset / 4) - 1; 933 data[2] = numWords >> 8; 934 data[3] = numWords & 0xff; 935 936 buffer->setRange(buffer->offset(), buffer->size() + offset); 937} 938 939// static 940uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() { 941 uint64_t nowUs = ALooper::GetNowUs(); 942 943 nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 944 945 uint64_t hi = nowUs / 1000000ll; 946 uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 947 948 return (hi << 32) | lo; 949} 950 951void WifiDisplaySource::PlaybackSession::onSendSR() { 952 sp<ABuffer> buffer = new ABuffer(1500); 953 buffer->setRange(0, 0); 954 955 addSR(buffer); 956 addSDES(buffer); 957 958 if (mUseInterleavedTCP) { 959 sp<AMessage> notify = mNotify->dup(); 960 notify->setInt32("what", kWhatBinaryData); 961 notify->setInt32("channel", mRTCPChannel); 962 notify->setBuffer("data", buffer); 963 notify->post(); 964 } else { 965 mNetSession->sendRequest( 966 mRTCPSessionID, buffer->data(), buffer->size()); 967 } 968 969 ++mNumSRsSent; 970} 971 972ssize_t WifiDisplaySource::PlaybackSession::appendTSData( 973 const void *data, size_t size, bool timeDiscontinuity, bool flush) { 974 CHECK_EQ(size, 188); 975 976 CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); 977 978 memcpy(mTSQueue->data() + mTSQueue->size(), data, size); 979 mTSQueue->setRange(0, mTSQueue->size() + size); 980 981 if (flush || mTSQueue->size() == mTSQueue->capacity()) { 982 // flush 983 984 int64_t nowUs = ALooper::GetNowUs(); 985 if (mFirstPacketTimeUs < 0ll) { 986 mFirstPacketTimeUs = nowUs; 987 } 988 989 // 90kHz time scale 990 uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll; 991 992 uint8_t *rtp = mTSQueue->data(); 993 rtp[0] = 0x80; 994 rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit 995 rtp[2] = (mRTPSeqNo >> 8) & 0xff; 996 rtp[3] = mRTPSeqNo & 0xff; 997 rtp[4] = rtpTime >> 24; 998 rtp[5] = (rtpTime >> 16) & 0xff; 999 rtp[6] = (rtpTime >> 8) & 0xff; 1000 rtp[7] = rtpTime & 0xff; 1001 rtp[8] = kSourceID >> 24; 1002 rtp[9] = (kSourceID >> 16) & 0xff; 1003 rtp[10] = (kSourceID >> 8) & 0xff; 1004 rtp[11] = kSourceID & 0xff; 1005 1006 ++mRTPSeqNo; 1007 ++mNumRTPSent; 1008 mNumRTPOctetsSent += mTSQueue->size() - 12; 1009 1010 mLastRTPTime = rtpTime; 1011 mLastNTPTime = GetNowNTP(); 1012 1013 if (mUseInterleavedTCP) { 1014 sp<AMessage> notify = mNotify->dup(); 1015 notify->setInt32("what", kWhatBinaryData); 1016 1017 sp<ABuffer> data = new ABuffer(mTSQueue->size()); 1018 memcpy(data->data(), rtp, mTSQueue->size()); 1019 1020 notify->setInt32("channel", mRTPChannel); 1021 notify->setBuffer("data", data); 1022 notify->post(); 1023 } else { 1024 mNetSession->sendRequest( 1025 mRTPSessionID, rtp, mTSQueue->size()); 1026 } 1027 1028 mTSQueue->setInt32Data(mRTPSeqNo - 1); 1029 mHistory.push_back(mTSQueue); 1030 ++mHistoryLength; 1031 1032 if (mHistoryLength > kMaxHistoryLength) { 1033 mTSQueue = *mHistory.begin(); 1034 mHistory.erase(mHistory.begin()); 1035 1036 --mHistoryLength; 1037 } else { 1038 mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); 1039 } 1040 1041 mTSQueue->setRange(0, 12); 1042 } 1043 1044 return size; 1045} 1046 1047status_t WifiDisplaySource::PlaybackSession::parseRTCP( 1048 const sp<ABuffer> &buffer) { 1049 const uint8_t *data = buffer->data(); 1050 size_t size = buffer->size(); 1051 1052 while (size > 0) { 1053 if (size < 8) { 1054 // Too short to be a valid RTCP header 1055 return ERROR_MALFORMED; 1056 } 1057 1058 if ((data[0] >> 6) != 2) { 1059 // Unsupported version. 1060 return ERROR_UNSUPPORTED; 1061 } 1062 1063 if (data[0] & 0x20) { 1064 // Padding present. 1065 1066 size_t paddingLength = data[size - 1]; 1067 1068 if (paddingLength + 12 > size) { 1069 // If we removed this much padding we'd end up with something 1070 // that's too short to be a valid RTP header. 1071 return ERROR_MALFORMED; 1072 } 1073 1074 size -= paddingLength; 1075 } 1076 1077 size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 1078 1079 if (size < headerLength) { 1080 // Only received a partial packet? 1081 return ERROR_MALFORMED; 1082 } 1083 1084 switch (data[1]) { 1085 case 200: 1086 case 201: // RR 1087 case 202: // SDES 1088 case 203: 1089 case 204: // APP 1090 break; 1091 1092 case 205: // TSFB (transport layer specific feedback) 1093 parseTSFB(data, headerLength); 1094 break; 1095 1096 case 206: // PSFB (payload specific feedback) 1097 hexdump(data, headerLength); 1098 break; 1099 1100 default: 1101 { 1102 ALOGW("Unknown RTCP packet type %u of size %d", 1103 (unsigned)data[1], headerLength); 1104 break; 1105 } 1106 } 1107 1108 data += headerLength; 1109 size -= headerLength; 1110 } 1111 1112 return OK; 1113} 1114 1115status_t WifiDisplaySource::PlaybackSession::parseTSFB( 1116 const uint8_t *data, size_t size) { 1117 if ((data[0] & 0x1f) != 1) { 1118 return ERROR_UNSUPPORTED; // We only support NACK for now. 1119 } 1120 1121 uint32_t srcId = U32_AT(&data[8]); 1122 if (srcId != kSourceID) { 1123 return ERROR_MALFORMED; 1124 } 1125 1126 for (size_t i = 12; i < size; i += 4) { 1127 uint16_t seqNo = U16_AT(&data[i]); 1128 uint16_t blp = U16_AT(&data[i + 2]); 1129 1130 List<sp<ABuffer> >::iterator it = mHistory.begin(); 1131 bool found = false; 1132 while (it != mHistory.end()) { 1133 const sp<ABuffer> &buffer = *it; 1134 1135 uint16_t bufferSeqNo = buffer->int32Data() & 0xffff; 1136 1137 if (bufferSeqNo == seqNo) { 1138 mNetSession->sendRequest( 1139 mRTPSessionID, buffer->data(), buffer->size()); 1140 1141 found = true; 1142 break; 1143 } 1144 1145 ++it; 1146 } 1147 1148 if (found) { 1149 ALOGI("retransmitting seqNo %d", seqNo); 1150 } else { 1151 ALOGI("seqNo %d no longer available", seqNo); 1152 } 1153 } 1154 1155 return OK; 1156} 1157 1158} // namespace android 1159 1160