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>
321b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h>
33e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h>
38082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h>
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h>
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h>
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h>
440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber#include <media/stagefright/NuMediaExtractor.h>
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h>
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h>
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler {
5396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
5496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatStopped,
5596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    Track(const sp<AMessage> &notify,
5896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber          const sp<ALooper> &pullLooper,
59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<ALooper> &codecLooper,
60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<MediaPuller> &mediaPuller,
61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<Converter> &converter);
62e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    Track(const sp<AMessage> &notify, const sp<AMessage> &format);
640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
654a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void setRepeaterSource(const sp<RepeaterSource> &source);
664a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> getFormat();
68b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool isAudio() const;
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<Converter> &converter() const;
71eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    const sp<RepeaterSource> &repeaterSource() const;
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mediaSenderTrackIndex() const;
74a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    void setMediaSenderTrackIndex(size_t index);
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
76e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t start();
7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    void stopAsync();
7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
795131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    void pause();
805131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    void resume();
815131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
8228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    void queueAccessUnit(const sp<ABuffer> &accessUnit);
8328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> dequeueAccessUnit();
8428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
8590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool hasOutputBuffer(int64_t *timeUs) const;
8690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    void queueOutputBuffer(const sp<ABuffer> &accessUnit);
8790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> dequeueOutputBuffer();
880224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
890224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE
9090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool isSuspended() const;
910224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif
9290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
9390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t countQueuedOutputBuffers() const {
9490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return mQueuedOutputBuffers.size();
9590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
9690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
974a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void requestIDRFrame();
984a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected:
10096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    virtual ~Track();
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate:
10496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
10596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatMediaPullerStopped,
10696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
10796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
10896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> mNotify;
109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mPullLooper;
110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mCodecLooper;
111e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<MediaPuller> mMediaPuller;
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> mConverter;
1130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<AMessage> mFormat;
114e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    bool mStarted;
115a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mMediaSenderTrackIndex;
116b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool mIsAudio;
11728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    List<sp<ABuffer> > mQueuedAccessUnits;
1184a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> mRepeaterSource;
11990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    List<sp<ABuffer> > mQueuedOutputBuffers;
12090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t mLastOutputBufferQueuedTimeUs;
121b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
122b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    static bool IsAudioFormat(const sp<AMessage> &format);
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber};
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
127e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
12896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &notify,
129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &pullLooper,
130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &codecLooper,
131e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<MediaPuller> &mediaPuller,
132e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<Converter> &converter)
13396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    : mNotify(notify),
13496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber      mPullLooper(pullLooper),
135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mCodecLooper(codecLooper),
136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mMediaPuller(mediaPuller),
137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mConverter(converter),
138e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mStarted(false),
13990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
14090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1430b530f1050150bb751ae642d5a9dce34141d9475Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
1440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const sp<AMessage> &notify, const sp<AMessage> &format)
1450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    : mNotify(notify),
1460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFormat(format),
1470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mStarted(false),
1480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mIsAudio(IsAudioFormat(format)),
1490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
1500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
1510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
15396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
156b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static
157b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
158b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<AMessage> &format) {
159b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    AString mime;
160b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    CHECK(format->findString("mime", &mime));
161b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
162b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return !strncasecmp(mime.c_str(), "audio/", 6);
163b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
164b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
1660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    return mFormat != NULL ? mFormat : mConverter->getOutputFormat();
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
169b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
170b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return mIsAudio;
171b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
172b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter;
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
177eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huberconst sp<RepeaterSource> &
178eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas HuberWifiDisplaySource::PlaybackSession::Track::repeaterSource() const {
179eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    return mRepeaterSource;
180eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber}
181eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber
182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_GE(mMediaSenderTrackIndex, 0);
184a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return mMediaSenderTrackIndex;
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex(
188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t index) {
189a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSenderTrackIndex = index;
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
192e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
193ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    ALOGV("Track::start isAudio=%d", mIsAudio);
194ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
19596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
196e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
197e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = OK;
198e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
199e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (mMediaPuller != NULL) {
200e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        err = mMediaPuller->start();
201e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
202e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
203e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err == OK) {
204e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mStarted = true;
205e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
206e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
207e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return err;
208e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
209e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() {
21196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
212ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
2130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (mConverter != NULL) {
2140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mConverter->shutdownAsync();
2150b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, this);
218e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
219ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber    if (mStarted && mMediaPuller != NULL) {
2204a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        if (mRepeaterSource != NULL) {
2214a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            // Let's unblock MediaPuller's MediaSource::read().
2224a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            mRepeaterSource->wakeUp();
2234a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        }
2244a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mMediaPuller->stopAsync(msg);
22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    } else {
2270b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mStarted = false;
22896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        msg->post();
229e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
23096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
231e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
2325131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::pause() {
2335131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    mMediaPuller->pause();
2345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber}
2355131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
2365131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::resume() {
2375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    mMediaPuller->resume();
2385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber}
2395131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &msg) {
24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    switch (msg->what()) {
24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerStopped:
24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
24596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mConverter.clear();
246a438123bd96c7faf145683876702387efe5628d9Andreas Huber
24796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mStarted = false;
248e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            sp<AMessage> notify = mNotify->dup();
25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->setInt32("what", kWhatStopped);
25196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->post();
25277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
25377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
25796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        default:
25896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            TRESPASS();
25996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    }
260e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
261e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
26228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
26328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        const sp<ABuffer> &accessUnit) {
26428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.push_back(accessUnit);
26528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
26628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
26728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
26828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mQueuedAccessUnits.empty()) {
26928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return NULL;
27028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
27128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
27328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    CHECK(accessUnit != NULL);
27428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
27628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return accessUnit;
27828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
27928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
2804a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
2814a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        const sp<RepeaterSource> &source) {
2824a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mRepeaterSource = source;
2834a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2844a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2854a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
2864a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mIsAudio) {
2874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        return;
2884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mRepeaterSource != NULL) {
2914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mRepeaterSource->wakeUp();
2924a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2934a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2944a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mConverter->requestIDRFrame();
2954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2964a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t *timeUs) const {
29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    *timeUs = 0ll;
30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mQueuedOutputBuffers.empty()) {
30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return true;
31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<ABuffer> &accessUnit) {
31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.push_back(accessUnit);
31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(!mQueuedOutputBuffers.empty());
32090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
32290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
32390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return outputBuffer;
32590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
32690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE
32890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
32990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (!mQueuedOutputBuffers.empty()) {
33090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
33290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mLastOutputBufferQueuedTimeUs < 0ll) {
33490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // We've never seen an output buffer queued, but tracks start
33590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // out live, not suspended.
33690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
33790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
33890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // If we've not seen new output data for 60ms or more, we consider
34090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // this track suspended for the time being.
34190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
34290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
3430224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif
34490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber////////////////////////////////////////////////////////////////////////////////
346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
348be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov        const String16 &opPackageName,
349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ANetworkSession> &netSession,
3500b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber        const sp<AMessage> &notify,
351bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        const in_addr &interfaceAddr,
3520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const sp<IHDCP> &hdcp,
3530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const char *path)
354be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov    : mOpPackageName(opPackageName),
355be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov      mNetSession(netSession),
356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
357bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mInterfaceAddr(interfaceAddr),
358b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mHDCP(hdcp),
359a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mLocalRTPPort(-1),
360ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber      mWeAreDead(false),
3615131d127a042ee88f903370be88845dc8c9f8578Andreas Huber      mPaused(false),
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastLifesignUs(),
363e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mVideoTrackIndex(-1),
3640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPrevTimeUs(-1ll),
3650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPullExtractorPending(false),
3660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPullExtractorGeneration(0),
3670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFirstSampleTimeRealUs(-1ll),
3680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFirstSampleTimeUs(-1ll) {
3690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (path != NULL) {
3700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mMediaPath.setTo(path);
3710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
3752aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        const char *clientIP,
3762aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        int32_t clientRtp,
3772aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        RTPSender::TransportMode rtpMode,
3782aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        int32_t clientRtcp,
3792aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        RTPSender::TransportMode rtcpMode,
38094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableAudio,
38194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool usePCMAudio,
38294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableVideo,
38394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
384308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        size_t videoResolutionIndex,
385308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::ProfileType videoProfileType,
386308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::LevelType videoLevelType) {
3871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, this);
388a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSender = new MediaSender(mNetSession, notify);
389a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    looper()->registerHandler(mMediaSender);
390a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
391a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSender->setHDCP(mHDCP);
392a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
39394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    status_t err = setupPacketizer(
39494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            enableAudio,
39594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            usePCMAudio,
39694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            enableVideo,
39794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            videoResolutionType,
398308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            videoResolutionIndex,
399308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            videoProfileType,
400308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            videoLevelType);
401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
402a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err == OK) {
403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        err = mMediaSender->initAsync(
404a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                -1 /* trackIndex */,
405a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientIP,
406a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientRtp,
4072aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber                rtpMode,
408a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientRtcp,
4092aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber                rtcpMode,
410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                &mLocalRTPPort);
411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
413a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err != OK) {
414a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mLocalRTPPort = -1;
415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
416a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        looper()->unregisterHandler(mMediaSender->id());
417a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mMediaSender.clear();
418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
41990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return err;
420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
431a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return mLocalRTPPort;
432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mLastLifesignUs;
436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
442d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
4465131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
447bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
448bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
449bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
450a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
451e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
45296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
453e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
454e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
455bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    sp<AMessage> notify = mNotify->dup();
456bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->setInt32("what", kWhatSessionEstablished);
457bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->post();
458bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
459e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatPause, this))->post();
4665131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
47096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() {
47196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGI("destroyAsync");
472a438123bd96c7faf145683876702387efe5628d9Andreas Huber
47396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
47496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mTracks.valueAt(i)->stopAsync();
475a438123bd96c7faf145683876702387efe5628d9Andreas Huber    }
476a438123bd96c7faf145683876702387efe5628d9Andreas Huber}
477a438123bd96c7faf145683876702387efe5628d9Andreas Huber
478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &msg) {
480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatConverterNotify:
482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
4836360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            if (mWeAreDead) {
4846360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                ALOGV("dropping msg '%s' because we're dead",
4856360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                      msg->debugString().c_str());
4866360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
4876360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                break;
4886360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            }
4896360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t trackIndex;
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Converter::kWhatAccessUnit) {
49728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                sp<ABuffer> accessUnit;
49828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
500a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
502a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                status_t err = mMediaSender->queueAccessUnit(
503a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        track->mediaSenderTrackIndex(),
504a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        accessUnit);
505774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
506a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (err != OK) {
507a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    notifySessionDead();
508a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
50928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                break;
510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else if (what == Converter::kWhatEOS) {
511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
513ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGI("output EOS on track %zu", trackIndex);
514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_GE(index, 0);
517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Converter> &converter =
519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(index)->converter();
520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                looper()->unregisterHandler(converter->id());
521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.removeItemsAt(index);
523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (mTracks.isEmpty()) {
525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("Reached EOS");
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
527a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber            } else if (what != Converter::kWhatShutdownCompleted) {
528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                status_t err;
531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findInt32("err", &err));
532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGE("converter signaled error %d", err);
534ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber
535ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                notifySessionDead();
536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
537d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
538d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
540a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case kWhatMediaSenderNotify:
54190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
54290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t what;
54390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findInt32("what", &what));
54490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
545a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (what == MediaSender::kWhatInitDone) {
546a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                status_t err;
547a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK(msg->findInt32("err", &err));
5487cc0c29d6a7b76520ec588437ab51d5b8eac9ebcAndreas Huber
549a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (err == OK) {
550a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    onMediaSenderInitialized();
551a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                } else {
552a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    notifySessionDead();
553a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
554a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else if (what == MediaSender::kWhatError) {
555a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                notifySessionDead();
556126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            } else if (what == MediaSender::kWhatNetworkStall) {
557126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                size_t numBytesQueued;
558126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
559126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
560126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                if (mVideoTrackIndex >= 0) {
561126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                    const sp<Track> &videoTrack =
562126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                        mTracks.valueFor(mVideoTrackIndex);
563126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
5640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    sp<Converter> converter = videoTrack->converter();
5650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    if (converter != NULL) {
5660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                        converter->dropAFrame();
5670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    }
568126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                }
569c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            } else if (what == MediaSender::kWhatInformSender) {
570c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                onSinkFeedback(msg);
57190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else {
57290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                TRESPASS();
57390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
574bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            break;
575bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        }
576bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
57796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatTrackNotify:
57896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
57996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
58096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
58196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
58296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            size_t trackIndex;
58396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
58496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
58596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == Track::kWhatStopped) {
586ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGI("Track %zu stopped", trackIndex);
58796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
58877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                sp<Track> track = mTracks.valueFor(trackIndex);
58977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                looper()->unregisterHandler(track->id());
59077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                mTracks.removeItem(trackIndex);
59177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                track.clear();
59277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
59377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                if (!mTracks.isEmpty()) {
59477245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                    ALOGI("not all tracks are stopped yet");
59596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    break;
59696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
59796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
598a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                looper()->unregisterHandler(mMediaSender->id());
599a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mMediaSender.clear();
60096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
60190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                sp<AMessage> notify = mNotify->dup();
60290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->setInt32("what", kWhatSessionDestroyed);
60390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->post();
60490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
60590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
60690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
60796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
6085131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        case kWhatPause:
6095131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        {
6100b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (mExtractor != NULL) {
6110b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                ++mPullExtractorGeneration;
6120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                mFirstSampleTimeRealUs = -1ll;
6130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                mFirstSampleTimeUs = -1ll;
6140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6150b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6165131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            if (mPaused) {
6175131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                break;
6185131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6195131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6205131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
6215131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                mTracks.editValueAt(i)->pause();
6225131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6235131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6245131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            mPaused = true;
6255131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            break;
6265131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        }
6275131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6285131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        case kWhatResume:
6295131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        {
6300b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (mExtractor != NULL) {
6310b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                schedulePullExtractor();
6320b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6330b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            if (!mPaused) {
6355131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                break;
6365131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
6395131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                mTracks.editValueAt(i)->resume();
6405131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6415131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6425131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            mPaused = false;
6435131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            break;
6445131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        }
6455131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        case kWhatPullExtractorSample:
6470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        {
6480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            int32_t generation;
6490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            CHECK(msg->findInt32("generation", &generation));
6500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (generation != mPullExtractorGeneration) {
6520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                break;
6530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mPullExtractorPending = false;
6560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            onPullExtractor();
6580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            break;
6590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
6600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
664d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
666c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Hubervoid WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg) {
667c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    int64_t avgLatencyUs;
668c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
669c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
670c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    int64_t maxLatencyUs;
671c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
672c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
673c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    ALOGI("sink reports avg. latency of %lld ms (max %lld ms)",
674c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber          avgLatencyUs / 1000ll,
675c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber          maxLatencyUs / 1000ll);
676c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
677c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    if (mVideoTrackIndex >= 0) {
678c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex);
679c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        sp<Converter> converter = videoTrack->converter();
680c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
681c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        if (converter != NULL) {
682c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            int32_t videoBitrate =
683c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                Converter::GetInt32Property("media.wfd.video-bitrate", -1);
684c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
685c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            char val[PROPERTY_VALUE_MAX];
686c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (videoBitrate < 0
687c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && property_get("media.wfd.video-bitrate", val, NULL)
688c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && !strcasecmp("adaptive", val)) {
689c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                videoBitrate = converter->getVideoBitrate();
690c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
691c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (avgLatencyUs > 300000ll) {
692c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate *= 0.6;
693c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (avgLatencyUs < 100000ll) {
694c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate *= 1.1;
695c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
696c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
697c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
698c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (videoBitrate > 0) {
699c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (videoBitrate < 500000) {
700c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate = 500000;
701c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (videoBitrate > 10000000) {
702c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate = 10000000;
703c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
704c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
705c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (videoBitrate != converter->getVideoBitrate()) {
706c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    ALOGI("setting video bitrate to %d bps", videoBitrate);
707c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
708c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    converter->setVideoBitrate(videoBitrate);
709c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
710c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
711c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        }
712c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
713c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource();
714c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        if (repeaterSource != NULL) {
715c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            double rateHz =
716c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                Converter::GetInt32Property(
717c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                        "media.wfd.video-framerate", -1);
718c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
719c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            char val[PROPERTY_VALUE_MAX];
720c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (rateHz < 0.0
721c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && property_get("media.wfd.video-framerate", val, NULL)
722c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && !strcasecmp("adaptive", val)) {
723c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                 rateHz = repeaterSource->getFrameRate();
724c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
725c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (avgLatencyUs > 300000ll) {
726c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz *= 0.9;
727c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (avgLatencyUs < 200000ll) {
728c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz *= 1.1;
729c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
730c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
731c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
732c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (rateHz > 0) {
733c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (rateHz < 5.0) {
734c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz = 5.0;
735c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (rateHz > 30.0) {
736c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz = 30.0;
737c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
738c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
739c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (rateHz != repeaterSource->getFrameRate()) {
740c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    ALOGI("setting frame rate to %.2f Hz", rateHz);
741c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
742c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    repeaterSource->setFrameRate(rateHz);
743c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
744c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
745c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        }
746c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    }
747c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber}
748c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
7490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
7500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool enableAudio, bool enableVideo) {
7510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    DataSource::RegisterDefaultSniffers();
7520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mExtractor = new NuMediaExtractor;
7540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7551b86fe063badb5f28c467ade39be0f4008688947Andreas Huber    status_t err = mExtractor->setDataSource(
7561b86fe063badb5f28c467ade39be0f4008688947Andreas Huber            NULL /* httpService */, mMediaPath.c_str());
7570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (err != OK) {
7590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return err;
7600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
7610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    size_t n = mExtractor->countTracks();
7630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    bool haveAudio = false;
7640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    bool haveVideo = false;
7650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    for (size_t i = 0; i < n; ++i) {
7660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        sp<AMessage> format;
7670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        err = mExtractor->getTrackFormat(i, &format);
7680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (err != OK) {
7700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            continue;
7710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
7720b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7730b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        AString mime;
7740b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        CHECK(format->findString("mime", &mime));
7750b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7760b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
7770b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
7780b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7790b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (isAudio && enableAudio && !haveAudio) {
7800b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            haveAudio = true;
7810b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        } else if (isVideo && enableVideo && !haveVideo) {
7820b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            haveVideo = true;
7830b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        } else {
7840b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            continue;
7850b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
7860b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7870b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        err = mExtractor->selectTrack(i);
7880b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7890b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        size_t trackIndex = mTracks.size();
7900b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatTrackNotify, this);
7920b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        notify->setSize("trackIndex", trackIndex);
7930b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7940b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        sp<Track> track = new Track(notify, format);
7950b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        looper()->registerHandler(track);
7960b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7970b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mTracks.add(trackIndex, track);
7980b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7990b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mExtractorTrackToInternalTrack.add(i, trackIndex);
8000b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8010b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (isVideo) {
8020b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mVideoTrackIndex = trackIndex;
8030b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
8040b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8050b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        uint32_t flags = MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
8060b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8070b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        ssize_t mediaSenderTrackIndex =
8080b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mMediaSender->addTrack(format, flags);
8090b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        CHECK_GE(mediaSenderTrackIndex, 0);
8100b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8110b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
8120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if ((haveAudio || !enableAudio) && (haveVideo || !enableVideo)) {
8140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            break;
8150b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
8160b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8170b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8180b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    return OK;
8190b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8200b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8210b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::schedulePullExtractor() {
8220b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (mPullExtractorPending) {
8230b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return;
8240b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8250b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8263b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar    int64_t delayUs = 1000000; // default delay is 1 sec
8270b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t sampleTimeUs;
8280b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    status_t err = mExtractor->getSampleTime(&sampleTimeUs);
8290b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8303b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar    if (err == OK) {
8313b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        int64_t nowUs = ALooper::GetNowUs();
8320b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8333b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        if (mFirstSampleTimeRealUs < 0ll) {
8343b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar            mFirstSampleTimeRealUs = nowUs;
8353b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar            mFirstSampleTimeUs = sampleTimeUs;
8363b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        }
8370b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8383b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs;
8393b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        delayUs = whenUs - nowUs;
8403b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar    } else {
8413b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar        ALOGW("could not get sample time (%d)", err);
8423b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar    }
8430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, this);
8450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setInt32("generation", mPullExtractorGeneration);
8463b0da19c78f6a61ed343a07f2448b94faafe4c02Lajos Molnar    msg->post(delayUs);
8470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mPullExtractorPending = true;
8490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8510b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::onPullExtractor() {
8520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(1024 * 1024);
8530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    status_t err = mExtractor->readSampleData(accessUnit);
8540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (err != OK) {
8550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        // EOS.
8560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return;
8570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t timeUs;
8600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTime(&timeUs));
8610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    accessUnit->meta()->setInt64(
8630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            "timeUs", mFirstSampleTimeRealUs + timeUs - mFirstSampleTimeUs);
8640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    size_t trackIndex;
8660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex));
8670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConverterNotify, this);
8690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setSize(
8710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            "trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex));
8720b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8730b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setInt32("what", Converter::kWhatAccessUnit);
8740b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setBuffer("accessUnit", accessUnit);
8750b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->post();
8760b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8770b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mExtractor->advance();
8780b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8790b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    schedulePullExtractor();
8800b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8810b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
88294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer(
88394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableAudio,
88494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool usePCMAudio,
88594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableVideo,
88694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
887308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        size_t videoResolutionIndex,
888308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::ProfileType videoProfileType,
889308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::LevelType videoLevelType) {
89094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(enableAudio || enableVideo);
89194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
8920b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (!mMediaPath.empty()) {
8930b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return setupMediaPacketizer(enableAudio, enableVideo);
8940b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8950b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
89694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (enableVideo) {
89794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        status_t err = addVideoSource(
898308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                videoResolutionType, videoResolutionIndex, videoProfileType,
899308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                videoLevelType);
900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
90194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (err != OK) {
90294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            return err;
90394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
90494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
90594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
90694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (!enableAudio) {
90794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return OK;
908e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
909e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
910e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return addAudioSource(usePCMAudio);
911e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
912d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
913e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource(
9144a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
915308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        bool usePCMAudio, unsigned profileIdc, unsigned levelIdc,
916308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        unsigned constraintSet, size_t *numInputBuffers) {
917e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !isVideo);
918e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!isRepeaterSource || isVideo);
919308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(!profileIdc || isVideo);
920308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(!levelIdc || isVideo);
921308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(!constraintSet || isVideo);
922e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
923e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> pullLooper = new ALooper;
924e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->setName("pull_looper");
925e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
926e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->start(
927e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
928e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
929ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
931e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> codecLooper = new ALooper;
932e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->setName("codec_looper");
933e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
934e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->start(
935e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
936e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
937ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
938e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
939e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t trackIndex;
940e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
941e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<AMessage> notify;
942e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
943e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    trackIndex = mTracks.size();
944e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> format;
946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(err, (status_t)OK);
948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
949e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
9509fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber        format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
9513e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        format->setInt32(
9523e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                "android._input-metadata-buffer-type", kMetadataBufferTypeANWBuffer);
9533e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        format->setInt32("android._store-metadata-in-buffers-output", (mHDCP != NULL)
954ec3acca4a75fc4adc076b56751124f507b419622Chong Zhang                && (mHDCP->getCaps() & HDCPModule::HDCP_CAPS_ENCRYPT_NATIVE));
955e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32(
956e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber                "color-format", OMX_COLOR_FormatAndroidOpaque);
957308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        format->setInt32("profile-idc", profileIdc);
958308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        format->setInt32("level-idc", levelIdc);
959308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        format->setInt32("constraint-set", constraintSet);
9609fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    } else {
96178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        if (usePCMAudio) {
96278bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            format->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
96378bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            format->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
96478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        } else {
96578bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar            format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
96678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar        }
967e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
968d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatConverterNotify, this);
970e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify->setSize("trackIndex", trackIndex);
971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9729fef8d453b15a91a2b748faac2bfaff713bcf1e1Andreas Huber    sp<Converter> converter = new Converter(notify, codecLooper, format);
9733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
974a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    looper()->registerHandler(converter);
975a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
976a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber    err = converter->init();
9770224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    if (err != OK) {
9780224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err);
979a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber
980a05822a368dfc8c220b413c3d23dcc1af58b4b5fAndreas Huber        looper()->unregisterHandler(converter->id());
9810224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        return err;
9823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
98366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
9841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter);
98596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
98696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
98796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<MediaPuller> puller = new MediaPuller(source, notify);
98896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    pullLooper->registerHandler(puller);
98996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
990e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (numInputBuffers != NULL) {
991e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        *numInputBuffers = converter->getInputBufferCount();
992e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
99366e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
9941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    notify = new AMessage(kWhatTrackNotify, this);
99596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
99696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
99796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<Track> track = new Track(
99896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify, pullLooper, codecLooper, puller, converter);
99996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
10004a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (isRepeaterSource) {
10014a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
10024a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
10034a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
100496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    looper()->registerHandler(track);
100596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
100696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mTracks.add(trackIndex, track);
1007e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1008e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
1009e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mVideoTrackIndex = trackIndex;
1010e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
1011e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1012a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint32_t flags = 0;
1013a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (converter->needToManuallyPrependSPSPPS()) {
1014a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
1015a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
1016a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1017a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mediaSenderTrackIndex =
1018a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mMediaSender->addTrack(converter->getOutputFormat(), flags);
1019a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_GE(mediaSenderTrackIndex, 0);
1020a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1021a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
1022a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
1023e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
1024e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
1025e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
102694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource(
102794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
1028308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        size_t videoResolutionIndex,
1029308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::ProfileType videoProfileType,
1030308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        VideoFormats::LevelType videoLevelType) {
103194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    size_t width, height, framesPerSecond;
103294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    bool interlaced;
103394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(VideoFormats::GetConfiguration(
103494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                videoResolutionType,
103594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                videoResolutionIndex,
103694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &width,
103794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &height,
103894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &framesPerSecond,
103994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &interlaced));
104094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
1041308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    unsigned profileIdc, levelIdc, constraintSet;
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    CHECK(VideoFormats::GetProfileLevel(
1043308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                videoProfileType,
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                videoLevelType,
1045308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                &profileIdc,
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                &levelIdc,
1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                &constraintSet));
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
104994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width, height);
1050e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1051af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    source->setUseAbsoluteTimestamps();
1052af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber
10534a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> videoSource =
105494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        new RepeaterSource(source, framesPerSecond);
10554a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
1056e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t numInputBuffers;
10574a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    status_t err = addSource(
10584a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            true /* isVideo */, videoSource, true /* isRepeaterSource */,
1059308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            false /* usePCMAudio */, profileIdc, levelIdc, constraintSet,
1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            &numInputBuffers);
1061e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1062e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
1063e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
1064e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
106566e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
10665a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber    err = source->setMaxAcquiredBufferCount(numInputBuffers);
106766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    CHECK_EQ(err, (status_t)OK);
106866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
10695205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mProducer = source->getProducer();
10700b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
1071e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
1072e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
1073e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1074e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
1075082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber    sp<AudioSource> audioSource = new AudioSource(
10761646a0fed94c30a44128b3c379736def4b332033Andreas Huber            AUDIO_SOURCE_REMOTE_SUBMIX,
1077be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov            mOpPackageName,
1078082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber            48000 /* sampleRate */,
10791646a0fed94c30a44128b3c379736def4b332033Andreas Huber            2 /* channelCount */);
1080082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
10817977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    if (audioSource->initCheck() == OK) {
1082e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return addSource(
10834a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber                false /* isVideo */, audioSource, false /* isRepeaterSource */,
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                usePCMAudio, 0 /* profileIdc */, 0 /* levelIdc */,
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                0 /* constraintSet */, NULL /* numInputBuffers */);
10867977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    }
1087e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1088e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    ALOGW("Unable to instantiate audio source");
1089082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
1090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
10938ba01021b573889802e67e029225a96f0dfa471aAndy McFaddensp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
10945205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    return mProducer;
10950b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
10960b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
1097496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1098496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
1099496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        const sp<Track> &track = mTracks.valueAt(i);
1100496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
11014a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->requestIDRFrame();
1102496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
1103496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
1104496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1105ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() {
1106ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    // Inform WifiDisplaySource of our premature death (wish).
1107ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    sp<AMessage> notify = mNotify->dup();
1108ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->setInt32("what", kWhatSessionDead);
1109ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->post();
1110ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1111ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    mWeAreDead = true;
1112ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber}
1113ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
1115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1116