PlaybackSession.cpp revision bd08e2f93bafd02abf2c25d740e9fb8bce455a99
1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber/* 2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Copyright 2012, The Android Open Source Project 3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * you may not use this file except in compliance with the License. 6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * You may obtain a copy of the License at 7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * 10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Unless required by applicable law or agreed to in writing, software 11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * See the License for the specific language governing permissions and 14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * limitations under the License. 15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber */ 16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0 18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "PlaybackSession" 19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h> 20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "PlaybackSession.h" 22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 23d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Converter.h" 24e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include "MediaPuller.h" 25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "RepeaterSource.h" 26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Serializer.h" 27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "TSPacketizer.h" 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h> 31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h> 32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h> 36082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h> 37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h> 38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaExtractor.h> 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h> 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h> 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h> 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h> 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h> 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h> 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 49bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber//#define FAKE_VIDEO 1 50bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber#define USE_SERIALIZER 0 51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxRTPPacketSize = 1500; 55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; 56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public RefBase { 58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber Track(const sp<ALooper> &pullLooper, 59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter); 62e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Track(const sp<AMessage> &format); 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> getFormat(); 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter() const; 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex() const; 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void setPacketizerTrackIndex(size_t index); 71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 72e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t start(); 73e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t stop(); 74e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 78d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 79e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mPullLooper; 80e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mCodecLooper; 81e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> mMediaPuller; 82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> mConverter; 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> mFormat; 84e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool mStarted; 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t mPacketizerTrackIndex; 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 90e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track( 91e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &pullLooper, 92e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 93e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 94e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter) 95e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber : mPullLooper(pullLooper), 96e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mCodecLooper(codecLooper), 97e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mMediaPuller(mediaPuller), 98e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mConverter(converter), 99e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted(false), 100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizerTrackIndex(-1) { 101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format) 104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mFormat(format), 105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizerTrackIndex(-1) { 106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() { 109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber stop(); 110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mFormat != NULL) { 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mFormat; 115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter->getOutputFormat(); 118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter; 122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mPacketizerTrackIndex; 126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LT(mPacketizerTrackIndex, 0); 130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizerTrackIndex = index; 131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 133e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() { 134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mStarted) { 135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return INVALID_OPERATION; 136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 138e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 139e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 140e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 141e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->start(); 142e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 143e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 144e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == OK) { 145e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = true; 146e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 147e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 148e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 149e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 150e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 151e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::stop() { 152e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (!mStarted) { 153e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return INVALID_OPERATION; 154e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 156e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 157e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 158e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->stop(); 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 161e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 162a438123bd96c7faf145683876702387efe5628d9Andreas Huber mConverter.clear(); 163a438123bd96c7faf145683876702387efe5628d9Andreas Huber 164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = false; 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession( 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ANetworkSession> &netSession, 1730b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber const sp<AMessage> ¬ify, 174bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const in_addr &interfaceAddr, 1750b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber bool legacyMode) 176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mNetSession(netSession), 177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 178bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInterfaceAddr(interfaceAddr), 1790b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber mLegacyMode(legacyMode), 180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs(), 181e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex(-1), 182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), 183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPrevTimeUs(-1ll), 184bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode(TRANSPORT_UDP), 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel(0), 186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel(0), 187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort(0), 188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID(0), 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID(0), 190bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort(0), 191bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort(0), 192bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected(false), 193bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected(false), 194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSeqNo(0), 195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime(0), 196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime(0), 197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPSent(0), 198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent(0), 199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumSRsSent(0), 200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending(false), 201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFirstPacketTimeUs(-1ll), 202dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mHistoryLength(0), 203dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent(0ll) 204774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 205774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber ,mLogFile(NULL) 206774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 207774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber{ 208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 209774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 210774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 211774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = fopen("/system/etc/log.ts", "wb"); 212774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init( 216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 217bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TransportMode transportMode) { 218bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientIP = clientIP; 219bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = setupPacketizer(); 221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 226bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode = transportMode; 227bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 228bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (transportMode == TRANSPORT_TCP_INTERLEAVED) { 229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = clientRtp; 230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = clientRtcp; 231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort = 0; 232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = 0; 240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = 0; 241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 242bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP) { 243bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // XXX This is wrong, we need to allocate sockets here, we only 244bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // need to do this because the dongles are not establishing their 245bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // end until after PLAY instead of before SETUP. 246bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort = 20000; 247bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPSessionID = 0; 248bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPSessionID = 0; 249bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort = clientRtp; 250bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort = clientRtcp; 251bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 252bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber updateLiveness(); 253bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 254bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 255bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int serverRtp; 257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (serverRtp = 15550;; serverRtp += 2) { 261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t rtpSession; 262bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 263bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 264bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 265bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 266bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 267bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 268bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 269bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 270bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("failed to create RTP socket on port %d", serverRtp); 274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber continue; 275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (clientRtcp < 0) { 278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // No RTCP. 279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort = serverRtp; 281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = rtpSession; 282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("rtpSessionId = %d", rtpSession); 285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t rtcpSession; 289bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 290bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 291bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp + 1, clientIP, clientRtcp, 292bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtcpNotify, &rtcpSession); 293bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 294bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 295bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp + 1, clientIP, clientRtcp, 296bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtcpNotify, &rtcpSession); 297bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err == OK) { 300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort = serverRtp; 301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = rtpSession; 302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = rtcpSession; 303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession); 305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("failed to create RTCP socket on port %d", serverRtp + 1); 309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNetSession->destroySession(rtpSession); 310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTPPort == 0) { 313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return UNKNOWN_ERROR; 314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() { 322774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 323774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber if (mLogFile != NULL) { 324774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber fclose(mLogFile); 325774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = NULL; 326774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber } 327774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mRTPPort; 332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mLastLifesignUs; 336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() { 339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs = ALooper::GetNowUs(); 340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 342d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() { 343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 345bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 346bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 347bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 348bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::finishPlay() { 349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // XXX Give the dongle 3 secs to bind its sockets. 350bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber (new AMessage(kWhatFinishPlay, id()))->post(3000000ll); 351bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 352bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 353bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay() { 355bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode != TRANSPORT_TCP) { 356bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return onFinishPlay2(); 357bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 358bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 359bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 360bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 361bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber status_t err = mNetSession->createTCPDatagramSession( 362bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort, mClientIP.c_str(), mClientRTPPort, 363bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &mRTPSessionID); 364bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 365bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (err != OK) { 366bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 367bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 368bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 369bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mClientRTCPPort >= 0) { 370bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 371bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 372bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 373bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort, 374bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtcpNotify, &mRTCPSessionID); 375bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 376bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 377bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 378bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 379bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 380bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { 381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID != 0) { 382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 385e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mSerializer != NULL) { 386e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return mSerializer->start(); 387e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 388e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 389e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 390e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = mTracks.editValueAt(i)->start(); 391e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 392e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 393e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t j = 0; j < i; ++j) { 394e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mTracks.editValueAt(j)->stop(); 395e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 396e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 397e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 398e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 399e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 400e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 401bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 402bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("what", kWhatSessionEstablished); 403bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 404bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 405e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() { 409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 414a438123bd96c7faf145683876702387efe5628d9Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::destroy() { 415a438123bd96c7faf145683876702387efe5628d9Andreas Huber mTracks.clear(); 416a438123bd96c7faf145683876702387efe5628d9Andreas Huber 417a438123bd96c7faf145683876702387efe5628d9Andreas Huber mPacketizer.clear(); 418a438123bd96c7faf145683876702387efe5628d9Andreas Huber 419a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mSerializer != NULL) { 420a438123bd96c7faf145683876702387efe5628d9Andreas Huber mSerializer->stop(); 421a438123bd96c7faf145683876702387efe5628d9Andreas Huber 422a438123bd96c7faf145683876702387efe5628d9Andreas Huber looper()->unregisterHandler(mSerializer->id()); 423a438123bd96c7faf145683876702387efe5628d9Andreas Huber mSerializer.clear(); 424a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 425a438123bd96c7faf145683876702387efe5628d9Andreas Huber 426a438123bd96c7faf145683876702387efe5628d9Andreas Huber mTracks.clear(); 427a438123bd96c7faf145683876702387efe5628d9Andreas Huber 428a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mSerializerLooper != NULL) { 429a438123bd96c7faf145683876702387efe5628d9Andreas Huber mSerializerLooper->stop(); 430a438123bd96c7faf145683876702387efe5628d9Andreas Huber mSerializerLooper.clear(); 431a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 432a438123bd96c7faf145683876702387efe5628d9Andreas Huber 433a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mLegacyMode) { 434a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 435a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 436a438123bd96c7faf145683876702387efe5628d9Andreas Huber sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder); 437a438123bd96c7faf145683876702387efe5628d9Andreas Huber CHECK(service != NULL); 438a438123bd96c7faf145683876702387efe5628d9Andreas Huber 439a438123bd96c7faf145683876702387efe5628d9Andreas Huber service->connectDisplay(NULL); 440a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 441a438123bd96c7faf145683876702387efe5628d9Andreas Huber 442a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mRTCPSessionID != 0) { 443a438123bd96c7faf145683876702387efe5628d9Andreas Huber mNetSession->destroySession(mRTCPSessionID); 444a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 445a438123bd96c7faf145683876702387efe5628d9Andreas Huber 446a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mRTPSessionID != 0) { 447a438123bd96c7faf145683876702387efe5628d9Andreas Huber mNetSession->destroySession(mRTPSessionID); 448a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 449a438123bd96c7faf145683876702387efe5628d9Andreas Huber 450a438123bd96c7faf145683876702387efe5628d9Andreas Huber return OK; 451a438123bd96c7faf145683876702387efe5628d9Andreas Huber} 452a438123bd96c7faf145683876702387efe5628d9Andreas Huber 453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived( 454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &msg) { 455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTPNotify: 457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTCPNotify: 458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t reason; 460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("reason", &reason)); 461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (reason) { 463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatError: 464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t err; 469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t errorOccuredDuringSend; 472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("send", &errorOccuredDuringSend)); 473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString detail; 475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findString("detail", &detail)); 476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (msg->what() == kWhatRTPNotify 478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber && !errorOccuredDuringSend) { 479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // This is ok, we don't expect to receive anything on 480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the RTP socket. 481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("An error occurred during %s in session %d " 485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "(%d, '%s' (%s)).", 486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber errorOccuredDuringSend ? "send" : "receive", 487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sessionID, 488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err, 489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber detail.c_str(), 490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber strerror(-err)); 491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNetSession->destroySession(sessionID); 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (sessionID == mRTPSessionID) { 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (sessionID == mRTCPSessionID) { 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Inform WifiDisplaySource of our premature death (wish). 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatSessionDead); 503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatDatagram: 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data; 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("data", &data)); 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (msg->what() == kWhatRTCPNotify) { 517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = parseRTCP(data); 518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 522bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case ANetworkSession::kWhatConnected: 523bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 524bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK_EQ(mTransportMode, TRANSPORT_TCP); 525bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 526bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID; 527bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 528bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 529bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (sessionID == mRTPSessionID) { 530bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTPConnected); 531bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected = true; 532bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTP Session now connected."); 533bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else if (sessionID == mRTCPSessionID) { 534bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTCPConnected); 535bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected = true; 536bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTCP Session now connected."); 537bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 538bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TRESPASS(); 539bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 540bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 541bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mRTPConnected 542bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && (mClientRTCPPort < 0 || mRTCPConnected)) { 543bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay2(); 544bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 545bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 546bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 547bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatSendSR: 555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = false; 557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID == 0) { 559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 562d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber onSendSR(); 563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatSerializerNotify: 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (what == Serializer::kWhatEOS) { 574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("input eos"); 575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO 578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> msg = new AMessage(kWhatConverterNotify, id()); 579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->setInt32("what", Converter::kWhatEOS); 580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->setSize("trackIndex", i); 581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->post(); 582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else 583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(i)->converter()->signalEOS(); 584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Serializer::kWhatAccessUnit); 588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> accessUnit; 593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO 596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t timeUs; 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void *mbuf; 600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(accessUnit->meta()->findPointer("mediaBuffer", &mbuf)); 601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ((MediaBuffer *)mbuf)->release(); 603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mbuf = NULL; 604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> msg = new AMessage(kWhatConverterNotify, id()); 606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->setInt32("what", Converter::kWhatAccessUnit); 607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->setSize("trackIndex", trackIndex); 608d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->setBuffer("accessUnit", accessUnit); 609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber msg->post(); 610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else 611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueFor(trackIndex)->converter() 612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ->feedAccessUnit(accessUnit); 613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatConverterNotify: 619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (what == Converter::kWhatAccessUnit) { 627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t flags = 0; 630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (packetizerTrackIndex < 0) { 633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber flags = TSPacketizer::EMIT_PAT_AND_PMT; 634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetizerTrackIndex = 636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizer->addTrack(track->getFormat()); 637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (packetizerTrackIndex >= 0) { 639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber track->setPacketizerTrackIndex(packetizerTrackIndex); 640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (packetizerTrackIndex >= 0) { 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> accessUnit; 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t timeUs; 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs)); 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) { 651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber flags |= TSPacketizer::EMIT_PCR; 652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPrevTimeUs = timeUs; 653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> packets; 656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizer->packetize( 657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetizerTrackIndex, accessUnit, &packets, flags); 658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t offset = 0; 660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset < packets->size(); offset += 188) { 661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool lastTSPacket = (offset + 188 >= packets->size()); 662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 663e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber // We're only going to flush video, audio packets are 664e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber // much more frequent and would waste all that space 665e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber // available in a full sized UDP packet. 666e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool flush = 667e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber lastTSPacket 668e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber && ((ssize_t)trackIndex == mVideoTrackIndex); 669e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber appendTSData( 671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packets->data() + offset, 672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 188, 673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber true /* timeDiscontinuity */, 674e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber flush); 675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 676774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 677774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 678774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber if (mLogFile != NULL) { 679774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber fwrite(packets->data(), 1, packets->size(), mLogFile); 680774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber } 681774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (what == Converter::kWhatEOS) { 684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatEOS); 685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("output EOS on track %d", trackIndex); 687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t index = mTracks.indexOfKey(trackIndex); 689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_GE(index, 0); 690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if !FAKE_VIDEO 692d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter = 693d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(index)->converter(); 694d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->unregisterHandler(converter->id()); 695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.removeItemsAt(index); 698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mTracks.isEmpty()) { 700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("Reached EOS"); 701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatError); 704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("converter signaled error %d", err); 709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 713bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kWhatFinishPlay: 714bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 715bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay(); 716bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 717bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 718bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer() { 725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 727e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mPacketizer = new TSPacketizer; 728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO 730e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addFakeSources(); 731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else 732e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addVideoSource(); 733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 734e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 735e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 736e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 737e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 738e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addAudioSource(); 739e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#endif 740e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 742e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addFakeSources() { 743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO 744e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper = new ALooper; 745e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->setName("serializer_looper"); 746e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->start(); 747e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 748e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 749e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializer = new Serializer( 750e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber true /* throttled */, msg); 751e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 752e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->registerHandler(mSerializer); 753e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DataSource::RegisterDefaultSniffers(); 755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<DataSource> dataSource = 757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DataSource::CreateFromURI( 758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "/system/etc/inception_1500.mp4"); 759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(dataSource != NULL); 761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); 763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(extractor != NULL); 764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool haveAudio = false; 766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool haveVideo = false; 767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < extractor->countTracks(); ++i) { 768d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<MetaData> meta = extractor->getTrackMetaData(i); 769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const char *mime; 771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(meta->findCString(kKeyMIMEType, &mime)); 772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool useTrack = false; 774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!strncasecmp(mime, "audio/", 6) && !haveAudio) { 775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber useTrack = true; 776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber haveAudio = true; 777d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (!strncasecmp(mime, "video/", 6) && !haveVideo) { 778d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber useTrack = true; 779d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber haveVideo = true; 780d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 781d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 782d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (!useTrack) { 783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber continue; 784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<MediaSource> source = extractor->getTrack(i); 787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t index = mSerializer->addSource(source); 789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_GE(index, 0); 790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> format; 792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = convertMetaDataToMessage(source->getFormat(), &format); 793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(err, (status_t)OK); 794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.add(index, new Track(format)); 796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(haveAudio || haveVideo); 798e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#endif 799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 800e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 801e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 803e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource( 804e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) { 805e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#if USE_SERIALIZER 806e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mSerializer == NULL) { 807e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper = new ALooper; 808e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->setName("serializer_looper"); 809e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->start(); 810e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 811e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id()); 812e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializer = new Serializer( 813e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* throttled */, msg); 814e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 815e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mSerializerLooper->registerHandler(mSerializer); 816e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 817d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else 818e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> pullLooper = new ALooper; 819e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->setName("pull_looper"); 820e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 821e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->start( 822e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 823e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 824e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber PRIORITY_DEFAULT); 825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif 826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 827e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> codecLooper = new ALooper; 828e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->setName("codec_looper"); 829e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 830e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->start( 831e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 832e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 833e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber PRIORITY_DEFAULT); 834e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 835e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t trackIndex; 836e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 837e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify; 838e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 839e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#if USE_SERIALIZER 840e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber trackIndex = mSerializer->addSource(source); 841e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#else 842e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber trackIndex = mTracks.size(); 843e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 844e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify = new AMessage(kWhatSerializerNotify, id()); 845e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 846e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> puller = new MediaPuller(source, notify); 847e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->registerHandler(puller); 848e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#endif 849d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 850d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> format; 851d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = convertMetaDataToMessage(source->getFormat(), &format); 852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(err, (status_t)OK); 853d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 854e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 855e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32("store-metadata-in-buffers", true); 856d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 857e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32( 858e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber "color-format", OMX_COLOR_FormatAndroidOpaque); 859e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 860d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 861e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify = new AMessage(kWhatConverterNotify, id()); 862e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 863d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 864d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> converter = 865e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber new Converter(notify, codecLooper, format); 86666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(converter->initCheck(), (status_t)OK); 86766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 868d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->registerHandler(converter); 869d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 870e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (numInputBuffers != NULL) { 871e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber *numInputBuffers = converter->getInputBufferCount(); 872e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 87366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 874e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#if USE_SERIALIZER 875e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mTracks.add(trackIndex, new Track(NULL, codecLooper, NULL, converter)); 876e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#else 877e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter)); 878e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#endif 879e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 880e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 881e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex = trackIndex; 882e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 883e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 884e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 885e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 886e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 887e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource() { 888e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 889e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 890e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaSource> videoSource = 891e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber new RepeaterSource(source, 30.0 /* rateHz */); 892e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 893e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t numInputBuffers; 894e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers); 895e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 896e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 897e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 898e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 89966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 90066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber // Add one reference to account for the serializer. 9015a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber err = source->setMaxAcquiredBufferCount(numInputBuffers); 90266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(err, (status_t)OK); 90366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 9040b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber mBufferQueue = source->getBufferQueue(); 9050b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9060b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber if (mLegacyMode) { 907e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<IServiceManager> sm = defaultServiceManager(); 908e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 909e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder); 910e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber CHECK(service != NULL); 911e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 9120b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber service->connectDisplay(mBufferQueue); 9130b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber } 914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 915e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 916e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 917e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 918e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource() { 919082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber sp<AudioSource> audioSource = new AudioSource( 9201646a0fed94c30a44128b3c379736def4b332033Andreas Huber AUDIO_SOURCE_REMOTE_SUBMIX, 921082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 48000 /* sampleRate */, 9221646a0fed94c30a44128b3c379736def4b332033Andreas Huber 2 /* channelCount */); 923082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 9247977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber if (audioSource->initCheck() == OK) { 9257977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber audioSource->setUseLooperTime(true); 926082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 927e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addSource( 928e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* isVideo */, audioSource, NULL /* numInputBuffers */); 9297977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber } 930e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 931e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGW("Unable to instantiate audio source"); 932082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9360b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Hubersp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 9370b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber return mBufferQueue; 9380b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9390b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9400b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::width() const { 9417977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber return mLegacyMode ? 720 : 1280; 9420b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9430b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9440b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::height() const { 9457977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber return mLegacyMode ? 1280 : 720; 9460b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9470b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::scheduleSendSR() { 949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mSendSRPending) { 950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = true; 954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs); 955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) { 958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // TODO: Use macros/utility functions to clean up all the bitshifts below. 961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 0; 963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 200; // SR 964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = 0; 965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = 6; 966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 968d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 969d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[8] = mLastNTPTime >> (64 - 8); 972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 974d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[11] = (mLastNTPTime >> 32) & 0xff; 975d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[12] = (mLastNTPTime >> 24) & 0xff; 976d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[13] = (mLastNTPTime >> 16) & 0xff; 977d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[14] = (mLastNTPTime >> 8) & 0xff; 978d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[15] = mLastNTPTime & 0xff; 979d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 980d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[16] = (mLastRTPTime >> 24) & 0xff; 981d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[17] = (mLastRTPTime >> 16) & 0xff; 982d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[18] = (mLastRTPTime >> 8) & 0xff; 983d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[19] = mLastRTPTime & 0xff; 984d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 985d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[20] = mNumRTPSent >> 24; 986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[21] = (mNumRTPSent >> 16) & 0xff; 987d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[22] = (mNumRTPSent >> 8) & 0xff; 988d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[23] = mNumRTPSent & 0xff; 989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 990d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[24] = mNumRTPOctetsSent >> 24; 991d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 992d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 993d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[27] = mNumRTPOctetsSent & 0xff; 994d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 995d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + 28); 996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) { 999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 1000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 1; 1001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 202; // SDES 1002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 1003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 1004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 1005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 1006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = 8; 1008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 1; // CNAME 1010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kCNAME = "someone@somewhere"; 1012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kCNAME); 1013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kCNAME, strlen(kCNAME)); 1015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kCNAME); 1016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 7; // NOTE 1018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kNOTE = "Hell's frozen over."; 1020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kNOTE); 1021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kNOTE, strlen(kNOTE)); 1023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kNOTE); 1024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1026d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((offset % 4) > 0) { 1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t count = 4 - (offset % 4); 1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (count) { 1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 3: 1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 2: 1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 1: 1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numWords = (offset / 4) - 1; 1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = numWords >> 8; 1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = numWords & 0xff; 1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + offset); 1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber// static 1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() { 1048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t nowUs = ALooper::GetNowUs(); 1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 1051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t hi = nowUs / 1000000ll; 1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return (hi << 32) | lo; 1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onSendSR() { 1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(1500); 1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(0, 0); 1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSR(buffer); 1063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSDES(buffer); 1064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1065bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTCPChannel); 1069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", buffer); 1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1072bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTCPSessionID, buffer->data(), buffer->size()); 1073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumSRsSent; 1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::appendTSData( 1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const void *data, size_t size, bool timeDiscontinuity, bool flush) { 1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(size, 188); 1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); 1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mTSQueue->data() + mTSQueue->size(), data, size); 1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, mTSQueue->size() + size); 1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flush || mTSQueue->size() == mTSQueue->capacity()) { 1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // flush 1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mFirstPacketTimeUs < 0ll) { 1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFirstPacketTimeUs = nowUs; 1093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1095d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 90kHz time scale 1096d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll; 1097d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *rtp = mTSQueue->data(); 1099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[0] = 0x80; 1100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit 1101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[2] = (mRTPSeqNo >> 8) & 0xff; 1102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[3] = mRTPSeqNo & 0xff; 1103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[4] = rtpTime >> 24; 1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[5] = (rtpTime >> 16) & 0xff; 1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[6] = (rtpTime >> 8) & 0xff; 1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[7] = rtpTime & 0xff; 1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[8] = kSourceID >> 24; 1108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[9] = (kSourceID >> 16) & 0xff; 1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[10] = (kSourceID >> 8) & 0xff; 1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[11] = kSourceID & 0xff; 1111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mRTPSeqNo; 1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumRTPSent; 1114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent += mTSQueue->size() - 12; 1115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime = rtpTime; 1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime = GetNowNTP(); 1118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1119bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data = new ABuffer(mTSQueue->size()); 1124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(data->data(), rtp, mTSQueue->size()); 1125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTPChannel); 1127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", data); 1128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1130bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTPSessionID, rtp, mTSQueue->size()); 1131dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 1132dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent += mTSQueue->size(); 1133dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; 1134dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 1135dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber if (delayUs > 0ll) { 1136dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber ALOGV("approx. net bandwidth used: %.2f Mbit/sec", 1137dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent * 8.0 / delayUs); 1138dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber } 1139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setInt32Data(mRTPSeqNo - 1); 1142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.push_back(mTSQueue); 1143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mHistoryLength; 1144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mHistoryLength > kMaxHistoryLength) { 1146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = *mHistory.begin(); 1147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.erase(mHistory.begin()); 1148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber --mHistoryLength; 1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); 1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return size; 1158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseRTCP( 1161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer) { 1162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data = buffer->data(); 1163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t size = buffer->size(); 1164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (size > 0) { 1166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < 8) { 1167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Too short to be a valid RTCP header 1168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] >> 6) != 2) { 1172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Unsupported version. 1173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 1174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (data[0] & 0x20) { 1177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Padding present. 1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t paddingLength = data[size - 1]; 1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (paddingLength + 12 > size) { 1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // If we removed this much padding we'd end up with something 1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // that's too short to be a valid RTP header. 1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= paddingLength; 1188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < headerLength) { 1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Only received a partial packet? 1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (data[1]) { 1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 200: 1199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 201: // RR 1200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 202: // SDES 1201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 203: 1202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 204: // APP 1203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 205: // TSFB (transport layer specific feedback) 1206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber parseTSFB(data, headerLength); 1207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 206: // PSFB (payload specific feedback) 1210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber hexdump(data, headerLength); 1211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 1214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 1215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGW("Unknown RTCP packet type %u of size %d", 1216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (unsigned)data[1], headerLength); 1217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data += headerLength; 1222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= headerLength; 1223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseTSFB( 1229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data, size_t size) { 1230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] & 0x1f) != 1) { 1231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; // We only support NACK for now. 1232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t srcId = U32_AT(&data[8]); 1235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (srcId != kSourceID) { 1236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 12; i < size; i += 4) { 1240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t seqNo = U16_AT(&data[i]); 1241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t blp = U16_AT(&data[i + 2]); 1242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber List<sp<ABuffer> >::iterator it = mHistory.begin(); 1244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber bool found = false; 1245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (it != mHistory.end()) { 1246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer = *it; 1247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t bufferSeqNo = buffer->int32Data() & 0xffff; 1249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (bufferSeqNo == seqNo) { 1251bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTPSessionID, buffer->data(), buffer->size()); 1252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber found = true; 1254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++it; 1258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (found) { 1261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("retransmitting seqNo %d", seqNo); 1262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("seqNo %d no longer available", seqNo); 1264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1270496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() { 1271496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 1272496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber const sp<Track> &track = mTracks.valueAt(i); 1273496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1274496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber track->converter()->requestIDRFrame(); 1275496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 1276496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 1277496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1278bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::sendPacket( 1279bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID, const void *data, size_t size) { 1280bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mNetSession->sendRequest(sessionID, data, size); 1281bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 1282bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 1283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 1284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1285