PlaybackSession.cpp revision c86ef45279185b474bd6af0a7ae407f8ab577f13
1d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber/*
2d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Copyright 2012, The Android Open Source Project
3d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
4d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * you may not use this file except in compliance with the License.
6d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * You may obtain a copy of the License at
7d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
8d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber *
10d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * Unless required by applicable law or agreed to in writing, software
11d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * See the License for the specific language governing permissions and
14d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber * limitations under the License.
15d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber */
16d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
17d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber//#define LOG_NDEBUG 0
18d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define LOG_TAG "PlaybackSession"
19d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <utils/Log.h>
20d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
21d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "PlaybackSession.h"
22d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
23d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Converter.h"
24e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber#include "MediaPuller.h"
25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "RepeaterSource.h"
26e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include "include/avc_utils.h"
270224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#include "WifiDisplaySource.h"
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h>
30eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber#include <cutils/properties.h>
31b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.h>
32e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h>
37082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h>
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h>
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h>
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h>
430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber#include <media/stagefright/NuMediaExtractor.h>
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h>
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h>
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler {
5296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
5396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatStopped,
5496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
5596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    Track(const sp<AMessage> &notify,
5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber          const sp<ALooper> &pullLooper,
58e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<ALooper> &codecLooper,
59e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<MediaPuller> &mediaPuller,
60e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<Converter> &converter);
61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    Track(const sp<AMessage> &notify, const sp<AMessage> &format);
630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
644a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void setRepeaterSource(const sp<RepeaterSource> &source);
654a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> getFormat();
67b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool isAudio() const;
68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<Converter> &converter() const;
70eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    const sp<RepeaterSource> &repeaterSource() const;
71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
72a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mediaSenderTrackIndex() const;
73a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    void setMediaSenderTrackIndex(size_t index);
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t start();
7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    void stopAsync();
7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
785131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    void pause();
795131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    void resume();
805131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
8128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    void queueAccessUnit(const sp<ABuffer> &accessUnit);
8228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> dequeueAccessUnit();
8328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
8490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool hasOutputBuffer(int64_t *timeUs) const;
8590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    void queueOutputBuffer(const sp<ABuffer> &accessUnit);
8690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> dequeueOutputBuffer();
870224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber
880224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE
8990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool isSuspended() const;
900224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif
9190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
9290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t countQueuedOutputBuffers() const {
9390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return mQueuedOutputBuffers.size();
9490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
9590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
964a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void requestIDRFrame();
974a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected:
9996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    virtual ~Track();
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate:
10396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
10496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatMediaPullerStopped,
10596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
10696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
10796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> mNotify;
108e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mPullLooper;
109e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mCodecLooper;
110e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<MediaPuller> mMediaPuller;
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> mConverter;
1120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<AMessage> mFormat;
113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    bool mStarted;
114a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mMediaSenderTrackIndex;
115b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool mIsAudio;
11628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    List<sp<ABuffer> > mQueuedAccessUnits;
1174a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> mRepeaterSource;
11890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    List<sp<ABuffer> > mQueuedOutputBuffers;
11990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t mLastOutputBufferQueuedTimeUs;
120b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
121b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    static bool IsAudioFormat(const sp<AMessage> &format);
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber};
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
126e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
12796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &notify,
128e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &pullLooper,
129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &codecLooper,
130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<MediaPuller> &mediaPuller,
131e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<Converter> &converter)
13296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    : mNotify(notify),
13396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber      mPullLooper(pullLooper),
134e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mCodecLooper(codecLooper),
135e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mMediaPuller(mediaPuller),
136e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mConverter(converter),
137e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mStarted(false),
13890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
13990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1420b530f1050150bb751ae642d5a9dce34141d9475Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
1430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const sp<AMessage> &notify, const sp<AMessage> &format)
1440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    : mNotify(notify),
1450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFormat(format),
1460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mStarted(false),
1470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mIsAudio(IsAudioFormat(format)),
1480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
1490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
1500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
15296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
155b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static
156b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
157b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<AMessage> &format) {
158b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    AString mime;
159b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    CHECK(format->findString("mime", &mime));
160b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
161b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return !strncasecmp(mime.c_str(), "audio/", 6);
162b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
163b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
1650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    return mFormat != NULL ? mFormat : mConverter->getOutputFormat();
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
168b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
169b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return mIsAudio;
170b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
171b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter;
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
176eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huberconst sp<RepeaterSource> &
177eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas HuberWifiDisplaySource::PlaybackSession::Track::repeaterSource() const {
178eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber    return mRepeaterSource;
179eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber}
180eaf5381f38bf6c3ecb5fe32a8351c26a447549f5Andreas Huber
181a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
182a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_GE(mMediaSenderTrackIndex, 0);
183a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return mMediaSenderTrackIndex;
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
186a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex(
187a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        size_t index) {
188a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSenderTrackIndex = index;
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
191e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
192ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    ALOGV("Track::start isAudio=%d", mIsAudio);
193ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
19496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
195e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
196e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = OK;
197e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
198e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (mMediaPuller != NULL) {
199e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        err = mMediaPuller->start();
200e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
201e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
202e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err == OK) {
203e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mStarted = true;
204e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
205e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
206e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return err;
207e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
208e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
20996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() {
21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
211ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
2120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (mConverter != NULL) {
2130b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mConverter->shutdownAsync();
2140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
217e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
218ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber    if (mStarted && mMediaPuller != NULL) {
2194a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        if (mRepeaterSource != NULL) {
2204a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            // Let's unblock MediaPuller's MediaSource::read().
2214a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            mRepeaterSource->wakeUp();
2224a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        }
2234a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mMediaPuller->stopAsync(msg);
22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    } else {
2260b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mStarted = false;
22796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        msg->post();
228e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
22996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
230e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
2315131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::pause() {
2325131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    mMediaPuller->pause();
2335131d127a042ee88f903370be88845dc8c9f8578Andreas Huber}
2345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
2355131d127a042ee88f903370be88845dc8c9f8578Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::resume() {
2365131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    mMediaPuller->resume();
2375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber}
2385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
23996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
24096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &msg) {
24196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    switch (msg->what()) {
24296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerStopped:
24396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
24496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mConverter.clear();
245a438123bd96c7faf145683876702387efe5628d9Andreas Huber
24696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mStarted = false;
247e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
24896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            sp<AMessage> notify = mNotify->dup();
24996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->setInt32("what", kWhatStopped);
25096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->post();
25177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
25277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
25396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
25496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
25596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
25696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        default:
25796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            TRESPASS();
25896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    }
259e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
260e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
26128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
26228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        const sp<ABuffer> &accessUnit) {
26328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.push_back(accessUnit);
26428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
26528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
26628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
26728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mQueuedAccessUnits.empty()) {
26828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return NULL;
26928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
27028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
27228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    CHECK(accessUnit != NULL);
27328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
27528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
27628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return accessUnit;
27728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
27828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
2794a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
2804a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        const sp<RepeaterSource> &source) {
2814a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mRepeaterSource = source;
2824a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2834a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2844a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
2854a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mIsAudio) {
2864a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        return;
2874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mRepeaterSource != NULL) {
2904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mRepeaterSource->wakeUp();
2914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2924a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2934a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mConverter->requestIDRFrame();
2944a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t *timeUs) const {
29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    *timeUs = 0ll;
29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mQueuedOutputBuffers.empty()) {
30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return true;
30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
31290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<ABuffer> &accessUnit) {
31390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.push_back(accessUnit);
31490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
31590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
31690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
31790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
31890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(!mQueuedOutputBuffers.empty());
31990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
32190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
32290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
32390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return outputBuffer;
32490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
32590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
3260224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#if SUSPEND_VIDEO_IF_IDLE
32790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
32890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (!mQueuedOutputBuffers.empty()) {
32990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
33090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mLastOutputBufferQueuedTimeUs < 0ll) {
33390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // We've never seen an output buffer queued, but tracks start
33490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // out live, not suspended.
33590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
33690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
33790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
33890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // If we've not seen new output data for 60ms or more, we consider
33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // this track suspended for the time being.
34090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
34190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
3420224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber#endif
34390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber////////////////////////////////////////////////////////////////////////////////
345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ANetworkSession> &netSession,
3480b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber        const sp<AMessage> &notify,
349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        const in_addr &interfaceAddr,
3500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const sp<IHDCP> &hdcp,
3510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        const char *path)
352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mNetSession(netSession),
353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mInterfaceAddr(interfaceAddr),
355b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mHDCP(hdcp),
356a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber      mLocalRTPPort(-1),
357ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber      mWeAreDead(false),
3585131d127a042ee88f903370be88845dc8c9f8578Andreas Huber      mPaused(false),
359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastLifesignUs(),
360e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mVideoTrackIndex(-1),
3610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPrevTimeUs(-1ll),
3620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPullExtractorPending(false),
3630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mPullExtractorGeneration(0),
3640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFirstSampleTimeRealUs(-1ll),
3650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber      mFirstSampleTimeUs(-1ll) {
3660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (path != NULL) {
3670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mMediaPath.setTo(path);
3680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
3722aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        const char *clientIP,
3732aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        int32_t clientRtp,
3742aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        RTPSender::TransportMode rtpMode,
3752aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        int32_t clientRtcp,
3762aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber        RTPSender::TransportMode rtcpMode,
37794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableAudio,
37894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool usePCMAudio,
37994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableVideo,
38094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
38194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        size_t videoResolutionIndex) {
382a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, id());
383a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSender = new MediaSender(mNetSession, notify);
384a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    looper()->registerHandler(mMediaSender);
385a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
386a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    mMediaSender->setHDCP(mHDCP);
387a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
38894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    status_t err = setupPacketizer(
38994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            enableAudio,
39094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            usePCMAudio,
39194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            enableVideo,
39294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            videoResolutionType,
39394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            videoResolutionIndex);
394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
395a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err == OK) {
396a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        err = mMediaSender->initAsync(
397a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                -1 /* trackIndex */,
398a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientIP,
399a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientRtp,
4002aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber                rtpMode,
401a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                clientRtcp,
4022aea9552aeba92bbaf9e56c666049ea2d14057b5Andreas Huber                rtcpMode,
403a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                &mLocalRTPPort);
404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
406a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (err != OK) {
407a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mLocalRTPPort = -1;
408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
409a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        looper()->unregisterHandler(mMediaSender->id());
410a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mMediaSender.clear();
411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
41290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return err;
413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
414d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
424a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    return mLocalRTPPort;
425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mLastLifesignUs;
429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    (new AMessage(kWhatResume, id()))->post();
4395131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
440bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
441bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
442bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
443a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
444e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
44596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
446e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
447e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
448bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    sp<AMessage> notify = mNotify->dup();
449bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->setInt32("what", kWhatSessionEstablished);
450bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->post();
451bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
452e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4585131d127a042ee88f903370be88845dc8c9f8578Andreas Huber    (new AMessage(kWhatPause, id()))->post();
4595131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
46396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() {
46496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGI("destroyAsync");
465a438123bd96c7faf145683876702387efe5628d9Andreas Huber
46696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
46796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mTracks.valueAt(i)->stopAsync();
468a438123bd96c7faf145683876702387efe5628d9Andreas Huber    }
469a438123bd96c7faf145683876702387efe5628d9Andreas Huber}
470a438123bd96c7faf145683876702387efe5628d9Andreas Huber
471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &msg) {
473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatConverterNotify:
475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
4766360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            if (mWeAreDead) {
4776360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                ALOGV("dropping msg '%s' because we're dead",
4786360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                      msg->debugString().c_str());
4796360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
4806360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                break;
4816360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            }
4826360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t trackIndex;
487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Converter::kWhatAccessUnit) {
49028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                sp<ABuffer> accessUnit;
49128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
493a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
495a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                status_t err = mMediaSender->queueAccessUnit(
496a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        track->mediaSenderTrackIndex(),
497a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                        accessUnit);
498774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
499a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (err != OK) {
500a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    notifySessionDead();
501a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
50228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                break;
503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else if (what == Converter::kWhatEOS) {
504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGI("output EOS on track %d", trackIndex);
507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_GE(index, 0);
510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Converter> &converter =
512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(index)->converter();
513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                looper()->unregisterHandler(converter->id());
514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.removeItemsAt(index);
516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (mTracks.isEmpty()) {
518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("Reached EOS");
519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                status_t err;
524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findInt32("err", &err));
525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGE("converter signaled error %d", err);
527ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber
528ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                notifySessionDead();
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
533a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        case kWhatMediaSenderNotify:
53490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
53590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t what;
53690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findInt32("what", &what));
53790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
538a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            if (what == MediaSender::kWhatInitDone) {
539a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                status_t err;
540a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                CHECK(msg->findInt32("err", &err));
5417cc0c29d6a7b76520ec588437ab51d5b8eac9ebcAndreas Huber
542a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                if (err == OK) {
543a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    onMediaSenderInitialized();
544a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                } else {
545a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                    notifySessionDead();
546a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                }
547a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber            } else if (what == MediaSender::kWhatError) {
548a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                notifySessionDead();
549126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber            } else if (what == MediaSender::kWhatNetworkStall) {
550126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                size_t numBytesQueued;
551126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
552126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
553126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                if (mVideoTrackIndex >= 0) {
554126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                    const sp<Track> &videoTrack =
555126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                        mTracks.valueFor(mVideoTrackIndex);
556126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber
5570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    sp<Converter> converter = videoTrack->converter();
5580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    if (converter != NULL) {
5590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                        converter->dropAFrame();
5600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                    }
561126568c7aeeb5570789e70a310477f44dbdbd885Andreas Huber                }
562c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            } else if (what == MediaSender::kWhatInformSender) {
563c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                onSinkFeedback(msg);
56490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else {
56590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                TRESPASS();
56690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
567bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            break;
568bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        }
569bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
57096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatTrackNotify:
57196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
57296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
57396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
57496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
57596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            size_t trackIndex;
57696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
57796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
57896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == Track::kWhatStopped) {
57977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                ALOGI("Track %d stopped", trackIndex);
58096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
58177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                sp<Track> track = mTracks.valueFor(trackIndex);
58277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                looper()->unregisterHandler(track->id());
58377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                mTracks.removeItem(trackIndex);
58477245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                track.clear();
58577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
58677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                if (!mTracks.isEmpty()) {
58777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                    ALOGI("not all tracks are stopped yet");
58896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    break;
58996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
59096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
591a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                looper()->unregisterHandler(mMediaSender->id());
592a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber                mMediaSender.clear();
59396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
59490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                sp<AMessage> notify = mNotify->dup();
59590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->setInt32("what", kWhatSessionDestroyed);
59690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->post();
59790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
59890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
59990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
60096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
6015131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        case kWhatPause:
6025131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        {
6030b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (mExtractor != NULL) {
6040b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                ++mPullExtractorGeneration;
6050b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                mFirstSampleTimeRealUs = -1ll;
6060b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                mFirstSampleTimeUs = -1ll;
6070b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6080b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6095131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            if (mPaused) {
6105131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                break;
6115131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6125131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6135131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
6145131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                mTracks.editValueAt(i)->pause();
6155131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6165131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6175131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            mPaused = true;
6185131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            break;
6195131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        }
6205131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6215131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        case kWhatResume:
6225131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        {
6230b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (mExtractor != NULL) {
6240b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                schedulePullExtractor();
6250b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6260b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6275131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            if (!mPaused) {
6285131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                break;
6295131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6305131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6315131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
6325131d127a042ee88f903370be88845dc8c9f8578Andreas Huber                mTracks.editValueAt(i)->resume();
6335131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            }
6345131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6355131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            mPaused = false;
6365131d127a042ee88f903370be88845dc8c9f8578Andreas Huber            break;
6375131d127a042ee88f903370be88845dc8c9f8578Andreas Huber        }
6385131d127a042ee88f903370be88845dc8c9f8578Andreas Huber
6390b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        case kWhatPullExtractorSample:
6400b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        {
6410b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            int32_t generation;
6420b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            CHECK(msg->findInt32("generation", &generation));
6430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            if (generation != mPullExtractorGeneration) {
6450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber                break;
6460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            }
6470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mPullExtractorPending = false;
6490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
6500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            onPullExtractor();
6510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            break;
6520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
6530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
659c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Hubervoid WifiDisplaySource::PlaybackSession::onSinkFeedback(const sp<AMessage> &msg) {
660c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    int64_t avgLatencyUs;
661c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    CHECK(msg->findInt64("avgLatencyUs", &avgLatencyUs));
662c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
663c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    int64_t maxLatencyUs;
664c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    CHECK(msg->findInt64("maxLatencyUs", &maxLatencyUs));
665c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
666c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    ALOGI("sink reports avg. latency of %lld ms (max %lld ms)",
667c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber          avgLatencyUs / 1000ll,
668c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber          maxLatencyUs / 1000ll);
669c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
670c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    if (mVideoTrackIndex >= 0) {
671c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        const sp<Track> &videoTrack = mTracks.valueFor(mVideoTrackIndex);
672c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        sp<Converter> converter = videoTrack->converter();
673c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
674c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        if (converter != NULL) {
675c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            int32_t videoBitrate =
676c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                Converter::GetInt32Property("media.wfd.video-bitrate", -1);
677c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
678c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            char val[PROPERTY_VALUE_MAX];
679c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (videoBitrate < 0
680c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && property_get("media.wfd.video-bitrate", val, NULL)
681c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && !strcasecmp("adaptive", val)) {
682c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                videoBitrate = converter->getVideoBitrate();
683c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
684c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (avgLatencyUs > 300000ll) {
685c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate *= 0.6;
686c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (avgLatencyUs < 100000ll) {
687c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate *= 1.1;
688c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
689c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
690c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
691c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (videoBitrate > 0) {
692c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (videoBitrate < 500000) {
693c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate = 500000;
694c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (videoBitrate > 10000000) {
695c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    videoBitrate = 10000000;
696c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
697c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
698c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (videoBitrate != converter->getVideoBitrate()) {
699c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    ALOGI("setting video bitrate to %d bps", videoBitrate);
700c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
701c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    converter->setVideoBitrate(videoBitrate);
702c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
703c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
704c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        }
705c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
706c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        sp<RepeaterSource> repeaterSource = videoTrack->repeaterSource();
707c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        if (repeaterSource != NULL) {
708c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            double rateHz =
709c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                Converter::GetInt32Property(
710c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                        "media.wfd.video-framerate", -1);
711c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
712c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            char val[PROPERTY_VALUE_MAX];
713c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (rateHz < 0.0
714c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && property_get("media.wfd.video-framerate", val, NULL)
715c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    && !strcasecmp("adaptive", val)) {
716c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                 rateHz = repeaterSource->getFrameRate();
717c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
718c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (avgLatencyUs > 300000ll) {
719c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz *= 0.9;
720c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (avgLatencyUs < 200000ll) {
721c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz *= 1.1;
722c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
723c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
724c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
725c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            if (rateHz > 0) {
726c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (rateHz < 5.0) {
727c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz = 5.0;
728c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                } else if (rateHz > 30.0) {
729c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    rateHz = 30.0;
730c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
731c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
732c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                if (rateHz != repeaterSource->getFrameRate()) {
733c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    ALOGI("setting frame rate to %.2f Hz", rateHz);
734c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
735c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                    repeaterSource->setFrameRate(rateHz);
736c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber                }
737c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber            }
738c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber        }
739c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber    }
740c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber}
741c86ef45279185b474bd6af0a7ae407f8ab577f13Andreas Huber
7420b530f1050150bb751ae642d5a9dce34141d9475Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
7430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool enableAudio, bool enableVideo) {
7440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    DataSource::RegisterDefaultSniffers();
7450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mExtractor = new NuMediaExtractor;
7470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    status_t err = mExtractor->setDataSource(mMediaPath.c_str());
7490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (err != OK) {
7510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return err;
7520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
7530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    size_t n = mExtractor->countTracks();
7550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    bool haveAudio = false;
7560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    bool haveVideo = false;
7570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    for (size_t i = 0; i < n; ++i) {
7580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        sp<AMessage> format;
7590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        err = mExtractor->getTrackFormat(i, &format);
7600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (err != OK) {
7620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            continue;
7630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
7640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        AString mime;
7660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        CHECK(format->findString("mime", &mime));
7670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7680b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
7690b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
7700b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7710b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (isAudio && enableAudio && !haveAudio) {
7720b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            haveAudio = true;
7730b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        } else if (isVideo && enableVideo && !haveVideo) {
7740b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            haveVideo = true;
7750b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        } else {
7760b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            continue;
7770b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
7780b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7790b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        err = mExtractor->selectTrack(i);
7800b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7810b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        size_t trackIndex = mTracks.size();
7820b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7830b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        sp<AMessage> notify = new AMessage(kWhatTrackNotify, id());
7840b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        notify->setSize("trackIndex", trackIndex);
7850b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7860b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        sp<Track> track = new Track(notify, format);
7870b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        looper()->registerHandler(track);
7880b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7890b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mTracks.add(trackIndex, track);
7900b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7910b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mExtractorTrackToInternalTrack.add(i, trackIndex);
7920b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7930b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if (isVideo) {
7940b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mVideoTrackIndex = trackIndex;
7950b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
7960b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7970b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        uint32_t flags = MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
7980b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
7990b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        ssize_t mediaSenderTrackIndex =
8000b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            mMediaSender->addTrack(format, flags);
8010b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        CHECK_GE(mediaSenderTrackIndex, 0);
8020b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8030b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
8040b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8050b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        if ((haveAudio || !enableAudio) && (haveVideo || !enableVideo)) {
8060b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            break;
8070b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        }
8080b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8090b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8100b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    return OK;
8110b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8120b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8130b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::schedulePullExtractor() {
8140b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (mPullExtractorPending) {
8150b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return;
8160b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8170b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8180b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t sampleTimeUs;
8190b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    status_t err = mExtractor->getSampleTime(&sampleTimeUs);
8200b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8210b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t nowUs = ALooper::GetNowUs();
8220b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8230b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (mFirstSampleTimeRealUs < 0ll) {
8240b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mFirstSampleTimeRealUs = nowUs;
8250b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        mFirstSampleTimeUs = sampleTimeUs;
8260b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8270b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8280b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs;
8290b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8300b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, id());
8310b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setInt32("generation", mPullExtractorGeneration);
8320b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->post(whenUs - nowUs);
8330b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8340b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mPullExtractorPending = true;
8350b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8360b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8370b530f1050150bb751ae642d5a9dce34141d9475Andreas Hubervoid WifiDisplaySource::PlaybackSession::onPullExtractor() {
8380b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(1024 * 1024);
8390b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    status_t err = mExtractor->readSampleData(accessUnit);
8400b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (err != OK) {
8410b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        // EOS.
8420b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return;
8430b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8440b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8450b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    int64_t timeUs;
8460b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTime(&timeUs));
8470b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8480b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    accessUnit->meta()->setInt64(
8490b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            "timeUs", mFirstSampleTimeRealUs + timeUs - mFirstSampleTimeUs);
8500b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8510b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    size_t trackIndex;
8520b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex));
8530b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8540b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
8550b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8560b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setSize(
8570b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber            "trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex));
8580b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8590b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setInt32("what", Converter::kWhatAccessUnit);
8600b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->setBuffer("accessUnit", accessUnit);
8610b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    msg->post();
8620b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8630b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    mExtractor->advance();
8640b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
8650b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    schedulePullExtractor();
8660b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber}
8670b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
86894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer(
86994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableAudio,
87094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool usePCMAudio,
87194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        bool enableVideo,
87294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
87394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        size_t videoResolutionIndex) {
87494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(enableAudio || enableVideo);
87594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
8760b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    if (!mMediaPath.empty()) {
8770b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber        return setupMediaPacketizer(enableAudio, enableVideo);
8780b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber    }
8790b530f1050150bb751ae642d5a9dce34141d9475Andreas Huber
88094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (enableVideo) {
88194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        status_t err = addVideoSource(
88294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                videoResolutionType, videoResolutionIndex);
883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
88494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        if (err != OK) {
88594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber            return err;
88694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        }
88794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    }
88894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
88994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    if (!enableAudio) {
89094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        return OK;
891e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
892e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
893e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return addAudioSource(usePCMAudio);
894e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
895d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
896e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource(
8974a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
898e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio, size_t *numInputBuffers) {
899e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !isVideo);
900e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!isRepeaterSource || isVideo);
901e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
902e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> pullLooper = new ALooper;
903e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->setName("pull_looper");
904e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
905e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->start(
906e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
907e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
908ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
909d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
910e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> codecLooper = new ALooper;
911e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->setName("codec_looper");
912e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
913e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->start(
914e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
915e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
916ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
917e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
918e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t trackIndex;
919e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
920e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<AMessage> notify;
921e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
922e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    trackIndex = mTracks.size();
923e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
924d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> format;
925d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
926d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(err, (status_t)OK);
927d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
928e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
929e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32("store-metadata-in-buffers", true);
930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
931e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32(
932e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber                "color-format", OMX_COLOR_FormatAndroidOpaque);
933e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
935e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify = new AMessage(kWhatConverterNotify, id());
936e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify->setSize("trackIndex", trackIndex);
937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> converter =
939e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        new Converter(notify, codecLooper, format, usePCMAudio);
9403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9410224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    err = converter->initCheck();
9420224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber    if (err != OK) {
9430224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err);
9440224bf170a3904576bba81593eaab113c5d3a4e7Andreas Huber        return err;
9453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
94666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    looper()->registerHandler(converter);
948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
94996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
95096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
95196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
95296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<MediaPuller> puller = new MediaPuller(source, notify);
95396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    pullLooper->registerHandler(puller);
95496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
955e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (numInputBuffers != NULL) {
956e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        *numInputBuffers = converter->getInputBufferCount();
957e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
95866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
95996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(kWhatTrackNotify, id());
96096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
96196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
96296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<Track> track = new Track(
96396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify, pullLooper, codecLooper, puller, converter);
96496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
9654a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (isRepeaterSource) {
9664a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
9674a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
9684a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
96996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    looper()->registerHandler(track);
97096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
97196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mTracks.add(trackIndex, track);
972e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
973e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
974e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mVideoTrackIndex = trackIndex;
975e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
976e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
977a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    uint32_t flags = 0;
978a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    if (converter->needToManuallyPrependSPSPPS()) {
979a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
980a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    }
981a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
982a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    ssize_t mediaSenderTrackIndex =
983a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber        mMediaSender->addTrack(converter->getOutputFormat(), flags);
984a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    CHECK_GE(mediaSenderTrackIndex, 0);
985a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
986a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber    track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
987a556c4822fc205db0d27834ba5b637c351d73ffaAndreas Huber
988e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
989e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
990e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
99194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource(
99294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        VideoFormats::ResolutionType videoResolutionType,
99394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        size_t videoResolutionIndex) {
99494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    size_t width, height, framesPerSecond;
99594a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    bool interlaced;
99694a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    CHECK(VideoFormats::GetConfiguration(
99794a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                videoResolutionType,
99894a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                videoResolutionIndex,
99994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &width,
100094a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &height,
100194a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &framesPerSecond,
100294a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber                &interlaced));
100394a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber
100494a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width, height);
1005e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1006af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    source->setUseAbsoluteTimestamps();
1007af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber
10084a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> videoSource =
100994a483bf2bd699275673d9cd57cb125d48572f30Andreas Huber        new RepeaterSource(source, framesPerSecond);
10104a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
1011e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t numInputBuffers;
10124a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    status_t err = addSource(
10134a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            true /* isVideo */, videoSource, true /* isRepeaterSource */,
1014e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
1015e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1016e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
1017e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
1018e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
101966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
10205a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber    err = source->setMaxAcquiredBufferCount(numInputBuffers);
102166e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    CHECK_EQ(err, (status_t)OK);
102266e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
10230b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    mBufferQueue = source->getBufferQueue();
10240b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
1025e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
1026e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
1027e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1028e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
1029082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber    sp<AudioSource> audioSource = new AudioSource(
10301646a0fed94c30a44128b3c379736def4b332033Andreas Huber            AUDIO_SOURCE_REMOTE_SUBMIX,
1031082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber            48000 /* sampleRate */,
10321646a0fed94c30a44128b3c379736def4b332033Andreas Huber            2 /* channelCount */);
1033082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
10347977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    if (audioSource->initCheck() == OK) {
1035e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return addSource(
10364a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber                false /* isVideo */, audioSource, false /* isRepeaterSource */,
1037e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                usePCMAudio, NULL /* numInputBuffers */);
10387977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    }
1039e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
1040e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    ALOGW("Unable to instantiate audio source");
1041082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
10458ba01021b573889802e67e029225a96f0dfa471aAndy McFaddensp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
10460b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    return mBufferQueue;
10470b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
10480b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
1049496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1050496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
1051496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        const sp<Track> &track = mTracks.valueAt(i);
1052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
10534a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->requestIDRFrame();
1054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
1055496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
1056496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1057ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() {
1058ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    // Inform WifiDisplaySource of our premature death (wish).
1059ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    sp<AMessage> notify = mNotify->dup();
1060ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->setInt32("what", kWhatSessionDead);
1061ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->post();
1062ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1063ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    mWeAreDead = true;
1064ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber}
1065ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1068