PlaybackSession.cpp revision ad0d97c7cf620e96a0b088dd9461645a3f8900b7
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" 27e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include "include/avc_utils.h" 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h> 30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h> 31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h> 32b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.h> 33e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h> 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h> 38082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h> 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h> 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaExtractor.h> 43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h> 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h> 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h> 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h> 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h> 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h> 50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxRTPPacketSize = 1500; 54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188; 55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler { 5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber enum { 5896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber kWhatStopped, 5996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber }; 6096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 6196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber Track(const sp<AMessage> ¬ify, 6296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<ALooper> &pullLooper, 63e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 64e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 65e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter); 66e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> getFormat(); 68b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool isAudio() const; 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter() const; 71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex() const; 72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber void setPacketizerTrackIndex(size_t index); 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t start(); 7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void stopAsync(); 7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 7828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber void queueAccessUnit(const sp<ABuffer> &accessUnit); 7928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> dequeueAccessUnit(); 8028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 8296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber virtual void onMessageReceived(const sp<AMessage> &msg); 83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 8696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber enum { 8796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber kWhatMediaPullerStopped, 8896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber }; 8996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 9096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> mNotify; 91e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mPullLooper; 92e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mCodecLooper; 93e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> mMediaPuller; 94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> mConverter; 95e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool mStarted; 96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t mPacketizerTrackIndex; 97b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool mIsAudio; 9828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber List<sp<ABuffer> > mQueuedAccessUnits; 99b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 100b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber static bool IsAudioFormat(const sp<AMessage> &format); 101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 105e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track( 10696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<AMessage> ¬ify, 107e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &pullLooper, 108e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter) 11196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber : mNotify(notify), 11296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mPullLooper(pullLooper), 113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mCodecLooper(codecLooper), 114e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mMediaPuller(mediaPuller), 115e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mConverter(converter), 116e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted(false), 117b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mPacketizerTrackIndex(-1), 118b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) { 119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() { 12296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(!mStarted); 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 125b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static 126b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( 127b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber const sp<AMessage> &format) { 128b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber AString mime; 129b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber CHECK(format->findString("mime", &mime)); 130b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 131b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return !strncasecmp(mime.c_str(), "audio/", 6); 132b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 133b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter->getOutputFormat(); 136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 138b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const { 139b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return mIsAudio; 140b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 141b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter; 144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const { 147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mPacketizerTrackIndex; 148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) { 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LT(mPacketizerTrackIndex, 0); 152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizerTrackIndex = index; 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 155e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() { 156ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber ALOGV("Track::start isAudio=%d", mIsAudio); 157ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 15896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(!mStarted); 159e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 161e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 162e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 163e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->start(); 164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == OK) { 167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = true; 168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 17396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() { 17496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("Track::stopAsync isAudio=%d", mIsAudio); 175ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 17696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mConverter->shutdownAsync(); 17796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 17896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id()); 179e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 180ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber if (mStarted && mMediaPuller != NULL) { 18196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mMediaPuller->stopAsync(msg); 18296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } else { 18396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->post(); 184e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 18596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber} 186e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 18796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived( 18896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<AMessage> &msg) { 18996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber switch (msg->what()) { 19096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatMediaPullerStopped: 19196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 19296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mConverter.clear(); 193a438123bd96c7faf145683876702387efe5628d9Andreas Huber 19496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mStarted = false; 195e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 19696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> notify = mNotify->dup(); 19796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setInt32("what", kWhatStopped); 19896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->post(); 19977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 20077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video"); 20196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 20296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 20396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 20496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber default: 20596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber TRESPASS(); 20696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 207e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 208e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 20928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( 21028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<ABuffer> &accessUnit) { 21128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.push_back(accessUnit); 21228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 21328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 21428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() { 21528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mQueuedAccessUnits.empty()) { 21628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return NULL; 21728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 21828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 21928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin(); 22028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(accessUnit != NULL); 22128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 22228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.erase(mQueuedAccessUnits.begin()); 22328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 22428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return accessUnit; 22528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 22628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession( 230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ANetworkSession> &netSession, 2310b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber const sp<AMessage> ¬ify, 232bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const in_addr &interfaceAddr, 233b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber const sp<IHDCP> &hdcp) 234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mNetSession(netSession), 235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 236bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInterfaceAddr(interfaceAddr), 237b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mHDCP(hdcp), 238ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber mWeAreDead(false), 239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs(), 240e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex(-1), 241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)), 242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPrevTimeUs(-1ll), 243bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode(TRANSPORT_UDP), 24428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mAllTracksHavePacketizerIndex(false), 245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel(0), 246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel(0), 247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort(0), 248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID(0), 249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID(0), 250efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 251efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID(0), 252efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID(0), 253efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 254bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort(0), 255bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort(0), 256bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected(false), 257bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected(false), 258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSeqNo(0), 259efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 260efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSeqNo(0), 261efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime(0), 263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime(0), 264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPSent(0), 265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent(0), 266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumSRsSent(0), 267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending(false), 26877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mHistoryLength(0) 26977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH 27077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ,mFirstPacketTimeUs(-1ll), 27177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ,mTotalBytesSent(0ll) 27277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif 273774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 274774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber ,mLogFile(NULL) 275774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 276774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber{ 277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 278774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 279774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 280774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = fopen("/system/etc/log.ts", "wb"); 281774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init( 285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const char *clientIP, int32_t clientRtp, int32_t clientRtcp, 286bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TransportMode transportMode) { 287bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientIP = clientIP; 288bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = setupPacketizer(); 290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return err; 293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 295bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mTransportMode = transportMode; 296bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 297bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (transportMode == TRANSPORT_TCP_INTERLEAVED) { 298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = clientRtp; 299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = clientRtcp; 300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPPort = 0; 301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPChannel = 0; 309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPChannel = 0; 310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 311bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP) { 312bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // XXX This is wrong, we need to allocate sockets here, we only 313bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // need to do this because the dongles are not establishing their 314bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber // end until after PLAY instead of before SETUP. 315bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort = 20000; 316bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPSessionID = 0; 317bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPSessionID = 0; 318bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTPPort = clientRtp; 319bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mClientRTCPPort = clientRtcp; 320bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 321bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber updateLiveness(); 322bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 323bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 324bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int serverRtp; 326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 329efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 330efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 331efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<AMessage> rtpRetransmissionNotify = 332efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber new AMessage(kWhatRTPRetransmissionNotify, id()); 333efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 334efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<AMessage> rtcpRetransmissionNotify = 335efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber new AMessage(kWhatRTCPRetransmissionNotify, id()); 336efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 337efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (serverRtp = 15550;; serverRtp += 2) { 339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t rtpSession; 340bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 341bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 342bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 343bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 344bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 345bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 346bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber serverRtp, clientIP, clientRtp, 347bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &rtpSession); 348bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (err != OK) { 351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("failed to create RTP socket on port %d", serverRtp); 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber continue; 353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 355efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtcpSession = 0; 356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 357efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (clientRtcp >= 0) { 358efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (mTransportMode == TRANSPORT_UDP) { 359efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createUDPSession( 360efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1, clientIP, clientRtcp, 361efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpNotify, &rtcpSession); 362efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else { 363efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createTCPDatagramSession( 364efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1, clientIP, clientRtcp, 365efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpNotify, &rtcpSession); 366efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 368efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 369efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("failed to create RTCP socket on port %d", serverRtp + 1); 370efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 371efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 372efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 373efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 376efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 377bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_UDP) { 378efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtpRetransmissionSession; 379efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 380bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createUDPSession( 381efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + kRetransmissionPortOffset, 382efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientIP, 383efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientRtp + kRetransmissionPortOffset, 384efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtpRetransmissionNotify, 385efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber &rtpRetransmissionSession); 386efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 387efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 388efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtcpSession); 389efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 390efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 391efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 393efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber CHECK_GE(clientRtcp, 0); 394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 395efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber int32_t rtcpRetransmissionSession; 396efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber err = mNetSession->createUDPSession( 397efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber serverRtp + 1 + kRetransmissionPortOffset, 398efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientIP, 399efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber clientRtp + 1 + kRetransmissionPortOffset, 400efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtcpRetransmissionNotify, 401efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber &rtcpRetransmissionSession); 402efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 403efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (err != OK) { 404efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpRetransmissionSession); 405efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtcpSession); 406efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mNetSession->destroySession(rtpSession); 407efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber continue; 408efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 409efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 410efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID = rtpRetransmissionSession; 411efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID = rtcpRetransmissionSession; 412efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 413efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("rtpRetransmissionSessionID = %d, " 414efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber "rtcpRetransmissionSessionID = %d", 415efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtpRetransmissionSession, rtcpRetransmissionSession); 416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 417efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 418efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 419efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPPort = serverRtp; 420efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPSessionID = rtpSession; 421efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPSessionID = rtcpSession; 422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 423efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession); 424efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber break; 425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTPPort == 0) { 428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return UNKNOWN_ERROR; 429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() { 437774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM 438774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber if (mLogFile != NULL) { 439774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber fclose(mLogFile); 440774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber mLogFile = NULL; 441774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber } 442774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif 443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 445d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 446d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mRTPPort; 447d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 448d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 449d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 450d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mLastLifesignUs; 451d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 452d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() { 454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs = ALooper::GetNowUs(); 455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() { 458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 460bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 461bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 462bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 463bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::finishPlay() { 46492f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber // XXX Give the dongle a second to bind its sockets. 46592f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber (new AMessage(kWhatFinishPlay, id()))->post(1000000ll); 466bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 467bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 468bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 469bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay() { 470bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode != TRANSPORT_TCP) { 471bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return onFinishPlay2(); 472bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 473bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 474bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id()); 475bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 476bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber status_t err = mNetSession->createTCPDatagramSession( 477bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort, mClientIP.c_str(), mClientRTPPort, 478bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtpNotify, &mRTPSessionID); 479bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 480bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (err != OK) { 481bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 482bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 483bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 484bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mClientRTCPPort >= 0) { 485bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id()); 486bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 487bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber err = mNetSession->createTCPDatagramSession( 488bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort, 489bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber rtcpNotify, &mRTCPSessionID); 490bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 491bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 492bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return err; 493bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 494bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 495bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay2() { 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID != 0) { 497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 500e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 50196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start()); 502e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 503e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 504bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 505bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("what", kWhatSessionEstablished); 506bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 507bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 508e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() { 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 51796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() { 51896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("destroyAsync"); 519a438123bd96c7faf145683876702387efe5628d9Andreas Huber 52096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 52196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mTracks.valueAt(i)->stopAsync(); 522a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 523a438123bd96c7faf145683876702387efe5628d9Andreas Huber} 524a438123bd96c7faf145683876702387efe5628d9Andreas Huber 525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived( 526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &msg) { 527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTPNotify: 529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatRTCPNotify: 530efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 531efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber case kWhatRTPRetransmissionNotify: 532efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber case kWhatRTCPRetransmissionNotify: 533efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t reason; 536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("reason", &reason)); 537d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 538d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (reason) { 539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatError: 540d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t err; 545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t errorOccuredDuringSend; 548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("send", &errorOccuredDuringSend)); 549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber AString detail; 551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findString("detail", &detail)); 552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 553efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if ((msg->what() == kWhatRTPNotify 554efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 555efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber || msg->what() == kWhatRTPRetransmissionNotify 556efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 557efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ) && !errorOccuredDuringSend) { 558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // This is ok, we don't expect to receive anything on 559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // the RTP socket. 560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 562d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("An error occurred during %s in session %d " 564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber "(%d, '%s' (%s)).", 565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber errorOccuredDuringSend ? "send" : "receive", 566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sessionID, 567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err, 568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber detail.c_str(), 569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber strerror(-err)); 570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNetSession->destroySession(sessionID); 572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (sessionID == mRTPSessionID) { 574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTPSessionID = 0; 575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (sessionID == mRTCPSessionID) { 576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mRTCPSessionID = 0; 577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 578efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 579efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber else if (sessionID == mRTPRetransmissionSessionID) { 580efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID = 0; 581efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else if (sessionID == mRTCPRetransmissionSessionID) { 582efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTCPRetransmissionSessionID = 0; 583efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 584efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 586ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notifySessionDead(); 587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case ANetworkSession::kWhatDatagram: 591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t sessionID; 593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data; 596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findBuffer("data", &data)); 597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 599efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (msg->what() == kWhatRTCPNotify 600efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 601efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber || msg->what() == kWhatRTCPRetransmissionNotify 602efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 603efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ) 604efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber { 605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber err = parseRTCP(data); 606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 608d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 610bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case ANetworkSession::kWhatConnected: 611bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 612bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK_EQ(mTransportMode, TRANSPORT_TCP); 613bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 614bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID; 615bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(msg->findInt32("sessionID", &sessionID)); 616bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 617bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (sessionID == mRTPSessionID) { 618bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTPConnected); 619bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTPConnected = true; 620bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTP Session now connected."); 621bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else if (sessionID == mRTCPSessionID) { 622bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber CHECK(!mRTCPConnected); 623bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mRTCPConnected = true; 624bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber ALOGI("RTCP Session now connected."); 625bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } else { 626bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber TRESPASS(); 627bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 628bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 629bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mRTPConnected 630bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber && (mClientRTCPPort < 0 || mRTCPConnected)) { 631bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay2(); 632bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 633bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 634bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 635bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatSendSR: 643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = false; 645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mRTCPSessionID == 0) { 647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber onSendSR(); 651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber scheduleSendSR(); 653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatConverterNotify: 657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 6586360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber if (mWeAreDead) { 6596360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber ALOGV("dropping msg '%s' because we're dead", 6606360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber msg->debugString().c_str()); 6616360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber 6626360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber break; 6636360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber } 6646360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber 665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (what == Converter::kWhatAccessUnit) { 672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t packetizerTrackIndex = track->packetizerTrackIndex(); 675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 67628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (packetizerTrackIndex < 0) { 677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber packetizerTrackIndex = 678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mPacketizer->addTrack(track->getFormat()); 679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 68028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK_GE(packetizerTrackIndex, 0); 681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 68228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->setPacketizerTrackIndex(packetizerTrackIndex); 683b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 68428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (allTracksHavePacketizerIndex()) { 68528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeQueuedAccessUnits(); 686b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 687b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber if (err != OK) { 688ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notifySessionDead(); 689b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber break; 690b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 691b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber } 69228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 693b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 69428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit; 69528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 69728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (!allTracksHavePacketizerIndex()) { 69828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->queueAccessUnit(accessUnit); 69928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 70028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 70228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeAccessUnit(trackIndex, accessUnit); 703774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 70428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 705ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notifySessionDead(); 706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 70728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (what == Converter::kWhatEOS) { 709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatEOS); 710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("output EOS on track %d", trackIndex); 712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 713d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t index = mTracks.indexOfKey(trackIndex); 714d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_GE(index, 0); 715d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter = 717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(index)->converter(); 718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->unregisterHandler(converter->id()); 719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.removeItemsAt(index); 721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mTracks.isEmpty()) { 723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("Reached EOS"); 724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatError); 727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("converter signaled error %d", err); 732ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber 733ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notifySessionDead(); 734d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 735d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 738bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber case kWhatFinishPlay: 739bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber { 740bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber onFinishPlay(); 741bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 742bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 743bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 74496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatTrackNotify: 74596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 74696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber int32_t what; 74796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findInt32("what", &what)); 74896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 74996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber size_t trackIndex; 75096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 75196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 75296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == Track::kWhatStopped) { 75377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("Track %d stopped", trackIndex); 75496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 75577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber sp<Track> track = mTracks.valueFor(trackIndex); 75677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber looper()->unregisterHandler(track->id()); 75777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mTracks.removeItem(trackIndex); 75877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber track.clear(); 75977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 76077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber if (!mTracks.isEmpty()) { 76177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("not all tracks are stopped yet"); 76296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 76396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 76496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 76596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mPacketizer.clear(); 76696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 76796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if ENABLE_RETRANSMISSION 76896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mRTCPRetransmissionSessionID != 0) { 76996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mNetSession->destroySession(mRTCPRetransmissionSessionID); 77096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 77196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 77296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mRTPRetransmissionSessionID != 0) { 77396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mNetSession->destroySession(mRTPRetransmissionSessionID); 77496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 77596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif 77696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 77796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mRTCPSessionID != 0) { 77896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mNetSession->destroySession(mRTCPSessionID); 77996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 78096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 78196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (mRTPSessionID != 0) { 78296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mNetSession->destroySession(mRTPSessionID); 78396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 78496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 78596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> notify = mNotify->dup(); 78696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setInt32("what", kWhatSessionDestroyed); 78796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->post(); 78896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 78996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 79096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 79196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer() { 798e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mPacketizer = new TSPacketizer; 799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 800e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addVideoSource(); 801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 802e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 803e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 804e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 805e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 806e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addAudioSource(); 807e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 808d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 809e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource( 810e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) { 811e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> pullLooper = new ALooper; 812e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->setName("pull_looper"); 813e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 814e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->start( 815e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 816e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 817ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 818d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 819e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> codecLooper = new ALooper; 820e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->setName("codec_looper"); 821e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 822e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->start( 823e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 824e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 825ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 826e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 827e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t trackIndex; 828e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 829e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify; 830e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 831e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber trackIndex = mTracks.size(); 832e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 833d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> format; 834d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = convertMetaDataToMessage(source->getFormat(), &format); 835d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(err, (status_t)OK); 836d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 837e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 838e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32("store-metadata-in-buffers", true); 839d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 840e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32( 841e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber "color-format", OMX_COLOR_FormatAndroidOpaque); 842e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 843d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 844e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify = new AMessage(kWhatConverterNotify, id()); 845e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 846d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 847d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> converter = 848e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber new Converter(notify, codecLooper, format); 8493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 8503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber if (converter->initCheck() != OK) { 8513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber return converter->initCheck(); 8523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 85366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 854d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->registerHandler(converter); 855d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 85696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id()); 85796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setSize("trackIndex", trackIndex); 85896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 85996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<MediaPuller> puller = new MediaPuller(source, notify); 86096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber pullLooper->registerHandler(puller); 86196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 862e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (numInputBuffers != NULL) { 863e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber *numInputBuffers = converter->getInputBufferCount(); 864e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 86566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 86696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify = new AMessage(kWhatTrackNotify, id()); 86796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setSize("trackIndex", trackIndex); 86896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 86996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<Track> track = new Track( 87096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify, pullLooper, codecLooper, puller, converter); 87196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 87296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber looper()->registerHandler(track); 87396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 87496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mTracks.add(trackIndex, track); 875e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 876e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 877e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex = trackIndex; 878e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 879e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 880e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 881e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 882e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 883e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource() { 884e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height()); 885e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 886e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaSource> videoSource = 88772ff5903df5f409ea83f74c363a52f0745ced8b8Andreas Huber new RepeaterSource(source, 24.0 /* rateHz */); 888e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 889e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t numInputBuffers; 890e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers); 891e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 892e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 893e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 894e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 89566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 8965a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber err = source->setMaxAcquiredBufferCount(numInputBuffers); 89766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(err, (status_t)OK); 89866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 8990b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber mBufferQueue = source->getBufferQueue(); 9000b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 901e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 902e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 903e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 904e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource() { 905082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber sp<AudioSource> audioSource = new AudioSource( 9061646a0fed94c30a44128b3c379736def4b332033Andreas Huber AUDIO_SOURCE_REMOTE_SUBMIX, 907082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 48000 /* sampleRate */, 9081646a0fed94c30a44128b3c379736def4b332033Andreas Huber 2 /* channelCount */); 909082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 9107977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber if (audioSource->initCheck() == OK) { 9117977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber audioSource->setUseLooperTime(true); 912082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 913e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addSource( 914e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* isVideo */, audioSource, NULL /* numInputBuffers */); 9157977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber } 916e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 917e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGW("Unable to instantiate audio source"); 918082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 919d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 921d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9220b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Hubersp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 9230b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber return mBufferQueue; 9240b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9250b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9260b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::width() const { 927207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber return 1280; 9280b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9290b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 9300b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::height() const { 931207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber return 720; 9320b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 9330b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::scheduleSendSR() { 935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mSendSRPending) { 936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return; 937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mSendSRPending = true; 940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs); 941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) { 944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // TODO: Use macros/utility functions to clean up all the bitshifts below. 947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 0; 949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 200; // SR 950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = 0; 951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = 6; 952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[8] = mLastNTPTime >> (64 - 8); 958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[9] = (mLastNTPTime >> (64 - 16)) & 0xff; 959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[10] = (mLastNTPTime >> (64 - 24)) & 0xff; 960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[11] = (mLastNTPTime >> 32) & 0xff; 961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[12] = (mLastNTPTime >> 24) & 0xff; 962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[13] = (mLastNTPTime >> 16) & 0xff; 963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[14] = (mLastNTPTime >> 8) & 0xff; 964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[15] = mLastNTPTime & 0xff; 965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[16] = (mLastRTPTime >> 24) & 0xff; 967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[17] = (mLastRTPTime >> 16) & 0xff; 968d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[18] = (mLastRTPTime >> 8) & 0xff; 969d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[19] = mLastRTPTime & 0xff; 970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[20] = mNumRTPSent >> 24; 972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[21] = (mNumRTPSent >> 16) & 0xff; 973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[22] = (mNumRTPSent >> 8) & 0xff; 974d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[23] = mNumRTPSent & 0xff; 975d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 976d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[24] = mNumRTPOctetsSent >> 24; 977d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[25] = (mNumRTPOctetsSent >> 16) & 0xff; 978d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[26] = (mNumRTPOctetsSent >> 8) & 0xff; 979d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[27] = mNumRTPOctetsSent & 0xff; 980d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 981d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + 28); 982d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 983d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 984d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) { 985d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *data = buffer->data() + buffer->size(); 986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[0] = 0x80 | 1; 987d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[1] = 202; // SDES 988d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[4] = kSourceID >> 24; 989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[5] = (kSourceID >> 16) & 0xff; 990d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[6] = (kSourceID >> 8) & 0xff; 991d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[7] = kSourceID & 0xff; 992d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 993d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t offset = 8; 994d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 995d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 1; // CNAME 996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kCNAME = "someone@somewhere"; 998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kCNAME); 999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kCNAME, strlen(kCNAME)); 1001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kCNAME); 1002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 7; // NOTE 1004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber static const char *kNOTE = "Hell's frozen over."; 1006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = strlen(kNOTE); 1007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(&data[offset], kNOTE, strlen(kNOTE)); 1009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber offset += strlen(kNOTE); 1010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((offset % 4) > 0) { 1014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t count = 4 - (offset % 4); 1015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (count) { 1016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 3: 1017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 2: 1019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 1: 1021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[offset++] = 0; 1022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t numWords = (offset / 4) - 1; 1026d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[2] = numWords >> 8; 1027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data[3] = numWords & 0xff; 1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(buffer->offset(), buffer->size() + offset); 1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber// static 1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() { 1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t nowUs = ALooper::GetNowUs(); 1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll; 1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t hi = nowUs / 1000000ll; 1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll; 1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return (hi << 32) | lo; 1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onSendSR() { 1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> buffer = new ABuffer(1500); 1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber buffer->setRange(0, 0); 1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSR(buffer); 1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber addSDES(buffer); 1050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1051bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTCPChannel); 1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", buffer); 1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1058bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTCPSessionID, buffer->data(), buffer->size()); 1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumSRsSent; 1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::appendTSData( 1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const void *data, size_t size, bool timeDiscontinuity, bool flush) { 1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(size, 188); 1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity()); 1069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(mTSQueue->data() + mTSQueue->size(), data, size); 1071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, mTSQueue->size() + size); 1072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (flush || mTSQueue->size() == mTSQueue->capacity()) { 1074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // flush 1075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int64_t nowUs = ALooper::GetNowUs(); 107777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 107877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH 1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mFirstPacketTimeUs < 0ll) { 1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mFirstPacketTimeUs = nowUs; 1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 108277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif 1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // 90kHz time scale 108577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber uint32_t rtpTime = (nowUs * 9ll) / 100ll; 1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint8_t *rtp = mTSQueue->data(); 1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[0] = 0x80; 1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0); // M-bit 1090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[2] = (mRTPSeqNo >> 8) & 0xff; 1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[3] = mRTPSeqNo & 0xff; 1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[4] = rtpTime >> 24; 1093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[5] = (rtpTime >> 16) & 0xff; 1094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[6] = (rtpTime >> 8) & 0xff; 1095d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[7] = rtpTime & 0xff; 1096d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[8] = kSourceID >> 24; 1097d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[9] = (kSourceID >> 16) & 0xff; 1098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[10] = (kSourceID >> 8) & 0xff; 1099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber rtp[11] = kSourceID & 0xff; 1100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mRTPSeqNo; 1102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mNumRTPSent; 1103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNumRTPOctetsSent += mTSQueue->size() - 12; 1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastRTPTime = rtpTime; 1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastNTPTime = GetNowNTP(); 1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1108bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) { 1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> notify = mNotify->dup(); 1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("what", kWhatBinaryData); 1111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<ABuffer> data = new ABuffer(mTSQueue->size()); 1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber memcpy(data->data(), rtp, mTSQueue->size()); 1114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setInt32("channel", mRTPChannel); 1116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->setBuffer("data", data); 1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber notify->post(); 1118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1119bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sendPacket(mRTPSessionID, rtp, mTSQueue->size()); 1120dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 112177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH 1122dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent += mTSQueue->size(); 1123dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs; 1124dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber 1125dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber if (delayUs > 0ll) { 1126dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber ALOGV("approx. net bandwidth used: %.2f Mbit/sec", 1127dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber mTotalBytesSent * 8.0 / delayUs); 1128dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber } 112977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif 1130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setInt32Data(mRTPSeqNo - 1); 1133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.push_back(mTSQueue); 1134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++mHistoryLength; 1135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mHistoryLength > kMaxHistoryLength) { 1137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = *mHistory.begin(); 1138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mHistory.erase(mHistory.begin()); 1139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber --mHistoryLength; 1141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else { 1142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188); 1143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTSQueue->setRange(0, 12); 1146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return size; 1149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseRTCP( 1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer) { 1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data = buffer->data(); 1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t size = buffer->size(); 1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (size > 0) { 1157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < 8) { 1158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Too short to be a valid RTCP header 1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] >> 6) != 2) { 1163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Unsupported version. 1164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; 1165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (data[0] & 0x20) { 1168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Padding present. 1169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t paddingLength = data[size - 1]; 1171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (paddingLength + 12 > size) { 1173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // If we removed this much padding we'd end up with something 1174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // that's too short to be a valid RTP header. 1175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= paddingLength; 1179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4; 1182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (size < headerLength) { 1184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber // Only received a partial packet? 1185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (data[1]) { 1189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 200: 1190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 201: // RR 1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 202: // SDES 1192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 203: 1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 204: // APP 1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1196efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 205: // TSFB (transport layer specific feedback) 1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber parseTSFB(data, headerLength); 1199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1200efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 1201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case 206: // PSFB (payload specific feedback) 1203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber hexdump(data, headerLength); 1204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 1207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 1208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGW("Unknown RTCP packet type %u of size %d", 1209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber (unsigned)data[1], headerLength); 1210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 1211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber data += headerLength; 1215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size -= headerLength; 1216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1221efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION 1222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseTSFB( 1223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const uint8_t *data, size_t size) { 1224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if ((data[0] & 0x1f) != 1) { 1225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_UNSUPPORTED; // We only support NACK for now. 1226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint32_t srcId = U32_AT(&data[8]); 1229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (srcId != kSourceID) { 1230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return ERROR_MALFORMED; 1231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber for (size_t i = 12; i < size; i += 4) { 1234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t seqNo = U16_AT(&data[i]); 1235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t blp = U16_AT(&data[i + 2]); 1236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber List<sp<ABuffer> >::iterator it = mHistory.begin(); 1238efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber bool foundSeqNo = false; 1239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber while (it != mHistory.end()) { 1240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ABuffer> &buffer = *it; 1241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber uint16_t bufferSeqNo = buffer->int32Data() & 0xffff; 1243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1244efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber bool retransmit = false; 1245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (bufferSeqNo == seqNo) { 1246efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransmit = true; 1247efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } else if (blp != 0) { 1248efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber for (size_t i = 0; i < 16; ++i) { 1249efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if ((blp & (1 << i)) 1250efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) { 1251efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber blp &= ~(1 << i); 1252efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransmit = true; 1253efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1254efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1255efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1257efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (retransmit) { 1258efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("retransmitting seqNo %d", bufferSeqNo); 1259efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1260efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size()); 1261efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber uint8_t *rtp = retransRTP->data(); 1262efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber memcpy(rtp, buffer->data(), 12); 1263efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff; 1264efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[3] = mRTPRetransmissionSeqNo & 0xff; 1265efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[12] = (bufferSeqNo >> 8) & 0xff; 1266efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber rtp[13] = bufferSeqNo & 0xff; 1267efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12); 1268efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1269efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ++mRTPRetransmissionSeqNo; 1270efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1271efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber sendPacket( 1272efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber mRTPRetransmissionSessionID, 1273efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber retransRTP->data(), retransRTP->size()); 1274efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1275efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (bufferSeqNo == seqNo) { 1276efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber foundSeqNo = true; 1277efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1278efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber 1279efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (foundSeqNo && blp == 0) { 1280efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber break; 1281efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber } 1282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ++it; 1285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1287efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber if (!foundSeqNo || blp != 0) { 1288efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber ALOGI("Some sequence numbers were no longer available for " 1289efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber "retransmission"); 1290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 1292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1295efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif 1296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1297496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() { 1298496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 1299496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber const sp<Track> &track = mTracks.valueAt(i); 1300496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1301496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber track->converter()->requestIDRFrame(); 1302496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 1303496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 1304496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1305bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::sendPacket( 1306bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber int32_t sessionID, const void *data, size_t size) { 1307bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return mNetSession->sendRequest(sessionID, data, size); 1308bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 1309bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 131028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberbool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() { 131128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mAllTracksHavePacketizerIndex) { 131228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return true; 131328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 131428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 131528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 131628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) { 131728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return false; 131828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 131928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 132028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 132128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mAllTracksHavePacketizerIndex = true; 132228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 132328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return true; 132428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 132528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 132628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit( 1327e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber size_t trackIndex, sp<ABuffer> accessUnit) { 132828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 132928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 133028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint32_t flags = 0; 133128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 133228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool isHDCPEncrypted = false; 133328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint64_t inputCTR; 133428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber uint8_t HDCP_private_data[16]; 133528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mHDCP != NULL && !track->isAudio()) { 133628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber isHDCPEncrypted = true; 133728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1338e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber if (IsIDR(accessUnit)) { 1339e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber // XXX remove this once the encoder takes care of this. 1340e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber accessUnit = mPacketizer->prependCSD( 1341e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber track->packetizerTrackIndex(), accessUnit); 1342eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber } 1343eb11600a248cfe5b95ddd3e5aaae02bd2ab65276Andreas Huber 134428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = mHDCP->encrypt( 1345e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber accessUnit->data(), accessUnit->size(), 134628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber trackIndex /* streamCTR */, 134728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber &inputCTR, 134828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber accessUnit->data()); 134928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 135128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ALOGE("Failed to HDCP-encrypt media data (err %d)", 135228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber err); 135328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return err; 135528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 135628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[0] = 0x00; 135828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 135928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[1] = 136028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((trackIndex >> 30) & 3) << 1) | 1; 136128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[2] = (trackIndex >> 22) & 0xff; 136328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[3] = 136528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((trackIndex >> 15) & 0x7f) << 1) | 1; 136628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[4] = (trackIndex >> 7) & 0xff; 136828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 136928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[5] = 137028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ((trackIndex & 0x7f) << 1) | 1; 137128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[6] = 0x00; 137328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[7] = 137528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 60) & 0x0f) << 1) | 1; 137628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[8] = (inputCTR >> 52) & 0xff; 137828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 137928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[9] = 138028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 45) & 0x7f) << 1) | 1; 138128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[10] = (inputCTR >> 37) & 0xff; 138328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[11] = 138528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 30) & 0x7f) << 1) | 1; 138628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[12] = (inputCTR >> 22) & 0xff; 138828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 138928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[13] = 139028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber (((inputCTR >> 15) & 0x7f) << 1) | 1; 139128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 139228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[14] = (inputCTR >> 7) & 0xff; 139328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 139428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber HDCP_private_data[15] = 139528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber ((inputCTR & 0x7f) << 1) | 1; 139628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1397e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#if 0 1398e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber ALOGI("HDCP_private_data:"); 1399e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber hexdump(HDCP_private_data, sizeof(HDCP_private_data)); 1400e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 1401e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber ABitReader br(HDCP_private_data, sizeof(HDCP_private_data)); 1402e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(13), 0); 1403e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3); 1404e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1405e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff); 1406e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1407e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), trackIndex & 0x7fff); 1408e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1409e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(11), 0); 1410e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf); 1411e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1412e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff); 1413e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1414e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff); 1415e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1416e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff); 1417e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1418e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(15), inputCTR & 0x7fff); 1419e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber CHECK_EQ(br.getBits(1), 1u); 1420e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#endif 1421e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber 142228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::IS_ENCRYPTED; 142328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 142428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 142528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber int64_t timeUs = ALooper::GetNowUs(); 142628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) { 142728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::EMIT_PCR; 142828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flags |= TSPacketizer::EMIT_PAT_AND_PMT; 142928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 143028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mPrevTimeUs = timeUs; 143128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 143228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 143328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> packets; 143428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mPacketizer->packetize( 143528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber track->packetizerTrackIndex(), accessUnit, &packets, flags, 1436019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber !isHDCPEncrypted ? NULL : HDCP_private_data, 1437019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data)); 143828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 143928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t offset = 0; 144028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber offset < packets->size(); offset += 188) { 144128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool lastTSPacket = (offset + 188 >= packets->size()); 144228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 144328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // We're only going to flush video, audio packets are 144428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // much more frequent and would waste all that space 144528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber // available in a full sized UDP packet. 144628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool flush = 144728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber lastTSPacket 144828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber && ((ssize_t)trackIndex == mVideoTrackIndex); 144928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 145028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber appendTSData( 145128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber packets->data() + offset, 145228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 188, 145328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber true /* timeDiscontinuity */, 145428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber flush); 145528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 145628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 145728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#if LOG_TRANSPORT_STREAM 145828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mLogFile != NULL) { 145928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber fwrite(packets->data(), 1, packets->size(), mLogFile); 146028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 146128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#endif 146228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 146328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return OK; 146428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 146528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 146628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() { 146728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (;;) { 146828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber bool gotMoreData = false; 146928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 147028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber size_t trackIndex = mTracks.keyAt(i); 147128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<Track> &track = mTracks.valueAt(i); 147228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 147328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit = track->dequeueAccessUnit(); 147428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (accessUnit != NULL) { 147528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber status_t err = packetizeAccessUnit(trackIndex, accessUnit); 147628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 147728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (err != OK) { 147828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return err; 147928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 148028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 148128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber gotMoreData = true; 148228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 148328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 148428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 148528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (!gotMoreData) { 148628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 148728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 148828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 148928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 149028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return OK; 149128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 149228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 1493ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() { 1494ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber // Inform WifiDisplaySource of our premature death (wish). 1495ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber sp<AMessage> notify = mNotify->dup(); 1496ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notify->setInt32("what", kWhatSessionDead); 1497ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notify->post(); 1498ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 1499ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber mWeAreDead = true; 1500ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber} 1501ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 1502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 1503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1504