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