PlaybackSession.cpp revision eb11600a248cfe5b95ddd3e5aaae02bd2ab65276
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 "TSPacketizer.h" 27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h> 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h> 31b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.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 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxRTPPacketSize = 1500; 52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; 53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public RefBase { 55e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber Track(const sp<ALooper> &pullLooper, 56e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 57e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter); 59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 60d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber Track(const sp<AMessage> &format); 61d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 62d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> getFormat(); 63b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool isAudio() const; 64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter() const; 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex() const; 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void setPacketizerTrackIndex(size_t index); 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t start(); 71e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t stop(); 72e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 7328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber void queueAccessUnit(const sp<ABuffer> &accessUnit); 7428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> dequeueAccessUnit(); 7528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 78d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 79d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 80e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mPullLooper; 81e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mCodecLooper; 82e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> mMediaPuller; 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> mConverter; 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> mFormat; 85e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool mStarted; 86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t mPacketizerTrackIndex; 87b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool mIsAudio; 8828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber List<sp<ABuffer> > mQueuedAccessUnits; 89b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 90b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber static bool IsAudioFormat(const sp<AMessage> &format); 91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 95e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track( 96e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &pullLooper, 97e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 98e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 99e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter) 100e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber : mPullLooper(pullLooper), 101e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mCodecLooper(codecLooper), 102e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mMediaPuller(mediaPuller), 103e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mConverter(converter), 104e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted(false), 105b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mPacketizerTrackIndex(-1), 106b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) { 107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format) 110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mFormat(format), 111b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mPacketizerTrackIndex(-1), 112b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mIsAudio(IsAudioFormat(mFormat)) { 113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() { 116e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber stop(); 117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 119b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static 120b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( 121b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber const sp<AMessage> &format) { 122b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber AString mime; 123b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber CHECK(format->findString("mime", &mime)); 124b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 125b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return !strncasecmp(mime.c_str(), "audio/", 6); 126b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 127b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mFormat != NULL) { 130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mFormat; 131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter->getOutputFormat(); 134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 136b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const { 137b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return mIsAudio; 138b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 139b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter; 142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mPacketizerTrackIndex; 146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LT(mPacketizerTrackIndex, 0); 150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizerTrackIndex = index; 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 153e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() { 154e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mStarted) { 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return INVALID_OPERATION; 156e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 157e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 158e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 161e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->start(); 162e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 163e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == OK) { 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = true; 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::stop() { 172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (!mStarted) { 173e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return INVALID_OPERATION; 174e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 175e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 176e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 177e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 178e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 179e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->stop(); 180e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 181e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 182a438123bd96c7faf145683876702387efe5628d9Andreas Huber mConverter.clear(); 183a438123bd96c7faf145683876702387efe5628d9Andreas Huber 184e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = false; 185e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 186e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 187e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 188e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 18928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( 19028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<ABuffer> &accessUnit) { 19128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.push_back(accessUnit); 19228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 19328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 19428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() { 19528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mQueuedAccessUnits.empty()) { 19628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return NULL; 19728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 19828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 19928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin(); 20028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(accessUnit != NULL); 20128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 20228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.erase(mQueuedAccessUnits.begin()); 20328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 20428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return accessUnit; 20528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 20628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession( 210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ANetworkSession> &netSession, 2110b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber const sp<AMessage> ¬ify, 212bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const in_addr &interfaceAddr, 213b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber const sp<IHDCP> &hdcp) 214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mNetSession(netSession), 215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 216bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInterfaceAddr(interfaceAddr), 217b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mHDCP(hdcp), 218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs(), 219e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex(-1), 220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), 221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPrevTimeUs(-1ll), 222bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode(TRANSPORT_UDP), 22328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mAllTracksHavePacketizerIndex(false), 224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel(0), 225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel(0), 226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort(0), 227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID(0), 228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID(0), 229efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 230efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID(0), 231efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID(0), 232efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 233bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort(0), 234bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort(0), 235bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected(false), 236bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected(false), 237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSeqNo(0), 238efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 239efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSeqNo(0), 240efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime(0), 242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime(0), 243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPSent(0), 244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent(0), 245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumSRsSent(0), 246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending(false), 247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFirstPacketTimeUs(-1ll), 248dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mHistoryLength(0), 249dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent(0ll) 250774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 251774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber ,mLogFile(NULL) 252774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 253774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber{ 254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 255774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 256774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 257774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = fopen("/system/etc/log.ts", "wb"); 258774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init( 262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 263bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TransportMode transportMode) { 264bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientIP = clientIP; 265bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = setupPacketizer(); 267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 272bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode = transportMode; 273bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 274bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (transportMode == TRANSPORT_TCP_INTERLEAVED) { 275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = clientRtp; 276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = clientRtcp; 277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort = 0; 278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = 0; 286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = 0; 287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 288bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP) { 289bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // XXX This is wrong, we need to allocate sockets here, we only 290bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // need to do this because the dongles are not establishing their 291bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // end until after PLAY instead of before SETUP. 292bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort = 20000; 293bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPSessionID = 0; 294bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPSessionID = 0; 295bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort = clientRtp; 296bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort = clientRtcp; 297bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 298bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber updateLiveness(); 299bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 300bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 301bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int serverRtp; 303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 306efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 307efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 308efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<AMessage> rtpRetransmissionNotify = 309efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber new AMessage(kWhatRTPRetransmissionNotify, id()); 310efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 311efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<AMessage> rtcpRetransmissionNotify = 312efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber new AMessage(kWhatRTCPRetransmissionNotify, id()); 313efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 314efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (serverRtp = 15550;; serverRtp += 2) { 316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t rtpSession; 317bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 318bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 319bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 320bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 321bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 322bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 323bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 324bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 325bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("failed to create RTP socket on port %d", serverRtp); 329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber continue; 330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 332efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtcpSession = 0; 333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 334efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (clientRtcp >= 0) { 335efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (mTransportMode == TRANSPORT_UDP) { 336efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createUDPSession( 337efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1, clientIP, clientRtcp, 338efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpNotify, &rtcpSession); 339efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else { 340efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createTCPDatagramSession( 341efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1, clientIP, clientRtcp, 342efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpNotify, &rtcpSession); 343efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 345efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 346efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("failed to create RTCP socket on port %d", serverRtp + 1); 347efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 348efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 349efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 350efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 353efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 355efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtpRetransmissionSession; 356efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 357bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 358efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + kRetransmissionPortOffset, 359efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientIP, 360efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientRtp + kRetransmissionPortOffset, 361efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtpRetransmissionNotify, 362efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber &rtpRetransmissionSession); 363efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 364efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 365efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtcpSession); 366efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 367efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 368efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 370efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber CHECK_GE(clientRtcp, 0); 371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 372efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtcpRetransmissionSession; 373efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createUDPSession( 374efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1 + kRetransmissionPortOffset, 375efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientIP, 376efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientRtp + 1 + kRetransmissionPortOffset, 377efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpRetransmissionNotify, 378efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber &rtcpRetransmissionSession); 379efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 380efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 381efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpRetransmissionSession); 382efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtcpSession); 383efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 384efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 385efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 386efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 387efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID = rtpRetransmissionSession; 388efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID = rtcpRetransmissionSession; 389efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 390efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("rtpRetransmissionSessionID = %d, " 391efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber "rtcpRetransmissionSessionID = %d", 392efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtpRetransmissionSession, rtcpRetransmissionSession); 393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 394efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 395efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 396efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPPort = serverRtp; 397efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPSessionID = rtpSession; 398efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPSessionID = rtcpSession; 399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 400efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession); 401efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber break; 402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTPPort == 0) { 405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return UNKNOWN_ERROR; 406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() { 414774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 415774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber if (mLogFile != NULL) { 416774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber fclose(mLogFile); 417774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = NULL; 418774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber } 419774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mRTPPort; 424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mLastLifesignUs; 428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() { 431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs = ALooper::GetNowUs(); 432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() { 435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 437bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 438bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 439bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 440bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::finishPlay() { 44192f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber // XXX Give the dongle a second to bind its sockets. 44292f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber (new AMessage(kWhatFinishPlay, id()))->post(1000000ll); 443bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 444bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 445bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 446bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay() { 447bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode != TRANSPORT_TCP) { 448bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return onFinishPlay2(); 449bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 450bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 451bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 452bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 453bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber status_t err = mNetSession->createTCPDatagramSession( 454bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort, mClientIP.c_str(), mClientRTPPort, 455bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &mRTPSessionID); 456bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 457bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (err != OK) { 458bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 459bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 460bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 461bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mClientRTCPPort >= 0) { 462bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 463bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 464bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 465bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort, 466bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtcpNotify, &mRTCPSessionID); 467bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 468bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 469bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 470bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 471bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 472bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { 473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID != 0) { 474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 477e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 478e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = mTracks.editValueAt(i)->start(); 479e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 480e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 481e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t j = 0; j < i; ++j) { 482e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mTracks.editValueAt(j)->stop(); 483e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 484e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 485e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 486e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 487e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 488e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 489bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 490bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("what", kWhatSessionEstablished); 491bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 492bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 493e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() { 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 502a438123bd96c7faf145683876702387efe5628d9Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::destroy() { 503a438123bd96c7faf145683876702387efe5628d9Andreas Huber mTracks.clear(); 504a438123bd96c7faf145683876702387efe5628d9Andreas Huber 505a438123bd96c7faf145683876702387efe5628d9Andreas Huber mPacketizer.clear(); 506a438123bd96c7faf145683876702387efe5628d9Andreas Huber 507a438123bd96c7faf145683876702387efe5628d9Andreas Huber mTracks.clear(); 508a438123bd96c7faf145683876702387efe5628d9Andreas Huber 509efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 510efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (mRTCPRetransmissionSessionID != 0) { 511efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(mRTCPRetransmissionSessionID); 512efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 513efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 514efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (mRTPRetransmissionSessionID != 0) { 515efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(mRTPRetransmissionSessionID); 516efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 517efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 518efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 519a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mRTCPSessionID != 0) { 520a438123bd96c7faf145683876702387efe5628d9Andreas Huber mNetSession->destroySession(mRTCPSessionID); 521a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 522a438123bd96c7faf145683876702387efe5628d9Andreas Huber 523a438123bd96c7faf145683876702387efe5628d9Andreas Huber if (mRTPSessionID != 0) { 524a438123bd96c7faf145683876702387efe5628d9Andreas Huber mNetSession->destroySession(mRTPSessionID); 525a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 526a438123bd96c7faf145683876702387efe5628d9Andreas Huber 527a438123bd96c7faf145683876702387efe5628d9Andreas Huber return OK; 528a438123bd96c7faf145683876702387efe5628d9Andreas Huber} 529a438123bd96c7faf145683876702387efe5628d9Andreas Huber 530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived( 531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &msg) { 532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTPNotify: 534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTCPNotify: 535efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 536efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber case kWhatRTPRetransmissionNotify: 537efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber case kWhatRTCPRetransmissionNotify: 538efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 540d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t reason; 541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("reason", &reason)); 542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (reason) { 544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatError: 545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t err; 550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t errorOccuredDuringSend; 553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("send", &errorOccuredDuringSend)); 554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString detail; 556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findString("detail", &detail)); 557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 558efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if ((msg->what() == kWhatRTPNotify 559efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 560efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber || msg->what() == kWhatRTPRetransmissionNotify 561efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 562efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ) && !errorOccuredDuringSend) { 563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // This is ok, we don't expect to receive anything on 564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the RTP socket. 565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("An error occurred during %s in session %d " 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "(%d, '%s' (%s)).", 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber errorOccuredDuringSend ? "send" : "receive", 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sessionID, 572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err, 573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber detail.c_str(), 574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber strerror(-err)); 575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNetSession->destroySession(sessionID); 577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (sessionID == mRTPSessionID) { 579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (sessionID == mRTCPSessionID) { 581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 583efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 584efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber else if (sessionID == mRTPRetransmissionSessionID) { 585efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID = 0; 586efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else if (sessionID == mRTCPRetransmissionSessionID) { 587efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID = 0; 588efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 589efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Inform WifiDisplaySource of our premature death (wish). 592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatSessionDead); 594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatDatagram: 599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data; 604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("data", &data)); 605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 607efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (msg->what() == kWhatRTCPNotify 608efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 609efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber || msg->what() == kWhatRTCPRetransmissionNotify 610efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 611efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ) 612efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber { 613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = parseRTCP(data); 614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 618bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case ANetworkSession::kWhatConnected: 619bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 620bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK_EQ(mTransportMode, TRANSPORT_TCP); 621bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 622bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID; 623bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 624bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 625bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (sessionID == mRTPSessionID) { 626bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTPConnected); 627bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected = true; 628bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTP Session now connected."); 629bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else if (sessionID == mRTCPSessionID) { 630bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTCPConnected); 631bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected = true; 632bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTCP Session now connected."); 633bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 634bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TRESPASS(); 635bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 636bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 637bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mRTPConnected 638bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && (mClientRTCPPort < 0 || mRTCPConnected)) { 639bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay2(); 640bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 641bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 642bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 643bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatSendSR: 651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = false; 653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID == 0) { 655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber onSendSR(); 659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 664207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber case kWhatMediaPullerNotify: 665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 669207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber if (what == MediaPuller::kWhatEOS) { 670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("input eos"); 671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(i)->converter()->signalEOS(); 674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 676207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber CHECK_EQ(what, MediaPuller::kWhatAccessUnit); 677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> accessUnit; 682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueFor(trackIndex)->converter() 685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ->feedAccessUnit(accessUnit); 686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatConverterNotify: 691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 692d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 693d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 694d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (what == Converter::kWhatAccessUnit) { 699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (packetizerTrackIndex < 0) { 704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetizerTrackIndex = 705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizer->addTrack(track->getFormat()); 706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK_GE(packetizerTrackIndex, 0); 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->setPacketizerTrackIndex(packetizerTrackIndex); 710b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 71128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (allTracksHavePacketizerIndex()) { 71228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeQueuedAccessUnits(); 713b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 714b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (err != OK) { 715b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber // Inform WifiDisplaySource of our premature death 716b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber // (wish). 717b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber sp<AMessage> notify = mNotify->dup(); 718b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber notify->setInt32("what", kWhatSessionDead); 719b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber notify->post(); 72028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 721b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber break; 722b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 723b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 72428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 725b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 72628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit; 72728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 72928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (!allTracksHavePacketizerIndex()) { 73028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->queueAccessUnit(accessUnit); 73128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 73228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 73428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeAccessUnit(trackIndex, accessUnit); 735774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 73628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 73728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // Inform WifiDisplaySource of our premature death 73828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // (wish). 73928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<AMessage> notify = mNotify->dup(); 74028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber notify->setInt32("what", kWhatSessionDead); 74128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber notify->post(); 742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 74328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (what == Converter::kWhatEOS) { 745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatEOS); 746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("output EOS on track %d", trackIndex); 748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t index = mTracks.indexOfKey(trackIndex); 750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_GE(index, 0); 751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter = 753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(index)->converter(); 754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->unregisterHandler(converter->id()); 755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.removeItemsAt(index); 757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mTracks.isEmpty()) { 759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("Reached EOS"); 760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatError); 763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("converter signaled error %d", err); 768ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber 769ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber // Inform WifiDisplaySource of our premature death (wish). 770ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber sp<AMessage> notify = mNotify->dup(); 771ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber notify->setInt32("what", kWhatSessionDead); 772ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber notify->post(); 773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 777bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kWhatFinishPlay: 778bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 779bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay(); 780bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 781bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 782bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer() { 789e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mPacketizer = new TSPacketizer; 790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 791e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addVideoSource(); 792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 793e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 794e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 795e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 796e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 797e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addAudioSource(); 798e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 800e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource( 801e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) { 802e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> pullLooper = new ALooper; 803e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->setName("pull_looper"); 804e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 805e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->start( 806e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 807e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 808ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 809d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 810e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> codecLooper = new ALooper; 811e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->setName("codec_looper"); 812e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 813e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->start( 814e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 815e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 816ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 817e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 818e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t trackIndex; 819e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 820e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify; 821e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 822e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber trackIndex = mTracks.size(); 823e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 824207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber notify = new AMessage(kWhatMediaPullerNotify, id()); 825e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 826e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> puller = new MediaPuller(source, notify); 827e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->registerHandler(puller); 828d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 829d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> format; 830d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = convertMetaDataToMessage(source->getFormat(), &format); 831d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(err, (status_t)OK); 832d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 833e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 834e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32("store-metadata-in-buffers", true); 835d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 836e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32( 837e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber "color-format", OMX_COLOR_FormatAndroidOpaque); 838e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 839d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 840e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify = new AMessage(kWhatConverterNotify, id()); 841e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 842d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 843d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> converter = 844e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber new Converter(notify, codecLooper, format); 84566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(converter->initCheck(), (status_t)OK); 84666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 847d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->registerHandler(converter); 848d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 849e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (numInputBuffers != NULL) { 850e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber *numInputBuffers = converter->getInputBufferCount(); 851e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 85266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 853e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter)); 854e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 855e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 856e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex = trackIndex; 857e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 858e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 859e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 860e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 861e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 862e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource() { 863e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 864e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 865e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaSource> videoSource = 866e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber new RepeaterSource(source, 30.0 /* rateHz */); 867e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 868e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t numInputBuffers; 869e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers); 870e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 871e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 872e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 873e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 87466e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 8755a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber err = source->setMaxAcquiredBufferCount(numInputBuffers); 87666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(err, (status_t)OK); 87766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 8780b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber mBufferQueue = source->getBufferQueue(); 8790b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 880e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 881e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 882e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 883e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource() { 884082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber sp<AudioSource> audioSource = new AudioSource( 8851646a0fed94c30a44128b3c379736def4b332033Andreas Huber AUDIO_SOURCE_REMOTE_SUBMIX, 886082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 48000 /* sampleRate */, 8871646a0fed94c30a44128b3c379736def4b332033Andreas Huber 2 /* channelCount */); 888082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 8897977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber if (audioSource->initCheck() == OK) { 8907977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber audioSource->setUseLooperTime(true); 891082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 892e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addSource( 893e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* isVideo */, audioSource, NULL /* numInputBuffers */); 8947977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber } 895e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 896e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGW("Unable to instantiate audio source"); 897082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9010b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Hubersp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 9020b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber return mBufferQueue; 9030b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9040b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9050b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::width() const { 906207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber return 1280; 9070b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9080b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9090b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::height() const { 910207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber return 720; 9110b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9120b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 913d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::scheduleSendSR() { 914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mSendSRPending) { 915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 918d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = true; 919d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs); 920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 921d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 922d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) { 923d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 924d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 925d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // TODO: Use macros/utility functions to clean up all the bitshifts below. 926d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 927d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 0; 928d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 200; // SR 929d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = 0; 930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = 6; 931d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 932d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[8] = mLastNTPTime >> (64 - 8); 937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[11] = (mLastNTPTime >> 32) & 0xff; 940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[12] = (mLastNTPTime >> 24) & 0xff; 941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[13] = (mLastNTPTime >> 16) & 0xff; 942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[14] = (mLastNTPTime >> 8) & 0xff; 943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[15] = mLastNTPTime & 0xff; 944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[16] = (mLastRTPTime >> 24) & 0xff; 946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[17] = (mLastRTPTime >> 16) & 0xff; 947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[18] = (mLastRTPTime >> 8) & 0xff; 948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[19] = mLastRTPTime & 0xff; 949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[20] = mNumRTPSent >> 24; 951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[21] = (mNumRTPSent >> 16) & 0xff; 952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[22] = (mNumRTPSent >> 8) & 0xff; 953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[23] = mNumRTPSent & 0xff; 954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[24] = mNumRTPOctetsSent >> 24; 956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[27] = mNumRTPOctetsSent & 0xff; 959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + 28); 961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) { 964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 1; 966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 202; // SDES 967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 968d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 969d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = 8; 973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 974d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 1; // CNAME 975d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 976d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kCNAME = "someone@somewhere"; 977d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kCNAME); 978d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 979d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kCNAME, strlen(kCNAME)); 980d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kCNAME); 981d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 982d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 7; // NOTE 983d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 984d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kNOTE = "Hell's frozen over."; 985d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kNOTE); 986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 987d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kNOTE, strlen(kNOTE)); 988d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kNOTE); 989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 990d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 991d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 992d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((offset % 4) > 0) { 993d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t count = 4 - (offset % 4); 994d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (count) { 995d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 3: 996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 2: 998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 1: 1000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numWords = (offset / 4) - 1; 1005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = numWords >> 8; 1006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = numWords & 0xff; 1007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + offset); 1009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber// static 1012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() { 1013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t nowUs = ALooper::GetNowUs(); 1014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 1016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t hi = nowUs / 1000000ll; 1018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 1019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return (hi << 32) | lo; 1021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onSendSR() { 1024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(1500); 1025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(0, 0); 1026d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSR(buffer); 1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSDES(buffer); 1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1030bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTCPChannel); 1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", buffer); 1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1037bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTCPSessionID, buffer->data(), buffer->size()); 1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumSRsSent; 1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::appendTSData( 1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const void *data, size_t size, bool timeDiscontinuity, bool flush) { 1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(size, 188); 1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); 1048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mTSQueue->data() + mTSQueue->size(), data, size); 1050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, mTSQueue->size() + size); 1051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flush || mTSQueue->size() == mTSQueue->capacity()) { 1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // flush 1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mFirstPacketTimeUs < 0ll) { 1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFirstPacketTimeUs = nowUs; 1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 90kHz time scale 1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll; 1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *rtp = mTSQueue->data(); 1064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[0] = 0x80; 1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit 1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[2] = (mRTPSeqNo >> 8) & 0xff; 1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[3] = mRTPSeqNo & 0xff; 1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[4] = rtpTime >> 24; 1069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[5] = (rtpTime >> 16) & 0xff; 1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[6] = (rtpTime >> 8) & 0xff; 1071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[7] = rtpTime & 0xff; 1072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[8] = kSourceID >> 24; 1073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[9] = (kSourceID >> 16) & 0xff; 1074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[10] = (kSourceID >> 8) & 0xff; 1075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[11] = kSourceID & 0xff; 1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mRTPSeqNo; 1078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumRTPSent; 1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent += mTSQueue->size() - 12; 1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime = rtpTime; 1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime = GetNowNTP(); 1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1084bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data = new ABuffer(mTSQueue->size()); 1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(data->data(), rtp, mTSQueue->size()); 1090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTPChannel); 1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", data); 1093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1095bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTPSessionID, rtp, mTSQueue->size()); 1096dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 1097dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent += mTSQueue->size(); 1098dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; 1099dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 1100dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber if (delayUs > 0ll) { 1101dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber ALOGV("approx. net bandwidth used: %.2f Mbit/sec", 1102dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent * 8.0 / delayUs); 1103dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber } 1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setInt32Data(mRTPSeqNo - 1); 1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.push_back(mTSQueue); 1108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mHistoryLength; 1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mHistoryLength > kMaxHistoryLength) { 1111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = *mHistory.begin(); 1112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.erase(mHistory.begin()); 1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber --mHistoryLength; 1115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); 1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 1120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return size; 1123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseRTCP( 1126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer) { 1127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data = buffer->data(); 1128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t size = buffer->size(); 1129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (size > 0) { 1131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < 8) { 1132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Too short to be a valid RTCP header 1133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] >> 6) != 2) { 1137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Unsupported version. 1138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 1139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (data[0] & 0x20) { 1142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Padding present. 1143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t paddingLength = data[size - 1]; 1145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (paddingLength + 12 > size) { 1147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // If we removed this much padding we'd end up with something 1148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // that's too short to be a valid RTP header. 1149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= paddingLength; 1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < headerLength) { 1158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Only received a partial packet? 1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (data[1]) { 1163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 200: 1164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 201: // RR 1165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 202: // SDES 1166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 203: 1167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 204: // APP 1168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1170efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 1171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 205: // TSFB (transport layer specific feedback) 1172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber parseTSFB(data, headerLength); 1173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1174efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 1175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 206: // PSFB (payload specific feedback) 1177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber hexdump(data, headerLength); 1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGW("Unknown RTCP packet type %u of size %d", 1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (unsigned)data[1], headerLength); 1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data += headerLength; 1189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= headerLength; 1190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1195efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 1196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseTSFB( 1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data, size_t size) { 1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] & 0x1f) != 1) { 1199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; // We only support NACK for now. 1200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t srcId = U32_AT(&data[8]); 1203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (srcId != kSourceID) { 1204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 12; i < size; i += 4) { 1208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t seqNo = U16_AT(&data[i]); 1209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t blp = U16_AT(&data[i + 2]); 1210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber List<sp<ABuffer> >::iterator it = mHistory.begin(); 1212efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber bool foundSeqNo = false; 1213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (it != mHistory.end()) { 1214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer = *it; 1215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t bufferSeqNo = buffer->int32Data() & 0xffff; 1217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1218efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber bool retransmit = false; 1219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (bufferSeqNo == seqNo) { 1220efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransmit = true; 1221efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else if (blp != 0) { 1222efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber for (size_t i = 0; i < 16; ++i) { 1223efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if ((blp & (1 << i)) 1224efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) { 1225efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber blp &= ~(1 << i); 1226efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransmit = true; 1227efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1228efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1229efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1231efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (retransmit) { 1232efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("retransmitting seqNo %d", bufferSeqNo); 1233efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1234efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size()); 1235efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber uint8_t *rtp = retransRTP->data(); 1236efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber memcpy(rtp, buffer->data(), 12); 1237efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff; 1238efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[3] = mRTPRetransmissionSeqNo & 0xff; 1239efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[12] = (bufferSeqNo >> 8) & 0xff; 1240efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[13] = bufferSeqNo & 0xff; 1241efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12); 1242efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1243efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ++mRTPRetransmissionSeqNo; 1244efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1245efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sendPacket( 1246efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID, 1247efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransRTP->data(), retransRTP->size()); 1248efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1249efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (bufferSeqNo == seqNo) { 1250efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber foundSeqNo = true; 1251efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1252efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1253efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (foundSeqNo && blp == 0) { 1254efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber break; 1255efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++it; 1259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1261efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (!foundSeqNo || blp != 0) { 1262efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("Some sequence numbers were no longer available for " 1263efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber "retransmission"); 1264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1269efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 1270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1271496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() { 1272496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 1273496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber const sp<Track> &track = mTracks.valueAt(i); 1274496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1275496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber track->converter()->requestIDRFrame(); 1276496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 1277496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 1278496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1279bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::sendPacket( 1280bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID, const void *data, size_t size) { 1281bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mNetSession->sendRequest(sessionID, data, size); 1282bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 1283bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 128428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberbool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { 128528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mAllTracksHavePacketizerIndex) { 128628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return true; 128728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 128828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 128928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 129028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) { 129128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return false; 129228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 129328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 129428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 129528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mAllTracksHavePacketizerIndex = true; 129628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 129728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return true; 129828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 129928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1300eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huberstatic inline size_t MIN(size_t a, size_t b) { 1301eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber return (a < b) ? a : b; 1302eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber} 1303eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber 130428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( 130528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber size_t trackIndex, const sp<ABuffer> &accessUnit) { 130628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 130728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 130828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint32_t flags = 0; 130928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 131028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool isHDCPEncrypted = false; 131128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint64_t inputCTR; 131228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint8_t HDCP_private_data[16]; 131328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mHDCP != NULL && !track->isAudio()) { 131428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber isHDCPEncrypted = true; 131528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1316eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber#if 0 1317eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber ALOGI("in:"); 1318eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber hexdump(accessUnit->data(), MIN(64, accessUnit->size())); 1319eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber#endif 1320eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber 1321eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber if (mTempAccessUnit == NULL 1322eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber || mTempAccessUnit->capacity() < accessUnit->size()) { 1323eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber mTempAccessUnit = new ABuffer(accessUnit->size()); 1324eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber } 1325eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber 1326eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber memcpy(mTempAccessUnit->data(), accessUnit->data(), accessUnit->size()); 1327eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber 132828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = mHDCP->encrypt( 1329eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber mTempAccessUnit->data(), mTempAccessUnit->size(), 133028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber trackIndex /* streamCTR */, 133128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber &inputCTR, 133228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber accessUnit->data()); 133328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 133428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 133528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ALOGE("Failed to HDCP-encrypt media data (err %d)", 133628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber err); 133728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 133828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return err; 1339eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber } else { 1340eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber#if 0 1341eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber ALOGI("out:"); 1342eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber hexdump(accessUnit->data(), MIN(64, accessUnit->size())); 1343eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber ALOGI("inputCTR: 0x%016llx", inputCTR); 1344eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber#endif 134528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 134628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 134728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[0] = 0x00; 134828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 134928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[1] = 135028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((trackIndex >> 30) & 3) << 1) | 1; 135128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 135328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[3] = 135528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((trackIndex >> 15) & 0x7f) << 1) | 1; 135628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 135828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[5] = 136028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ((trackIndex & 0x7f) << 1) | 1; 136128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[6] = 0x00; 136328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[7] = 136528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 60) & 0x0f) << 1) | 1; 136628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 136828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[9] = 137028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 45) & 0x7f) << 1) | 1; 137128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 137328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[11] = 137528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 30) & 0x7f) << 1) | 1; 137628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 137828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[13] = 138028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 15) & 0x7f) << 1) | 1; 138128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 138328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[15] = 138528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ((inputCTR & 0x7f) << 1) | 1; 138628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::IS_ENCRYPTED; 138828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 138928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 139028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber int64_t timeUs = ALooper::GetNowUs(); 139128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 139228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::EMIT_PCR; 139328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::EMIT_PAT_AND_PMT; 139428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 139528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mPrevTimeUs = timeUs; 139628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 139728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 139828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> packets; 139928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mPacketizer->packetize( 140028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->packetizerTrackIndex(), accessUnit, &packets, flags, 1401019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber !isHDCPEncrypted ? NULL : HDCP_private_data, 1402019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data)); 140328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 140428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t offset = 0; 140528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber offset < packets->size(); offset += 188) { 140628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool lastTSPacket = (offset + 188 >= packets->size()); 140728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 140828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // We're only going to flush video, audio packets are 140928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // much more frequent and would waste all that space 141028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // available in a full sized UDP packet. 141128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool flush = 141228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber lastTSPacket 141328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber && ((ssize_t)trackIndex == mVideoTrackIndex); 141428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 141528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber appendTSData( 141628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber packets->data() + offset, 141728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 188, 141828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber true /* timeDiscontinuity */, 141928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flush); 142028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 142128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 142228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#if LOG_TRANSPORT_STREAM 142328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mLogFile != NULL) { 142428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber fwrite(packets->data(), 1, packets->size(), mLogFile); 142528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 142628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#endif 142728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 142828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return OK; 142928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 143028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 143128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() { 143228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (;;) { 143328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool gotMoreData = false; 143428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 143528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber size_t trackIndex = mTracks.keyAt(i); 143628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<Track> &track = mTracks.valueAt(i); 143728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 143828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit = track->dequeueAccessUnit(); 143928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (accessUnit != NULL) { 144028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeAccessUnit(trackIndex, accessUnit); 144128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 144228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 144328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return err; 144428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 144528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 144628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber gotMoreData = true; 144728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 144828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 144928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 145028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (!gotMoreData) { 145128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 145228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 145328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 145428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 145528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return OK; 145628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 145728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 1459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1460