135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber/*
235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * Copyright 2012, The Android Open Source Project
335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber *
435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * you may not use this file except in compliance with the License.
635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * You may obtain a copy of the License at
735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber *
835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber *
1035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * Unless required by applicable law or agreed to in writing, software
1135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * See the License for the specific language governing permissions and
1435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber * limitations under the License.
1535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber */
1635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
1735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber//#define LOG_NDEBUG 0
1835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#define LOG_TAG "PlaybackSession"
1935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <utils/Log.h>
2035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
2135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include "PlaybackSession.h"
2235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
2335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include "Converter.h"
24eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber#include "MediaPuller.h"
2535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include "RepeaterSource.h"
26af5f02cdd48b8c93a1976c8e078586216d96bdc0Andreas Huber#include "include/avc_utils.h"
2783c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber#include "WifiDisplaySource.h"
2835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
2935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <binder/IServiceManager.h>
304646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huber#include <cutils/properties.h>
3175a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber#include <media/IHDCP.h>
32af5f02cdd48b8c93a1976c8e078586216d96bdc0Andreas Huber#include <media/stagefright/foundation/ABitReader.h>
3335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
3435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/foundation/ADebug.h>
3535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/foundation/AMessage.h>
3635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/foundation/hexdump.h>
37bd381af4d618a4da78de99d05d44a10c0c37207bAndreas Huber#include <media/stagefright/AudioSource.h>
3835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/DataSource.h>
3935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/MediaDefs.h>
4035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/MediaErrors.h>
4135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/MediaSource.h>
4235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/MetaData.h>
4316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber#include <media/stagefright/NuMediaExtractor.h>
4435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
4535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <media/stagefright/Utils.h>
4635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
4735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber#include <OMX_IVCommon.h>
4835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
4935213f1420c669f43314cb75eadea450d21a75cbAndreas Hubernamespace android {
5035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
51a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler {
52a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    enum {
53a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        kWhatStopped,
54a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    };
55a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
56a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    Track(const sp<AMessage> &notify,
57a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber          const sp<ALooper> &pullLooper,
58eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber          const sp<ALooper> &codecLooper,
59eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber          const sp<MediaPuller> &mediaPuller,
60eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber          const sp<Converter> &converter);
61eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
6216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    Track(const sp<AMessage> &notify, const sp<AMessage> &format);
6316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
6477c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    void setRepeaterSource(const sp<RepeaterSource> &source);
6577c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
6635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    sp<AMessage> getFormat();
6775a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    bool isAudio() const;
6835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
6935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    const sp<Converter> &converter() const;
704646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huber    const sp<RepeaterSource> &repeaterSource() const;
7135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
7243433111d4adff6a138447dfadf531046497a008Andreas Huber    ssize_t mediaSenderTrackIndex() const;
7343433111d4adff6a138447dfadf531046497a008Andreas Huber    void setMediaSenderTrackIndex(size_t index);
7435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
75eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    status_t start();
76a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    void stopAsync();
77a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
78bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    void pause();
79bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    void resume();
80bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
810d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    void queueAccessUnit(const sp<ABuffer> &accessUnit);
820d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    sp<ABuffer> dequeueAccessUnit();
830d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
84bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    bool hasOutputBuffer(int64_t *timeUs) const;
85bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    void queueOutputBuffer(const sp<ABuffer> &accessUnit);
86bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    sp<ABuffer> dequeueOutputBuffer();
8783c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber
8883c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber#if SUSPEND_VIDEO_IF_IDLE
89bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    bool isSuspended() const;
9083c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber#endif
91bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
92bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    size_t countQueuedOutputBuffers() const {
93bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return mQueuedOutputBuffers.size();
94bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
95bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
9677c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    void requestIDRFrame();
9777c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
9835213f1420c669f43314cb75eadea450d21a75cbAndreas Huberprotected:
99a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
10035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    virtual ~Track();
10135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
10235213f1420c669f43314cb75eadea450d21a75cbAndreas Huberprivate:
103a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    enum {
104a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        kWhatMediaPullerStopped,
105a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    };
106a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
107a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    sp<AMessage> mNotify;
108eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<ALooper> mPullLooper;
109eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<ALooper> mCodecLooper;
110eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<MediaPuller> mMediaPuller;
11135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    sp<Converter> mConverter;
11216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    sp<AMessage> mFormat;
113eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    bool mStarted;
11443433111d4adff6a138447dfadf531046497a008Andreas Huber    ssize_t mMediaSenderTrackIndex;
11575a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    bool mIsAudio;
1160d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    List<sp<ABuffer> > mQueuedAccessUnits;
11777c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    sp<RepeaterSource> mRepeaterSource;
118bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    List<sp<ABuffer> > mQueuedOutputBuffers;
119bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    int64_t mLastOutputBufferQueuedTimeUs;
12075a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber
12175a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    static bool IsAudioFormat(const sp<AMessage> &format);
12235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
12335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
12435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber};
12535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
126eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
127a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        const sp<AMessage> &notify,
128eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        const sp<ALooper> &pullLooper,
129eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        const sp<ALooper> &codecLooper,
130eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        const sp<MediaPuller> &mediaPuller,
131eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        const sp<Converter> &converter)
132a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    : mNotify(notify),
133a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber      mPullLooper(pullLooper),
134eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber      mCodecLooper(codecLooper),
135eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber      mMediaPuller(mediaPuller),
136eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber      mConverter(converter),
137eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber      mStarted(false),
138bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
139bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
14035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
14135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
14216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
14316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        const sp<AMessage> &notify, const sp<AMessage> &format)
14416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    : mNotify(notify),
14516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mFormat(format),
14616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mStarted(false),
14716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mIsAudio(IsAudioFormat(format)),
14816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
14916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber}
15016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
15135213f1420c669f43314cb75eadea450d21a75cbAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
152a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    CHECK(!mStarted);
15335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
15435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
15575a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber// static
15675a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
15775a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber        const sp<AMessage> &format) {
15875a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    AString mime;
15975a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    CHECK(format->findString("mime", &mime));
16075a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber
16175a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    return !strncasecmp(mime.c_str(), "audio/", 6);
16275a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber}
16375a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber
16435213f1420c669f43314cb75eadea450d21a75cbAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
16516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    return mFormat != NULL ? mFormat : mConverter->getOutputFormat();
16635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
16735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
16875a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
16975a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber    return mIsAudio;
17075a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber}
17175a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber
17235213f1420c669f43314cb75eadea450d21a75cbAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
17335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    return mConverter;
17435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
17535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
1764646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huberconst sp<RepeaterSource> &
1774646d5756c06e896f9f8489fa07cd14f958b2f84Andreas HuberWifiDisplaySource::PlaybackSession::Track::repeaterSource() const {
1784646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huber    return mRepeaterSource;
1794646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huber}
1804646d5756c06e896f9f8489fa07cd14f958b2f84Andreas Huber
18143433111d4adff6a138447dfadf531046497a008Andreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::mediaSenderTrackIndex() const {
18243433111d4adff6a138447dfadf531046497a008Andreas Huber    CHECK_GE(mMediaSenderTrackIndex, 0);
18343433111d4adff6a138447dfadf531046497a008Andreas Huber    return mMediaSenderTrackIndex;
18435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
18535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
18643433111d4adff6a138447dfadf531046497a008Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setMediaSenderTrackIndex(
18743433111d4adff6a138447dfadf531046497a008Andreas Huber        size_t index) {
18843433111d4adff6a138447dfadf531046497a008Andreas Huber    mMediaSenderTrackIndex = index;
18935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
19035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
191eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
192be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    ALOGV("Track::start isAudio=%d", mIsAudio);
193be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber
194a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    CHECK(!mStarted);
195eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
196eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    status_t err = OK;
197eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
198eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (mMediaPuller != NULL) {
199eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        err = mMediaPuller->start();
200eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
201eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
202eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (err == OK) {
203eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        mStarted = true;
204eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
205eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
206eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    return err;
207eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber}
208eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
209a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() {
210a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
211be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber
21216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (mConverter != NULL) {
21316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mConverter->shutdownAsync();
21416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
215a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
216a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
217eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
218799688d0520149edc7f18ebe69c1ddd453a73cceAndreas Huber    if (mStarted && mMediaPuller != NULL) {
21977c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        if (mRepeaterSource != NULL) {
22077c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber            // Let's unblock MediaPuller's MediaSource::read().
22177c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber            mRepeaterSource->wakeUp();
22277c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        }
22377c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
224a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        mMediaPuller->stopAsync(msg);
225a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    } else {
22616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mStarted = false;
227a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        msg->post();
228eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
229a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber}
230eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
231bf4950aa265ec7b54777d122b27037461638af0fAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::pause() {
232bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    mMediaPuller->pause();
233bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber}
234bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
235bf4950aa265ec7b54777d122b27037461638af0fAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::resume() {
236bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    mMediaPuller->resume();
237bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber}
238bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
239a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
240a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        const sp<AMessage> &msg) {
241a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    switch (msg->what()) {
242a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        case kWhatMediaPullerStopped:
243a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        {
244a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            mConverter.clear();
245596b4cde38b9fe18d21b4ed20dbdba909514a457Andreas Huber
246a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            mStarted = false;
247eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
248a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            sp<AMessage> notify = mNotify->dup();
249a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            notify->setInt32("what", kWhatStopped);
250a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            notify->post();
2519fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber
2529fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
253a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            break;
254a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        }
255a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
256a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        default:
257a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            TRESPASS();
258a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    }
259eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber}
260eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
2610d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
2620d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber        const sp<ABuffer> &accessUnit) {
2630d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    mQueuedAccessUnits.push_back(accessUnit);
2640d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber}
2650d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
2660d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
2670d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    if (mQueuedAccessUnits.empty()) {
2680d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber        return NULL;
2690d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    }
2700d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
2710d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
2720d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    CHECK(accessUnit != NULL);
2730d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
2740d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
2750d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
2760d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber    return accessUnit;
2770d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber}
2780d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber
27977c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
28077c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        const sp<RepeaterSource> &source) {
28177c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    mRepeaterSource = source;
28277c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber}
28377c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
28477c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
28577c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    if (mIsAudio) {
28677c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        return;
28777c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    }
28877c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
28977c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    if (mRepeaterSource != NULL) {
29077c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        mRepeaterSource->wakeUp();
29177c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    }
29277c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
29377c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    mConverter->requestIDRFrame();
29477c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber}
29577c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
296bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
297bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        int64_t *timeUs) const {
298bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    *timeUs = 0ll;
299bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
300bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (mQueuedOutputBuffers.empty()) {
301bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return false;
302bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
303bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
304bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
305bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
306bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
307bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
308bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    return true;
309bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber}
310bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
311bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
312bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        const sp<ABuffer> &accessUnit) {
313bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    mQueuedOutputBuffers.push_back(accessUnit);
314bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
315bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber}
316bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
317bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
318bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    CHECK(!mQueuedOutputBuffers.empty());
319bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
320bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
321bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
322bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
323bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    return outputBuffer;
324bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber}
325bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
32683c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber#if SUSPEND_VIDEO_IF_IDLE
327bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
328bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (!mQueuedOutputBuffers.empty()) {
329bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return false;
330bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
331bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
332bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    if (mLastOutputBufferQueuedTimeUs < 0ll) {
333bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        // We've never seen an output buffer queued, but tracks start
334bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        // out live, not suspended.
335bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return false;
336bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    }
337bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
338bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    // If we've not seen new output data for 60ms or more, we consider
339bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    // this track suspended for the time being.
340bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber    return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
341bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber}
34283c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber#endif
343bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
34435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber////////////////////////////////////////////////////////////////////////////////
34535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
34635213f1420c669f43314cb75eadea450d21a75cbAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
34735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        const sp<ANetworkSession> &netSession,
34828169b107327b5db58877babf6993f0eb109c58aAndreas Huber        const sp<AMessage> &notify,
3497d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber        const in_addr &interfaceAddr,
35016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        const sp<IHDCP> &hdcp,
35116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        const char *path)
35235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    : mNetSession(netSession),
35335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber      mNotify(notify),
3547d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber      mInterfaceAddr(interfaceAddr),
35575a8df99f695784cd458c72c8e1a99510e8761b2Andreas Huber      mHDCP(hdcp),
35643433111d4adff6a138447dfadf531046497a008Andreas Huber      mLocalRTPPort(-1),
357be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber      mWeAreDead(false),
358bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber      mPaused(false),
35935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber      mLastLifesignUs(),
360eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber      mVideoTrackIndex(-1),
36116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mPrevTimeUs(-1ll),
36216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mPullExtractorPending(false),
36316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mPullExtractorGeneration(0),
36416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mFirstSampleTimeRealUs(-1ll),
36516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber      mFirstSampleTimeUs(-1ll) {
36616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (path != NULL) {
36716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mMediaPath.setTo(path);
36816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
36935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
37035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
37135213f1420c669f43314cb75eadea450d21a75cbAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
372dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber        const char *clientIP,
373dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber        int32_t clientRtp,
374dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber        RTPSender::TransportMode rtpMode,
375dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber        int32_t clientRtcp,
376dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber        RTPSender::TransportMode rtcpMode,
377bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool enableAudio,
378bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool usePCMAudio,
379bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool enableVideo,
380bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        VideoFormats::ResolutionType videoResolutionType,
381bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        size_t videoResolutionIndex) {
38243433111d4adff6a138447dfadf531046497a008Andreas Huber    sp<AMessage> notify = new AMessage(kWhatMediaSenderNotify, id());
38343433111d4adff6a138447dfadf531046497a008Andreas Huber    mMediaSender = new MediaSender(mNetSession, notify);
38443433111d4adff6a138447dfadf531046497a008Andreas Huber    looper()->registerHandler(mMediaSender);
38543433111d4adff6a138447dfadf531046497a008Andreas Huber
38643433111d4adff6a138447dfadf531046497a008Andreas Huber    mMediaSender->setHDCP(mHDCP);
38743433111d4adff6a138447dfadf531046497a008Andreas Huber
388bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    status_t err = setupPacketizer(
389bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            enableAudio,
390bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            usePCMAudio,
391bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            enableVideo,
392bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            videoResolutionType,
393bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            videoResolutionIndex);
39435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
39543433111d4adff6a138447dfadf531046497a008Andreas Huber    if (err == OK) {
39643433111d4adff6a138447dfadf531046497a008Andreas Huber        err = mMediaSender->initAsync(
39743433111d4adff6a138447dfadf531046497a008Andreas Huber                -1 /* trackIndex */,
39843433111d4adff6a138447dfadf531046497a008Andreas Huber                clientIP,
39943433111d4adff6a138447dfadf531046497a008Andreas Huber                clientRtp,
400dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber                rtpMode,
40143433111d4adff6a138447dfadf531046497a008Andreas Huber                clientRtcp,
402dca73b8fe8fa4d991e1a78c02f1939aaeb673cc1Andreas Huber                rtcpMode,
40343433111d4adff6a138447dfadf531046497a008Andreas Huber                &mLocalRTPPort);
40435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
40535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
40643433111d4adff6a138447dfadf531046497a008Andreas Huber    if (err != OK) {
40743433111d4adff6a138447dfadf531046497a008Andreas Huber        mLocalRTPPort = -1;
40835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
40943433111d4adff6a138447dfadf531046497a008Andreas Huber        looper()->unregisterHandler(mMediaSender->id());
41043433111d4adff6a138447dfadf531046497a008Andreas Huber        mMediaSender.clear();
41135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
412bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        return err;
41335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
41435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
41535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    updateLiveness();
41635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
41735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    return OK;
41835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
41935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
42035213f1420c669f43314cb75eadea450d21a75cbAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
42135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
42235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
42335213f1420c669f43314cb75eadea450d21a75cbAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
42443433111d4adff6a138447dfadf531046497a008Andreas Huber    return mLocalRTPPort;
42535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
42635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
42735213f1420c669f43314cb75eadea450d21a75cbAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
42835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    return mLastLifesignUs;
42935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
43035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
43135213f1420c669f43314cb75eadea450d21a75cbAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
43235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
43335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
43435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
43535213f1420c669f43314cb75eadea450d21a75cbAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
43635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    updateLiveness();
43735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
438bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    (new AMessage(kWhatResume, id()))->post();
439bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
4407d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber    return OK;
4417d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber}
4427d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber
44343433111d4adff6a138447dfadf531046497a008Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onMediaSenderInitialized() {
444eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
445a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
446eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
447eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
4487d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber    sp<AMessage> notify = mNotify->dup();
4497d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber    notify->setInt32("what", kWhatSessionEstablished);
4507d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber    notify->post();
4517d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber
452eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    return OK;
45335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
45435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
45535213f1420c669f43314cb75eadea450d21a75cbAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
45635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    updateLiveness();
45735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
458bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber    (new AMessage(kWhatPause, id()))->post();
459bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
46035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    return OK;
46135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
46235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
463a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() {
464a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    ALOGI("destroyAsync");
465596b4cde38b9fe18d21b4ed20dbdba909514a457Andreas Huber
466a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
467a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        mTracks.valueAt(i)->stopAsync();
468596b4cde38b9fe18d21b4ed20dbdba909514a457Andreas Huber    }
469596b4cde38b9fe18d21b4ed20dbdba909514a457Andreas Huber}
470596b4cde38b9fe18d21b4ed20dbdba909514a457Andreas Huber
47135213f1420c669f43314cb75eadea450d21a75cbAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
47235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        const sp<AMessage> &msg) {
47335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    switch (msg->what()) {
47435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        case kWhatConverterNotify:
47535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        {
4768292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber            if (mWeAreDead) {
4778292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber                ALOGV("dropping msg '%s' because we're dead",
4788292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber                      msg->debugString().c_str());
4798292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber
4808292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber                break;
4818292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber            }
4828292f6d078a12062bbb090eed49d1ea025ff58f3Andreas Huber
48335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            int32_t what;
48435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            CHECK(msg->findInt32("what", &what));
48535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
48635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            size_t trackIndex;
48735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
48835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
48935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            if (what == Converter::kWhatAccessUnit) {
4900d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber                sp<ABuffer> accessUnit;
4910d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
49235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
49343433111d4adff6a138447dfadf531046497a008Andreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
49435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
49543433111d4adff6a138447dfadf531046497a008Andreas Huber                status_t err = mMediaSender->queueAccessUnit(
49643433111d4adff6a138447dfadf531046497a008Andreas Huber                        track->mediaSenderTrackIndex(),
49743433111d4adff6a138447dfadf531046497a008Andreas Huber                        accessUnit);
49808631506af1a6369ca291db50284d0f71cf801ecAndreas Huber
49943433111d4adff6a138447dfadf531046497a008Andreas Huber                if (err != OK) {
50043433111d4adff6a138447dfadf531046497a008Andreas Huber                    notifySessionDead();
50143433111d4adff6a138447dfadf531046497a008Andreas Huber                }
5020d76795773c2cb33fbf95f94a678a004653ca6eeAndreas Huber                break;
50335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            } else if (what == Converter::kWhatEOS) {
50435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
50535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
50635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                ALOGI("output EOS on track %d", trackIndex);
50735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
50835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
50935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                CHECK_GE(index, 0);
51035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
51135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                const sp<Converter> &converter =
51235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                    mTracks.valueAt(index)->converter();
51335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                looper()->unregisterHandler(converter->id());
51435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
51535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                mTracks.removeItemsAt(index);
51635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
51735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                if (mTracks.isEmpty()) {
51835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                    ALOGI("Reached EOS");
51935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                }
52035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            } else {
52135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
52235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
52335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                status_t err;
52435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                CHECK(msg->findInt32("err", &err));
52535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
52635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber                ALOGE("converter signaled error %d", err);
527a71c3ea5db4c035390a4a85012ee40f605ba4938Andreas Huber
528be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber                notifySessionDead();
52935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            }
53035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            break;
53135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        }
53235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
53343433111d4adff6a138447dfadf531046497a008Andreas Huber        case kWhatMediaSenderNotify:
534bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        {
535bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            int32_t what;
536bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            CHECK(msg->findInt32("what", &what));
537bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber
53843433111d4adff6a138447dfadf531046497a008Andreas Huber            if (what == MediaSender::kWhatInitDone) {
53943433111d4adff6a138447dfadf531046497a008Andreas Huber                status_t err;
54043433111d4adff6a138447dfadf531046497a008Andreas Huber                CHECK(msg->findInt32("err", &err));
5417bc2ffca12828d72aaeeace0891183dc547877c0Andreas Huber
54243433111d4adff6a138447dfadf531046497a008Andreas Huber                if (err == OK) {
54343433111d4adff6a138447dfadf531046497a008Andreas Huber                    onMediaSenderInitialized();
54443433111d4adff6a138447dfadf531046497a008Andreas Huber                } else {
54543433111d4adff6a138447dfadf531046497a008Andreas Huber                    notifySessionDead();
54643433111d4adff6a138447dfadf531046497a008Andreas Huber                }
54743433111d4adff6a138447dfadf531046497a008Andreas Huber            } else if (what == MediaSender::kWhatError) {
54843433111d4adff6a138447dfadf531046497a008Andreas Huber                notifySessionDead();
549e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber            } else if (what == MediaSender::kWhatNetworkStall) {
550e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                size_t numBytesQueued;
551e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                CHECK(msg->findSize("numBytesQueued", &numBytesQueued));
552e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber
553e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                if (mVideoTrackIndex >= 0) {
554e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                    const sp<Track> &videoTrack =
555e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                        mTracks.valueFor(mVideoTrackIndex);
556e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber
55716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                    sp<Converter> converter = videoTrack->converter();
55816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                    if (converter != NULL) {
55916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                        converter->dropAFrame();
56016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                    }
561e2aef54fee88fdeb585a41e1e9834e3d975b263cAndreas Huber                }
562bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            } else {
563bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber                TRESPASS();
564bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            }
5657d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber            break;
5667d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber        }
5677d34f83f64919295baff4b0e260267af3efb4f9fAndreas Huber
568a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        case kWhatTrackNotify:
569a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        {
570a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            int32_t what;
571a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            CHECK(msg->findInt32("what", &what));
572a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
573a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            size_t trackIndex;
574a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
575a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
576a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            if (what == Track::kWhatStopped) {
5779fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                ALOGI("Track %d stopped", trackIndex);
578a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
5799fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                sp<Track> track = mTracks.valueFor(trackIndex);
5809fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                looper()->unregisterHandler(track->id());
5819fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                mTracks.removeItem(trackIndex);
5829fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                track.clear();
5839fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber
5849fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                if (!mTracks.isEmpty()) {
5859fcc8ce3e8829b38be3fd86551e1ec9ee3eb244eAndreas Huber                    ALOGI("not all tracks are stopped yet");
586a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber                    break;
587a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber                }
588a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
58943433111d4adff6a138447dfadf531046497a008Andreas Huber                looper()->unregisterHandler(mMediaSender->id());
59043433111d4adff6a138447dfadf531046497a008Andreas Huber                mMediaSender.clear();
591a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
592bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber                sp<AMessage> notify = mNotify->dup();
593bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber                notify->setInt32("what", kWhatSessionDestroyed);
594bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber                notify->post();
595bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            }
596bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber            break;
597bd4e99c1636c75f6db0be70434b9f276bfecd96dAndreas Huber        }
598a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
599bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        case kWhatPause:
600bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        {
60116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            if (mExtractor != NULL) {
60216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                ++mPullExtractorGeneration;
60316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                mFirstSampleTimeRealUs = -1ll;
60416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                mFirstSampleTimeUs = -1ll;
60516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            }
60616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
607bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            if (mPaused) {
608bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber                break;
609bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            }
610bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
611bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
612bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber                mTracks.editValueAt(i)->pause();
613bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            }
614bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
615bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            mPaused = true;
616bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            break;
617bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        }
618bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
619bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        case kWhatResume:
620bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        {
62116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            if (mExtractor != NULL) {
62216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                schedulePullExtractor();
62316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            }
62416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
625bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            if (!mPaused) {
626bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber                break;
627bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            }
628bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
629bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            for (size_t i = 0; i < mTracks.size(); ++i) {
630bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber                mTracks.editValueAt(i)->resume();
631bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            }
632bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
633bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            mPaused = false;
634bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber            break;
635bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber        }
636bf4950aa265ec7b54777d122b27037461638af0fAndreas Huber
63716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        case kWhatPullExtractorSample:
63816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        {
63916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            int32_t generation;
64016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            CHECK(msg->findInt32("generation", &generation));
64116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
64216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            if (generation != mPullExtractorGeneration) {
64316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber                break;
64416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            }
64516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
64616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            mPullExtractorPending = false;
64716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
64816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            onPullExtractor();
64916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            break;
65016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        }
65116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
65235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber        default:
65335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber            TRESPASS();
65435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    }
65535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
65635213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
65716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupMediaPacketizer(
65816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        bool enableAudio, bool enableVideo) {
65916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    DataSource::RegisterDefaultSniffers();
66016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
66116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    mExtractor = new NuMediaExtractor;
66216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
66316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    status_t err = mExtractor->setDataSource(mMediaPath.c_str());
66416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
66516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (err != OK) {
66616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        return err;
66716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
66816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
66916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    size_t n = mExtractor->countTracks();
67016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    bool haveAudio = false;
67116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    bool haveVideo = false;
67216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    for (size_t i = 0; i < n; ++i) {
67316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        sp<AMessage> format;
67416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        err = mExtractor->getTrackFormat(i, &format);
67516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
67616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        if (err != OK) {
67716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            continue;
67816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        }
67916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
68016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        AString mime;
68116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        CHECK(format->findString("mime", &mime));
68216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
68316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        bool isAudio = !strncasecmp(mime.c_str(), "audio/", 6);
68416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        bool isVideo = !strncasecmp(mime.c_str(), "video/", 6);
68516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
68616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        if (isAudio && enableAudio && !haveAudio) {
68716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            haveAudio = true;
68816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        } else if (isVideo && enableVideo && !haveVideo) {
68916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            haveVideo = true;
69016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        } else {
69116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            continue;
69216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        }
69316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
69416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        err = mExtractor->selectTrack(i);
69516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
69616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        size_t trackIndex = mTracks.size();
69716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
69816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        sp<AMessage> notify = new AMessage(kWhatTrackNotify, id());
69916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        notify->setSize("trackIndex", trackIndex);
70016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
70116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        sp<Track> track = new Track(notify, format);
70216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        looper()->registerHandler(track);
70316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
70416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mTracks.add(trackIndex, track);
70516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
70616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mExtractorTrackToInternalTrack.add(i, trackIndex);
70716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
70816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        if (isVideo) {
70916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            mVideoTrackIndex = trackIndex;
71016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        }
71116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
71216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        uint32_t flags = MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
71316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
71416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        ssize_t mediaSenderTrackIndex =
71516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            mMediaSender->addTrack(format, flags);
71616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        CHECK_GE(mediaSenderTrackIndex, 0);
71716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
71816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
71916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
72016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        if ((haveAudio || !enableAudio) && (haveVideo || !enableVideo)) {
72116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            break;
72216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        }
72316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
72416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
72516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    return OK;
72616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber}
72716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
72816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Hubervoid WifiDisplaySource::PlaybackSession::schedulePullExtractor() {
72916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (mPullExtractorPending) {
73016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        return;
73116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
73216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
73316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    int64_t sampleTimeUs;
73416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    status_t err = mExtractor->getSampleTime(&sampleTimeUs);
73516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
73616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    int64_t nowUs = ALooper::GetNowUs();
73716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
73816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (mFirstSampleTimeRealUs < 0ll) {
73916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mFirstSampleTimeRealUs = nowUs;
74016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        mFirstSampleTimeUs = sampleTimeUs;
74116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
74216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
74316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    int64_t whenUs = sampleTimeUs - mFirstSampleTimeUs + mFirstSampleTimeRealUs;
74416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
74516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    sp<AMessage> msg = new AMessage(kWhatPullExtractorSample, id());
74616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->setInt32("generation", mPullExtractorGeneration);
74716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->post(whenUs - nowUs);
74816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
74916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    mPullExtractorPending = true;
75016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber}
75116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
75216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Hubervoid WifiDisplaySource::PlaybackSession::onPullExtractor() {
75316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    sp<ABuffer> accessUnit = new ABuffer(1024 * 1024);
75416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    status_t err = mExtractor->readSampleData(accessUnit);
75516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (err != OK) {
75616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        // EOS.
75716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        return;
75816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
75916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
76016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    int64_t timeUs;
76116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTime(&timeUs));
76216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
76316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    accessUnit->meta()->setInt64(
76416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            "timeUs", mFirstSampleTimeRealUs + timeUs - mFirstSampleTimeUs);
76516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
76616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    size_t trackIndex;
76716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    CHECK_EQ((status_t)OK, mExtractor->getSampleTrackIndex(&trackIndex));
76816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
76916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
77016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
77116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->setSize(
77216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber            "trackIndex", mExtractorTrackToInternalTrack.valueFor(trackIndex));
77316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
77416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->setInt32("what", Converter::kWhatAccessUnit);
77516fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->setBuffer("accessUnit", accessUnit);
77616fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    msg->post();
77716fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
77816fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    mExtractor->advance();
77916fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
78016fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    schedulePullExtractor();
78116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber}
78216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
783bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer(
784bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool enableAudio,
785bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool usePCMAudio,
786bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        bool enableVideo,
787bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        VideoFormats::ResolutionType videoResolutionType,
788bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        size_t videoResolutionIndex) {
789bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    CHECK(enableAudio || enableVideo);
790bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber
79116fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    if (!mMediaPath.empty()) {
79216fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber        return setupMediaPacketizer(enableAudio, enableVideo);
79316fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber    }
79416fb8f3954a6a4058953c505a4e7958a1b14c62bAndreas Huber
795bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    if (enableVideo) {
796bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        status_t err = addVideoSource(
797bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                videoResolutionType, videoResolutionIndex);
79835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
799bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        if (err != OK) {
800bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber            return err;
801bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        }
802bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    }
803bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber
804bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    if (!enableAudio) {
805bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        return OK;
806eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
807eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
80820a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber    return addAudioSource(usePCMAudio);
809eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber}
81035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
811eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource(
81277c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
81320a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber        bool usePCMAudio, size_t *numInputBuffers) {
81420a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber    CHECK(!usePCMAudio || !isVideo);
81520a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber    CHECK(!isRepeaterSource || isVideo);
81620a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber
817eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<ALooper> pullLooper = new ALooper;
818eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    pullLooper->setName("pull_looper");
819eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
820eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    pullLooper->start(
821eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber            false /* runOnCallingThread */,
822eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber            false /* canCallJava */,
823a71c3ea5db4c035390a4a85012ee40f605ba4938Andreas Huber            PRIORITY_AUDIO);
82435213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
825eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<ALooper> codecLooper = new ALooper;
826eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    codecLooper->setName("codec_looper");
827eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
828eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    codecLooper->start(
829eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber            false /* runOnCallingThread */,
830eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber            false /* canCallJava */,
831a71c3ea5db4c035390a4a85012ee40f605ba4938Andreas Huber            PRIORITY_AUDIO);
832eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
833eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    size_t trackIndex;
834eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
835eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    sp<AMessage> notify;
836eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
837eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    trackIndex = mTracks.size();
838eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
83935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    sp<AMessage> format;
84035213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
84135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    CHECK_EQ(err, (status_t)OK);
84235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
843eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (isVideo) {
844eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        format->setInt32("store-metadata-in-buffers", true);
84535213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
846eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        format->setInt32(
847eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber                "color-format", OMX_COLOR_FormatAndroidOpaque);
848eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
84935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
850eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    notify = new AMessage(kWhatConverterNotify, id());
851eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    notify->setSize("trackIndex", trackIndex);
85235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
85335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    sp<Converter> converter =
85420a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber        new Converter(notify, codecLooper, format, usePCMAudio);
85513315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber
85683c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber    err = converter->initCheck();
85783c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber    if (err != OK) {
85883c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber        ALOGE("%s converter returned err %d", isVideo ? "video" : "audio", err);
85983c9bd167600b3ff77008a6c06c05bb1f189d4caAndreas Huber        return err;
86013315ce05fbee1e1f5b920cfe4217c3a30167023Andreas Huber    }
8617f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber
86235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    looper()->registerHandler(converter);
86335213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
864a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
865a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    notify->setSize("trackIndex", trackIndex);
866a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
867a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    sp<MediaPuller> puller = new MediaPuller(source, notify);
868a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    pullLooper->registerHandler(puller);
869a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
870eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (numInputBuffers != NULL) {
871eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        *numInputBuffers = converter->getInputBufferCount();
872eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
8737f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber
874a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    notify = new AMessage(kWhatTrackNotify, id());
875a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    notify->setSize("trackIndex", trackIndex);
876a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
877a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    sp<Track> track = new Track(
878a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            notify, pullLooper, codecLooper, puller, converter);
879a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
88077c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    if (isRepeaterSource) {
88177c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
88277c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    }
88377c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
884a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    looper()->registerHandler(track);
885a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
886a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    mTracks.add(trackIndex, track);
887eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
888eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (isVideo) {
889eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        mVideoTrackIndex = trackIndex;
890eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
891eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
89243433111d4adff6a138447dfadf531046497a008Andreas Huber    uint32_t flags = 0;
89343433111d4adff6a138447dfadf531046497a008Andreas Huber    if (converter->needToManuallyPrependSPSPPS()) {
89443433111d4adff6a138447dfadf531046497a008Andreas Huber        flags |= MediaSender::FLAG_MANUALLY_PREPEND_SPS_PPS;
89543433111d4adff6a138447dfadf531046497a008Andreas Huber    }
89643433111d4adff6a138447dfadf531046497a008Andreas Huber
89743433111d4adff6a138447dfadf531046497a008Andreas Huber    ssize_t mediaSenderTrackIndex =
89843433111d4adff6a138447dfadf531046497a008Andreas Huber        mMediaSender->addTrack(converter->getOutputFormat(), flags);
89943433111d4adff6a138447dfadf531046497a008Andreas Huber    CHECK_GE(mediaSenderTrackIndex, 0);
90043433111d4adff6a138447dfadf531046497a008Andreas Huber
90143433111d4adff6a138447dfadf531046497a008Andreas Huber    track->setMediaSenderTrackIndex(mediaSenderTrackIndex);
90243433111d4adff6a138447dfadf531046497a008Andreas Huber
903eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    return OK;
904eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber}
905eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
906bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource(
907bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        VideoFormats::ResolutionType videoResolutionType,
908bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        size_t videoResolutionIndex) {
909bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    size_t width, height, framesPerSecond;
910bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    bool interlaced;
911bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    CHECK(VideoFormats::GetConfiguration(
912bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                videoResolutionType,
913bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                videoResolutionIndex,
914bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                &width,
915bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                &height,
916bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                &framesPerSecond,
917bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber                &interlaced));
918bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber
919bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width, height);
920eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
921fa0e033ab5a0ab5d96e90c9f6d4d53bedc74514bAndreas Huber    source->setUseAbsoluteTimestamps();
922fa0e033ab5a0ab5d96e90c9f6d4d53bedc74514bAndreas Huber
92377c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    sp<RepeaterSource> videoSource =
924bf049b94f53f0213d53ba00e1cbe6996164d8ecaAndreas Huber        new RepeaterSource(source, framesPerSecond);
92577c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber
926eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    size_t numInputBuffers;
92777c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber    status_t err = addSource(
92877c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber            true /* isVideo */, videoSource, true /* isRepeaterSource */,
92920a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
930eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
931eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    if (err != OK) {
932eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        return err;
933eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    }
9347f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber
9358bcc1a1ce7dab4479b36fb274ed66eaf687d1eacAndreas Huber    err = source->setMaxAcquiredBufferCount(numInputBuffers);
9367f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber    CHECK_EQ(err, (status_t)OK);
9377f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber
93828169b107327b5db58877babf6993f0eb109c58aAndreas Huber    mBufferQueue = source->getBufferQueue();
93928169b107327b5db58877babf6993f0eb109c58aAndreas Huber
940eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    return OK;
941eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber}
942eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
94320a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
944bd381af4d618a4da78de99d05d44a10c0c37207bAndreas Huber    sp<AudioSource> audioSource = new AudioSource(
945c17183c6b516f89d5a353b07fbd1312838adc74eAndreas Huber            AUDIO_SOURCE_REMOTE_SUBMIX,
946bd381af4d618a4da78de99d05d44a10c0c37207bAndreas Huber            48000 /* sampleRate */,
947c17183c6b516f89d5a353b07fbd1312838adc74eAndreas Huber            2 /* channelCount */);
948bd381af4d618a4da78de99d05d44a10c0c37207bAndreas Huber
949be009a3d9897e5f3a66f3eeeb6762552a1f858a8Andreas Huber    if (audioSource->initCheck() == OK) {
950eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber        return addSource(
95177c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber                false /* isVideo */, audioSource, false /* isRepeaterSource */,
95220a5a98667df7ed83e5d9f37e88b1bbdb876d718Andreas Huber                usePCMAudio, NULL /* numInputBuffers */);
953be009a3d9897e5f3a66f3eeeb6762552a1f858a8Andreas Huber    }
954eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber
955eb29bae4b8ae270e656b6fcd5216fa86e9f1d8d0Andreas Huber    ALOGW("Unable to instantiate audio source");
956bd381af4d618a4da78de99d05d44a10c0c37207bAndreas Huber
95735213f1420c669f43314cb75eadea450d21a75cbAndreas Huber    return OK;
95835213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}
95935213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
960484566c410afdfbc4b6bc5aa1732aef37428a5b8Andy McFaddensp<IGraphicBufferProducer> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
96128169b107327b5db58877babf6993f0eb109c58aAndreas Huber    return mBufferQueue;
96228169b107327b5db58877babf6993f0eb109c58aAndreas Huber}
96328169b107327b5db58877babf6993f0eb109c58aAndreas Huber
96403e2ffa64470eec4e886614a4fa4facbae58a862Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() {
96503e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
96603e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber        const sp<Track> &track = mTracks.valueAt(i);
96703e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
96877c887a262840d5dc013b7abb838696eb5cb5ee7Andreas Huber        track->requestIDRFrame();
96903e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber    }
97003e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber}
97103e2ffa64470eec4e886614a4fa4facbae58a862Andreas Huber
972be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() {
973be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    // Inform WifiDisplaySource of our premature death (wish).
974be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    sp<AMessage> notify = mNotify->dup();
975be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    notify->setInt32("what", kWhatSessionDead);
976be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    notify->post();
977be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber
978be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    mWeAreDead = true;
979be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber}
980be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber
98135213f1420c669f43314cb75eadea450d21a75cbAndreas Huber}  // namespace android
98235213f1420c669f43314cb75eadea450d21a75cbAndreas Huber
983