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