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