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> &notify,
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> &notify, 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> &notify,
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> &notify, 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> &notify,
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