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" 26e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include "include/avc_utils.h" 270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#include "WifiDisplaySource.h" 28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h> 30eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber#include <cutils/properties.h> 31b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.h> 32e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h> 33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h> 35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h> 36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h> 37082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h> 38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h> 39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h> 40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h> 41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h> 42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h> 430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber#include <media/stagefright/NuMediaExtractor.h> 44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h> 45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h> 46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h> 48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android { 50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 5196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler { 5296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber enum { 5396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber kWhatStopped, 5496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber }; 5596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber Track(const sp<AMessage> ¬ify, 5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<ALooper> &pullLooper, 58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter); 61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber Track(const sp<AMessage> ¬ify, const sp<AMessage> &format); 630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 644a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber void setRepeaterSource(const sp<RepeaterSource> &source); 654a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> getFormat(); 67b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool isAudio() const; 68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter() const; 70eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber const sp<RepeaterSource> &repeaterSource() const; 71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 72a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t mediaSenderTrackIndex() const; 73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber void setMediaSenderTrackIndex(size_t index); 74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t start(); 7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber void stopAsync(); 7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 785131d127a042ee88f903370be88845dc8c9f8578Andreas Huber void pause(); 795131d127a042ee88f903370be88845dc8c9f8578Andreas Huber void resume(); 805131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 8128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber void queueAccessUnit(const sp<ABuffer> &accessUnit); 8228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> dequeueAccessUnit(); 8328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 8490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber bool hasOutputBuffer(int64_t *timeUs) const; 8590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber void queueOutputBuffer(const sp<ABuffer> &accessUnit); 8690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> dequeueOutputBuffer(); 870224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber 880224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE 8990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber bool isSuspended() const; 900224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif 9190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 9290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber size_t countQueuedOutputBuffers() const { 9390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return mQueuedOutputBuffers.size(); 9490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 9590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 964a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber void requestIDRFrame(); 974a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected: 9996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber virtual void onMessageReceived(const sp<AMessage> &msg); 100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber virtual ~Track(); 101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate: 10396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber enum { 10496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber kWhatMediaPullerStopped, 10596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber }; 10696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 10796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> mNotify; 108e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mPullLooper; 109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> mCodecLooper; 110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<MediaPuller> mMediaPuller; 111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<Converter> mConverter; 1120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<AMessage> mFormat; 113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber bool mStarted; 114a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t mMediaSenderTrackIndex; 115b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber bool mIsAudio; 11628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber List<sp<ABuffer> > mQueuedAccessUnits; 1174a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber sp<RepeaterSource> mRepeaterSource; 11890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber List<sp<ABuffer> > mQueuedOutputBuffers; 11990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int64_t mLastOutputBufferQueuedTimeUs; 120b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 121b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber static bool IsAudioFormat(const sp<AMessage> &format); 122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber DISALLOW_EVIL_CONSTRUCTORS(Track); 124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}; 125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 126e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track( 12796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<AMessage> ¬ify, 128e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &pullLooper, 129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<ALooper> &codecLooper, 130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<MediaPuller> &mediaPuller, 131e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber const sp<Converter> &converter) 13296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber : mNotify(notify), 13396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mPullLooper(pullLooper), 134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mCodecLooper(codecLooper), 135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mMediaPuller(mediaPuller), 136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mConverter(converter), 137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted(false), 13890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mIsAudio(IsAudioFormat(mConverter->getOutputFormat())), 13990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mLastOutputBufferQueuedTimeUs(-1ll) { 140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1420b530f1050150bb751ae642d5a9dce34141d9475Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track( 1430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber const sp<AMessage> ¬ify, const sp<AMessage> &format) 1440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber : mNotify(notify), 1450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFormat(format), 1460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mStarted(false), 1470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mIsAudio(IsAudioFormat(format)), 1480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mLastOutputBufferQueuedTimeUs(-1ll) { 1490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber} 1500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() { 15296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(!mStarted); 153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 155b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static 156b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat( 157b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber const sp<AMessage> &format) { 158b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber AString mime; 159b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber CHECK(format->findString("mime", &mime)); 160b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 161b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return !strncasecmp(mime.c_str(), "audio/", 6); 162b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 163b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() { 1650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return mFormat != NULL ? mFormat : mConverter->getOutputFormat(); 166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 168b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const { 169b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber return mIsAudio; 170b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber} 171b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber 172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const { 173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mConverter; 174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 176eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huberconst sp<RepeaterSource> & 177eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas HuberWifiDisplaySource::PlaybackSession::Track::repeaterSource() const { 178eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber return mRepeaterSource; 179eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber} 180eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber 181a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const { 182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK_GE(mMediaSenderTrackIndex, 0); 183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return mMediaSenderTrackIndex; 184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 186a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex( 187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber size_t index) { 188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSenderTrackIndex = index; 189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 191e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() { 192ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber ALOGV("Track::start isAudio=%d", mIsAudio); 193ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 19496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(!mStarted); 195e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 196e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber status_t err = OK; 197e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 198e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (mMediaPuller != NULL) { 199e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber err = mMediaPuller->start(); 200e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 201e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 202e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err == OK) { 203e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mStarted = true; 204e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 205e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 206e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 207e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 208e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 20996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() { 21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGV("Track::stopAsync isAudio=%d", mIsAudio); 211ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 2120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (mConverter != NULL) { 2130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mConverter->shutdownAsync(); 2140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id()); 217e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 218ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber if (mStarted && mMediaPuller != NULL) { 2194a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mRepeaterSource != NULL) { 2204a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber // Let's unblock MediaPuller's MediaSource::read(). 2214a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mRepeaterSource->wakeUp(); 2224a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 2234a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mMediaPuller->stopAsync(msg); 22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } else { 2260b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mStarted = false; 22796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber msg->post(); 228e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber} 230e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 2315131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::pause() { 2325131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mMediaPuller->pause(); 2335131d127a042ee88f903370be88845dc8c9f8578Andreas Huber} 2345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 2355131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::resume() { 2365131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mMediaPuller->resume(); 2375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber} 2385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived( 24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber const sp<AMessage> &msg) { 24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber switch (msg->what()) { 24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatMediaPullerStopped: 24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mConverter.clear(); 245a438123bd96c7faf145683876702387efe5628d9Andreas Huber 24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mStarted = false; 247e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<AMessage> notify = mNotify->dup(); 24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setInt32("what", kWhatStopped); 25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->post(); 25177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 25277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video"); 25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber default: 25796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber TRESPASS(); 25896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 259e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 260e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 26128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit( 26228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber const sp<ABuffer> &accessUnit) { 26328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.push_back(accessUnit); 26428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 26528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 26628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() { 26728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber if (mQueuedAccessUnits.empty()) { 26828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return NULL; 26928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber } 27028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 27128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin(); 27228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(accessUnit != NULL); 27328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 27428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber mQueuedAccessUnits.erase(mQueuedAccessUnits.begin()); 27528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 27628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber return accessUnit; 27728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber} 27828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber 2794a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource( 2804a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber const sp<RepeaterSource> &source) { 2814a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mRepeaterSource = source; 2824a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber} 2834a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 2844a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() { 2854a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mIsAudio) { 2864a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber return; 2874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 2884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 2894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (mRepeaterSource != NULL) { 2904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mRepeaterSource->wakeUp(); 2914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 2924a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 2934a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber mConverter->requestIDRFrame(); 2944a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber} 2954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer( 29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int64_t *timeUs) const { 29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber *timeUs = 0ll; 29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mQueuedOutputBuffers.empty()) { 30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return false; 30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin(); 30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs)); 30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return true; 30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer( 31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber const sp<ABuffer> &accessUnit) { 31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mQueuedOutputBuffers.push_back(accessUnit); 31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs(); 31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() { 31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(!mQueuedOutputBuffers.empty()); 31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 32090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin(); 32190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin()); 32290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 32390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return outputBuffer; 32490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 32590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 3260224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE 32790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isSuspended() const { 32890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (!mQueuedOutputBuffers.empty()) { 32990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return false; 33090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 33290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber if (mLastOutputBufferQueuedTimeUs < 0ll) { 33390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // We've never seen an output buffer queued, but tracks start 33490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // out live, not suspended. 33590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return false; 33690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 33790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 33890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // If we've not seen new output data for 60ms or more, we consider 33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber // this track suspended for the time being. 34090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll; 34190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber} 3420224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif 34390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//////////////////////////////////////////////////////////////////////////////// 345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession( 347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<ANetworkSession> &netSession, 3480b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber const sp<AMessage> ¬ify, 349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber const in_addr &interfaceAddr, 3500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber const sp<IHDCP> &hdcp, 3510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber const char *path) 352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber : mNetSession(netSession), 353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mNotify(notify), 354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber mInterfaceAddr(interfaceAddr), 355b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber mHDCP(hdcp), 356a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mLocalRTPPort(-1), 357ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber mWeAreDead(false), 3585131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused(false), 359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs(), 360e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex(-1), 3610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mPrevTimeUs(-1ll), 3620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mPullExtractorPending(false), 3630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mPullExtractorGeneration(0), 3640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeRealUs(-1ll), 3650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeUs(-1ll) { 3660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (path != NULL) { 3670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mMediaPath.setTo(path); 3680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init( 3722aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber const char *clientIP, 3732aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber int32_t clientRtp, 3742aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber RTPSender::TransportMode rtpMode, 3752aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber int32_t clientRtcp, 3762aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber RTPSender::TransportMode rtcpMode, 37794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool enableAudio, 37894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool usePCMAudio, 37994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool enableVideo, 38094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber VideoFormats::ResolutionType videoResolutionType, 381308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang size_t videoResolutionIndex, 382308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::ProfileType videoProfileType, 383308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::LevelType videoLevelType) { 384a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, id()); 385a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSender = new MediaSender(mNetSession, notify); 386a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->registerHandler(mMediaSender); 387a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 388a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSender->setHDCP(mHDCP); 389a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 39094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber status_t err = setupPacketizer( 39194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber enableAudio, 39294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber usePCMAudio, 39394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber enableVideo, 39494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber videoResolutionType, 395308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoResolutionIndex, 396308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoProfileType, 397308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoLevelType); 398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 399a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err == OK) { 400a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber err = mMediaSender->initAsync( 401a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber -1 /* trackIndex */, 402a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber clientIP, 403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber clientRtp, 4042aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber rtpMode, 405a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber clientRtcp, 4062aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber rtcpMode, 407a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber &mLocalRTPPort); 408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 411a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mLocalRTPPort = -1; 412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 413a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->unregisterHandler(mMediaSender->id()); 414a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSender.clear(); 415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 41690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber return err; 417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() { 425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const { 428a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber return mLocalRTPPort; 429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const { 432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return mLastLifesignUs; 433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() { 436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mLastLifesignUs = ALooper::GetNowUs(); 437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() { 440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 4425131d127a042ee88f903370be88845dc8c9f8578Andreas Huber (new AMessage(kWhatResume, id()))->post(); 4435131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 444bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber return OK; 445bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber} 446bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 447a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() { 448e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 44996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start()); 450e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 451e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 452bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber sp<AMessage> notify = mNotify->dup(); 453bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->setInt32("what", kWhatSessionEstablished); 454bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber notify->post(); 455bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 456e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() { 460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber updateLiveness(); 461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 4625131d127a042ee88f903370be88845dc8c9f8578Andreas Huber (new AMessage(kWhatPause, id()))->post(); 4635131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 46796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() { 46896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber ALOGI("destroyAsync"); 469a438123bd96c7faf145683876702387efe5628d9Andreas Huber 47096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 47196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mTracks.valueAt(i)->stopAsync(); 472a438123bd96c7faf145683876702387efe5628d9Andreas Huber } 473a438123bd96c7faf145683876702387efe5628d9Andreas Huber} 474a438123bd96c7faf145683876702387efe5628d9Andreas Huber 475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived( 476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<AMessage> &msg) { 477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber switch (msg->what()) { 478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber case kWhatConverterNotify: 479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber { 4806360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber if (mWeAreDead) { 4816360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber ALOGV("dropping msg '%s' because we're dead", 4826360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber msg->debugString().c_str()); 4836360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber 4846360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber break; 4856360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber } 4866360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber 487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber int32_t what; 488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("what", &what)); 489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber size_t trackIndex; 491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (what == Converter::kWhatAccessUnit) { 49428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber sp<ABuffer> accessUnit; 49528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber CHECK(msg->findBuffer("accessUnit", &accessUnit)); 496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 497a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber const sp<Track> &track = mTracks.valueFor(trackIndex); 498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 499a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err = mMediaSender->queueAccessUnit( 500a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber track->mediaSenderTrackIndex(), 501a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber accessUnit); 502774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber 503a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err != OK) { 504a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifySessionDead(); 505a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 50628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber break; 507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } else if (what == Converter::kWhatEOS) { 508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatEOS); 509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("output EOS on track %d", trackIndex); 511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ssize_t index = mTracks.indexOfKey(trackIndex); 513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_GE(index, 0); 514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber const sp<Converter> &converter = 516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.valueAt(index)->converter(); 517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber looper()->unregisterHandler(converter->id()); 518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber mTracks.removeItemsAt(index); 520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber if (mTracks.isEmpty()) { 522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGI("Reached EOS"); 523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 524a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber } else if (what != Converter::kWhatShutdownCompleted) { 525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(what, Converter::kWhatError); 526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err; 528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK(msg->findInt32("err", &err)); 529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber ALOGE("converter signaled error %d", err); 531ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber 532ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notifySessionDead(); 533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber break; 535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 537a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber case kWhatMediaSenderNotify: 53890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber { 53990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber int32_t what; 54090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber CHECK(msg->findInt32("what", &what)); 54190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber 542a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (what == MediaSender::kWhatInitDone) { 543a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber status_t err; 544a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK(msg->findInt32("err", &err)); 5457cc0c29d6a7b76520ec588437ab51d5b8eac9ebcAndreas Huber 546a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (err == OK) { 547a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber onMediaSenderInitialized(); 548a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } else { 549a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifySessionDead(); 550a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 551a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } else if (what == MediaSender::kWhatError) { 552a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber notifySessionDead(); 553126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber } else if (what == MediaSender::kWhatNetworkStall) { 554126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber size_t numBytesQueued; 555126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber CHECK(msg->findSize("numBytesQueued", &numBytesQueued)); 556126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber 557126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber if (mVideoTrackIndex >= 0) { 558126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber const sp<Track> &videoTrack = 559126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber mTracks.valueFor(mVideoTrackIndex); 560126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber 5610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<Converter> converter = videoTrack->converter(); 5620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (converter != NULL) { 5630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber converter->dropAFrame(); 5640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 565126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber } 566c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } else if (what == MediaSender::kWhatInformSender) { 567c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber onSinkFeedback(msg); 56890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } else { 56990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber TRESPASS(); 57090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 571bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber break; 572bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber } 573bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber 57496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber case kWhatTrackNotify: 57596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber { 57696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber int32_t what; 57796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findInt32("what", &what)); 57896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 57996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber size_t trackIndex; 58096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber CHECK(msg->findSize("trackIndex", &trackIndex)); 58196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 58296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber if (what == Track::kWhatStopped) { 58377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("Track %d stopped", trackIndex); 58496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 58577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber sp<Track> track = mTracks.valueFor(trackIndex); 58677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber looper()->unregisterHandler(track->id()); 58777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber mTracks.removeItem(trackIndex); 58877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber track.clear(); 58977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber 59077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber if (!mTracks.isEmpty()) { 59177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber ALOGI("not all tracks are stopped yet"); 59296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber break; 59396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber } 59496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 595a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber looper()->unregisterHandler(mMediaSender->id()); 596a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSender.clear(); 59796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 59890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber sp<AMessage> notify = mNotify->dup(); 59990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber notify->setInt32("what", kWhatSessionDestroyed); 60090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber notify->post(); 60190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 60290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber break; 60390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber } 60496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 6055131d127a042ee88f903370be88845dc8c9f8578Andreas Huber case kWhatPause: 6065131d127a042ee88f903370be88845dc8c9f8578Andreas Huber { 6070b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (mExtractor != NULL) { 6080b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber ++mPullExtractorGeneration; 6090b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeRealUs = -1ll; 6100b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeUs = -1ll; 6110b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 6120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 6135131d127a042ee88f903370be88845dc8c9f8578Andreas Huber if (mPaused) { 6145131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 6155131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6165131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6175131d127a042ee88f903370be88845dc8c9f8578Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 6185131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mTracks.editValueAt(i)->pause(); 6195131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6205131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6215131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused = true; 6225131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 6235131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6245131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6255131d127a042ee88f903370be88845dc8c9f8578Andreas Huber case kWhatResume: 6265131d127a042ee88f903370be88845dc8c9f8578Andreas Huber { 6270b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (mExtractor != NULL) { 6280b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber schedulePullExtractor(); 6290b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 6300b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 6315131d127a042ee88f903370be88845dc8c9f8578Andreas Huber if (!mPaused) { 6325131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 6335131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6355131d127a042ee88f903370be88845dc8c9f8578Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 6365131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mTracks.editValueAt(i)->resume(); 6375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6395131d127a042ee88f903370be88845dc8c9f8578Andreas Huber mPaused = false; 6405131d127a042ee88f903370be88845dc8c9f8578Andreas Huber break; 6415131d127a042ee88f903370be88845dc8c9f8578Andreas Huber } 6425131d127a042ee88f903370be88845dc8c9f8578Andreas Huber 6430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber case kWhatPullExtractorSample: 6440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber { 6450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber int32_t generation; 6460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber CHECK(msg->findInt32("generation", &generation)); 6470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 6480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (generation != mPullExtractorGeneration) { 6490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber break; 6500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 6510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 6520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mPullExtractorPending = false; 6530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 6540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber onPullExtractor(); 6550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber break; 6560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 6570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber default: 659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber TRESPASS(); 660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber } 661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 663c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Hubervoid WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg) { 664c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber int64_t avgLatencyUs; 665c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs)); 666c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 667c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber int64_t maxLatencyUs; 668c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs)); 669c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 670c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber ALOGI("sink reports avg. latency of %lld ms (max %lld ms)", 671c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber avgLatencyUs / 1000ll, 672c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber maxLatencyUs / 1000ll); 673c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 674c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (mVideoTrackIndex >= 0) { 675c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex); 676c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber sp<Converter> converter = videoTrack->converter(); 677c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 678c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (converter != NULL) { 679c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber int32_t videoBitrate = 680c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber Converter::GetInt32Property("media.wfd.video-bitrate", -1); 681c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 682c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber char val[PROPERTY_VALUE_MAX]; 683c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (videoBitrate < 0 684c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber && property_get("media.wfd.video-bitrate", val, NULL) 685c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber && !strcasecmp("adaptive", val)) { 686c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber videoBitrate = converter->getVideoBitrate(); 687c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 688c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (avgLatencyUs > 300000ll) { 689c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber videoBitrate *= 0.6; 690c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } else if (avgLatencyUs < 100000ll) { 691c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber videoBitrate *= 1.1; 692c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 693c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 694c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 695c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (videoBitrate > 0) { 696c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (videoBitrate < 500000) { 697c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber videoBitrate = 500000; 698c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } else if (videoBitrate > 10000000) { 699c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber videoBitrate = 10000000; 700c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 701c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 702c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (videoBitrate != converter->getVideoBitrate()) { 703c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber ALOGI("setting video bitrate to %d bps", videoBitrate); 704c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 705c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber converter->setVideoBitrate(videoBitrate); 706c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 707c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 708c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 709c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 710c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource(); 711c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (repeaterSource != NULL) { 712c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber double rateHz = 713c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber Converter::GetInt32Property( 714c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber "media.wfd.video-framerate", -1); 715c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 716c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber char val[PROPERTY_VALUE_MAX]; 717c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (rateHz < 0.0 718c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber && property_get("media.wfd.video-framerate", val, NULL) 719c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber && !strcasecmp("adaptive", val)) { 720c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber rateHz = repeaterSource->getFrameRate(); 721c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 722c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (avgLatencyUs > 300000ll) { 723c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber rateHz *= 0.9; 724c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } else if (avgLatencyUs < 200000ll) { 725c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber rateHz *= 1.1; 726c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 727c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 728c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 729c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (rateHz > 0) { 730c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (rateHz < 5.0) { 731c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber rateHz = 5.0; 732c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } else if (rateHz > 30.0) { 733c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber rateHz = 30.0; 734c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 735c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 736c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber if (rateHz != repeaterSource->getFrameRate()) { 737c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber ALOGI("setting frame rate to %.2f Hz", rateHz); 738c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 739c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber repeaterSource->setFrameRate(rateHz); 740c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 741c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 742c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 743c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber } 744c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber} 745c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber 7460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer( 7470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber bool enableAudio, bool enableVideo) { 7480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber DataSource::RegisterDefaultSniffers(); 7490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mExtractor = new NuMediaExtractor; 7510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber status_t err = mExtractor->setDataSource(mMediaPath.c_str()); 7530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (err != OK) { 7550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return err; 7560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 7570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber size_t n = mExtractor->countTracks(); 7590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber bool haveAudio = false; 7600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber bool haveVideo = false; 7610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber for (size_t i = 0; i < n; ++i) { 7620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<AMessage> format; 7630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber err = mExtractor->getTrackFormat(i, &format); 7640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (err != OK) { 7660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber continue; 7670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 7680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber AString mime; 7700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber CHECK(format->findString("mime", &mime)); 7710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7720b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6); 7730b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber bool isVideo = !strncasecmp(mime.c_str(), "video/", 6); 7740b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7750b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (isAudio && enableAudio && !haveAudio) { 7760b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber haveAudio = true; 7770b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } else if (isVideo && enableVideo && !haveVideo) { 7780b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber haveVideo = true; 7790b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } else { 7800b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber continue; 7810b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 7820b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7830b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber err = mExtractor->selectTrack(i); 7840b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7850b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber size_t trackIndex = mTracks.size(); 7860b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7870b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<AMessage> notify = new AMessage(kWhatTrackNotify, id()); 7880b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber notify->setSize("trackIndex", trackIndex); 7890b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7900b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<Track> track = new Track(notify, format); 7910b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber looper()->registerHandler(track); 7920b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7930b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mTracks.add(trackIndex, track); 7940b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7950b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mExtractorTrackToInternalTrack.add(i, trackIndex); 7960b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 7970b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (isVideo) { 7980b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mVideoTrackIndex = trackIndex; 7990b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8000b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8010b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber uint32_t flags = MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS; 8020b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8030b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber ssize_t mediaSenderTrackIndex = 8040b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mMediaSender->addTrack(format, flags); 8050b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber CHECK_GE(mediaSenderTrackIndex, 0); 8060b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8070b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber track->setMediaSenderTrackIndex(mediaSenderTrackIndex); 8080b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8090b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if ((haveAudio || !enableAudio) && (haveVideo || !enableVideo)) { 8100b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber break; 8110b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return OK; 8150b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber} 8160b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8170b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::schedulePullExtractor() { 8180b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (mPullExtractorPending) { 8190b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return; 8200b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8210b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8220b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber int64_t sampleTimeUs; 8230b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber status_t err = mExtractor->getSampleTime(&sampleTimeUs); 8240b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8250b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber int64_t nowUs = ALooper::GetNowUs(); 8260b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8270b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (mFirstSampleTimeRealUs < 0ll) { 8280b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeRealUs = nowUs; 8290b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mFirstSampleTimeUs = sampleTimeUs; 8300b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8310b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8320b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs; 8330b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8340b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, id()); 8350b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->setInt32("generation", mPullExtractorGeneration); 8360b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->post(whenUs - nowUs); 8370b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8380b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mPullExtractorPending = true; 8390b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber} 8400b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8410b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::onPullExtractor() { 8420b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<ABuffer> accessUnit = new ABuffer(1024 * 1024); 8430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber status_t err = mExtractor->readSampleData(accessUnit); 8440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (err != OK) { 8450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber // EOS. 8460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return; 8470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber int64_t timeUs; 8500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber CHECK_EQ((status_t)OK, mExtractor->getSampleTime(&timeUs)); 8510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber accessUnit->meta()->setInt64( 8530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber "timeUs", mFirstSampleTimeRealUs + timeUs - mFirstSampleTimeUs); 8540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber size_t trackIndex; 8560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex)); 8570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber sp<AMessage> msg = new AMessage(kWhatConverterNotify, id()); 8590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->setSize( 8610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber "trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex)); 8620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->setInt32("what", Converter::kWhatAccessUnit); 8640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->setBuffer("accessUnit", accessUnit); 8650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber msg->post(); 8660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber mExtractor->advance(); 8680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 8690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber schedulePullExtractor(); 8700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber} 8710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 87294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer( 87394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool enableAudio, 87494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool usePCMAudio, 87594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool enableVideo, 87694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber VideoFormats::ResolutionType videoResolutionType, 877308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang size_t videoResolutionIndex, 878308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::ProfileType videoProfileType, 879308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::LevelType videoLevelType) { 88094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber CHECK(enableAudio || enableVideo); 88194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber 8820b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber if (!mMediaPath.empty()) { 8830b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber return setupMediaPacketizer(enableAudio, enableVideo); 8840b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber } 8850b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber 88694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber if (enableVideo) { 88794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber status_t err = addVideoSource( 888308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoResolutionType, videoResolutionIndex, videoProfileType, 889308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoLevelType); 890d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 89194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber if (err != OK) { 89294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber return err; 89394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber } 89494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber } 89594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber 89694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber if (!enableAudio) { 89794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber return OK; 898e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 899e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 900e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber return addAudioSource(usePCMAudio); 901e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 903e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource( 9044a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource, 905308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang bool usePCMAudio, unsigned profileIdc, unsigned levelIdc, 906308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang unsigned constraintSet, size_t *numInputBuffers) { 907e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(!usePCMAudio || !isVideo); 908e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber CHECK(!isRepeaterSource || isVideo); 909308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(!profileIdc || isVideo); 910308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(!levelIdc || isVideo); 911308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(!constraintSet || isVideo); 912e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber 913e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> pullLooper = new ALooper; 914e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->setName("pull_looper"); 915e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 916e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber pullLooper->start( 917e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 918e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 919ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 921e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<ALooper> codecLooper = new ALooper; 922e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->setName("codec_looper"); 923e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 924e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber codecLooper->start( 925e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* runOnCallingThread */, 926e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber false /* canCallJava */, 927ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber PRIORITY_AUDIO); 928e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 929e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t trackIndex; 930e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 931e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber sp<AMessage> notify; 932e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 933e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber trackIndex = mTracks.size(); 934e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber sp<AMessage> format; 936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber status_t err = convertMetaDataToMessage(source->getFormat(), &format); 937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber CHECK_EQ(err, (status_t)OK); 938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 939e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 9409fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC); 941e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32("store-metadata-in-buffers", true); 942ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang format->setInt32("store-metadata-in-buffers-output", (mHDCP != NULL) 943ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang && (mHDCP->getCaps() & HDCPModule::HDCP_CAPS_ENCRYPT_NATIVE)); 944e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber format->setInt32( 945e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber "color-format", OMX_COLOR_FormatAndroidOpaque); 946308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang format->setInt32("profile-idc", profileIdc); 947308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang format->setInt32("level-idc", levelIdc); 948308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang format->setInt32("constraint-set", constraintSet); 9499fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber } else { 9509fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber format->setString( 9519fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber "mime", 9529fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber usePCMAudio 9539fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber ? MEDIA_MIMETYPE_AUDIO_RAW : MEDIA_MIMETYPE_AUDIO_AAC); 954e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 956e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify = new AMessage(kWhatConverterNotify, id()); 957e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber notify->setSize("trackIndex", trackIndex); 958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 9599fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber sp<Converter> converter = new Converter(notify, codecLooper, format); 9603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber 961a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber looper()->registerHandler(converter); 962a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 963a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber err = converter->init(); 9640224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber if (err != OK) { 9650224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err); 966a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber 967a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber looper()->unregisterHandler(converter->id()); 9680224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber return err; 9693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber } 97066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 97196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id()); 97296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setSize("trackIndex", trackIndex); 97396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 97496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<MediaPuller> puller = new MediaPuller(source, notify); 97596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber pullLooper->registerHandler(puller); 97696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 977e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (numInputBuffers != NULL) { 978e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber *numInputBuffers = converter->getInputBufferCount(); 979e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 98066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 98196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify = new AMessage(kWhatTrackNotify, id()); 98296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify->setSize("trackIndex", trackIndex); 98396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 98496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber sp<Track> track = new Track( 98596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber notify, pullLooper, codecLooper, puller, converter); 98696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 9874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber if (isRepeaterSource) { 9884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber track->setRepeaterSource(static_cast<RepeaterSource *>(source.get())); 9894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber } 9904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 99196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber looper()->registerHandler(track); 99296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber 99396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber mTracks.add(trackIndex, track); 994e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 995e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (isVideo) { 996e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber mVideoTrackIndex = trackIndex; 997e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 998e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 999a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber uint32_t flags = 0; 1000a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber if (converter->needToManuallyPrependSPSPPS()) { 1001a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS; 1002a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber } 1003a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 1004a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber ssize_t mediaSenderTrackIndex = 1005a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber mMediaSender->addTrack(converter->getOutputFormat(), flags); 1006a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber CHECK_GE(mediaSenderTrackIndex, 0); 1007a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 1008a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber track->setMediaSenderTrackIndex(mediaSenderTrackIndex); 1009a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber 1010e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 1011e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 1012e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 101394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource( 101494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber VideoFormats::ResolutionType videoResolutionType, 1015308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang size_t videoResolutionIndex, 1016308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::ProfileType videoProfileType, 1017308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang VideoFormats::LevelType videoLevelType) { 101894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber size_t width, height, framesPerSecond; 101994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber bool interlaced; 102094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber CHECK(VideoFormats::GetConfiguration( 102194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber videoResolutionType, 102294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber videoResolutionIndex, 102394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber &width, 102494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber &height, 102594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber &framesPerSecond, 102694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber &interlaced)); 102794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber 1028308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang unsigned profileIdc, levelIdc, constraintSet; 1029308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang CHECK(VideoFormats::GetProfileLevel( 1030308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoProfileType, 1031308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang videoLevelType, 1032308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang &profileIdc, 1033308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang &levelIdc, 1034308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang &constraintSet)); 1035308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 103694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber sp<SurfaceMediaSource> source = new SurfaceMediaSource(width, height); 1037e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 1038af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber source->setUseAbsoluteTimestamps(); 1039af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber 10404a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber sp<RepeaterSource> videoSource = 104194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber new RepeaterSource(source, framesPerSecond); 10424a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber 1043e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber size_t numInputBuffers; 10444a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber status_t err = addSource( 10454a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber true /* isVideo */, videoSource, true /* isRepeaterSource */, 1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang false /* usePCMAudio */, profileIdc, levelIdc, constraintSet, 1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang &numInputBuffers); 1048e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 1049e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber if (err != OK) { 1050e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return err; 1051e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber } 105266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 10535a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber err = source->setMaxAcquiredBufferCount(numInputBuffers); 105466e72bc85fb762876baff60ef29de729da93cf26Andreas Huber CHECK_EQ(err, (status_t)OK); 105566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber 10560b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber mBufferQueue = source->getBufferQueue(); 10570b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 1058e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return OK; 1059e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber} 1060e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 1061e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) { 1062082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber sp<AudioSource> audioSource = new AudioSource( 10631646a0fed94c30a44128b3c379736def4b332033Andreas Huber AUDIO_SOURCE_REMOTE_SUBMIX, 1064082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 48000 /* sampleRate */, 10651646a0fed94c30a44128b3c379736def4b332033Andreas Huber 2 /* channelCount */); 1066082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 10677977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber if (audioSource->initCheck() == OK) { 1068e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber return addSource( 10694a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber false /* isVideo */, audioSource, false /* isRepeaterSource */, 1070308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang usePCMAudio, 0 /* profileIdc */, 0 /* levelIdc */, 1071308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang 0 /* constraintSet */, NULL /* numInputBuffers */); 10727977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber } 1073e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber 1074e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber ALOGW("Unable to instantiate audio source"); 1075082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber 1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber return OK; 1077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} 1078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 10798ba01021b573889802e67e029225a96f0dfa471aAndy McFaddensp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() { 10800b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber return mBufferQueue; 10810b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber} 10820b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber 1083496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() { 1084496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber for (size_t i = 0; i < mTracks.size(); ++i) { 1085496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber const sp<Track> &track = mTracks.valueAt(i); 1086496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 10874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber track->requestIDRFrame(); 1088496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 1089496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 1090496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1091ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() { 1092ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber // Inform WifiDisplaySource of our premature death (wish). 1093ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber sp<AMessage> notify = mNotify->dup(); 1094ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notify->setInt32("what", kWhatSessionDead); 1095ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber notify->post(); 1096ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 1097ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber mWeAreDead = true; 1098ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber} 1099ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber 1100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber} // namespace android 1101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber 1102