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