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"
2690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#include "Sender.h"
27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "TSPacketizer.h"
28e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include "include/avc_utils.h"
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h>
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h>
32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h>
33b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.h>
34e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h>
39082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h>
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h>
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaExtractor.h>
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h>
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h>
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h>
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h>
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h>
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler {
5596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatStopped,
5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
5896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
5996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    Track(const sp<AMessage> &notify,
6096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber          const sp<ALooper> &pullLooper,
61e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<ALooper> &codecLooper,
62e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<MediaPuller> &mediaPuller,
63e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<Converter> &converter);
64e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
654a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void setRepeaterSource(const sp<RepeaterSource> &source);
664a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> getFormat();
68b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool isAudio() const;
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<Converter> &converter() const;
71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t packetizerTrackIndex() const;
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void setPacketizerTrackIndex(size_t index);
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
75e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t start();
7696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    void stopAsync();
7796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
7828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    void queueAccessUnit(const sp<ABuffer> &accessUnit);
7928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> dequeueAccessUnit();
8028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
8190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool hasOutputBuffer(int64_t *timeUs) const;
8290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    void queueOutputBuffer(const sp<ABuffer> &accessUnit);
8390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> dequeueOutputBuffer();
8490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    bool isSuspended() const;
8590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
8690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    size_t countQueuedOutputBuffers() const {
8790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return mQueuedOutputBuffers.size();
8890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
8990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void requestIDRFrame();
914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected:
9396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    virtual ~Track();
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate:
9796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
9896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatMediaPullerStopped,
9996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
10096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
10196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> mNotify;
102e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mPullLooper;
103e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mCodecLooper;
104e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<MediaPuller> mMediaPuller;
105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> mConverter;
106e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    bool mStarted;
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t mPacketizerTrackIndex;
108b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool mIsAudio;
10928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    List<sp<ABuffer> > mQueuedAccessUnits;
1104a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> mRepeaterSource;
11190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    List<sp<ABuffer> > mQueuedOutputBuffers;
11290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t mLastOutputBufferQueuedTimeUs;
113b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
114b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    static bool IsAudioFormat(const sp<AMessage> &format);
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber};
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
119e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
12096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &notify,
121e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &pullLooper,
122e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &codecLooper,
123e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<MediaPuller> &mediaPuller,
124e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<Converter> &converter)
12596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    : mNotify(notify),
12696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber      mPullLooper(pullLooper),
127e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mCodecLooper(codecLooper),
128e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mMediaPuller(mediaPuller),
129e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mConverter(converter),
130e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mStarted(false),
131b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mPacketizerTrackIndex(-1),
13290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())),
13390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mLastOutputBufferQueuedTimeUs(-1ll) {
134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
13796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
140b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static
141b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
142b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<AMessage> &format) {
143b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    AString mime;
144b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    CHECK(format->findString("mime", &mime));
145b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
146b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return !strncasecmp(mime.c_str(), "audio/", 6);
147b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
148b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter->getOutputFormat();
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
153b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
154b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return mIsAudio;
155b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
156b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter;
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mPacketizerTrackIndex;
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_LT(mPacketizerTrackIndex, 0);
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mPacketizerTrackIndex = index;
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
171ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    ALOGV("Track::start isAudio=%d", mIsAudio);
172ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
17396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
174e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
175e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = OK;
176e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
177e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (mMediaPuller != NULL) {
178e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        err = mMediaPuller->start();
179e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
180e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
181e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err == OK) {
182e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mStarted = true;
183e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
184e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
185e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return err;
186e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
187e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
18896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() {
18996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
190ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
19196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mConverter->shutdownAsync();
19296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
19396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
194e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
195ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber    if (mStarted && mMediaPuller != NULL) {
1964a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        if (mRepeaterSource != NULL) {
1974a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            // Let's unblock MediaPuller's MediaSource::read().
1984a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            mRepeaterSource->wakeUp();
1994a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        }
2004a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
20196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mMediaPuller->stopAsync(msg);
20296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    } else {
20396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        msg->post();
204e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
20596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
206e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
20796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
20896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &msg) {
20996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    switch (msg->what()) {
21096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerStopped:
21196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
21296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mConverter.clear();
213a438123bd96c7faf145683876702387efe5628d9Andreas Huber
21496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mStarted = false;
215e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            sp<AMessage> notify = mNotify->dup();
21796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->setInt32("what", kWhatStopped);
21896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->post();
21977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
22077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
22196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
22296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
22396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
22496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        default:
22596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            TRESPASS();
22696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    }
227e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
228e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
22928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
23028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        const sp<ABuffer> &accessUnit) {
23128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.push_back(accessUnit);
23228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
23328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
23428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
23528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mQueuedAccessUnits.empty()) {
23628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return NULL;
23728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
23828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
23928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
24028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    CHECK(accessUnit != NULL);
24128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
24228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
24328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
24428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return accessUnit;
24528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
24628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
2474a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
2484a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        const sp<RepeaterSource> &source) {
2494a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mRepeaterSource = source;
2504a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2514a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2524a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
2534a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mIsAudio) {
2544a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        return;
2554a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2564a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2574a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mRepeaterSource != NULL) {
2584a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mRepeaterSource->wakeUp();
2594a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2604a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2614a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mConverter->requestIDRFrame();
2624a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2634a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
26490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::hasOutputBuffer(
26590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t *timeUs) const {
26690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    *timeUs = 0ll;
26790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
26890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mQueuedOutputBuffers.empty()) {
26990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
27090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
27190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    const sp<ABuffer> &outputBuffer = *mQueuedOutputBuffers.begin();
27390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(outputBuffer->meta()->findInt64("timeUs", timeUs));
27590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return true;
27790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
27890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
27990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueOutputBuffer(
28090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<ABuffer> &accessUnit) {
28190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.push_back(accessUnit);
28290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
28390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mLastOutputBufferQueuedTimeUs = ALooper::GetNowUs();
28490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
28590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
28690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueOutputBuffer() {
28790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    CHECK(!mQueuedOutputBuffers.empty());
28890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
28990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> outputBuffer = *mQueuedOutputBuffers.begin();
29090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mQueuedOutputBuffers.erase(mQueuedOutputBuffers.begin());
29190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
29290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return outputBuffer;
29390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
29490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
29590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isSuspended() const {
29690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (!mQueuedOutputBuffers.empty()) {
29790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
29890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
29990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (mLastOutputBufferQueuedTimeUs < 0ll) {
30190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // We've never seen an output buffer queued, but tracks start
30290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        // out live, not suspended.
30390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
30490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
30590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
30690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // If we've not seen new output data for 60ms or more, we consider
30790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    // this track suspended for the time being.
30890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return (ALooper::GetNowUs() - mLastOutputBufferQueuedTimeUs) > 60000ll;
30990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
31090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber////////////////////////////////////////////////////////////////////////////////
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ANetworkSession> &netSession,
3150b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber        const sp<AMessage> &notify,
316bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        const in_addr &interfaceAddr,
317b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<IHDCP> &hdcp)
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mNetSession(netSession),
319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
320bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mInterfaceAddr(interfaceAddr),
321b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mHDCP(hdcp),
322ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber      mWeAreDead(false),
323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastLifesignUs(),
324e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mVideoTrackIndex(-1),
325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mPrevTimeUs(-1ll),
32690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber      mAllTracksHavePacketizerIndex(false) {
327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
33190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        Sender::TransportMode transportMode,
332e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio) {
333e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    status_t err = setupPacketizer(usePCMAudio);
334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
33990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<AMessage> notify = new AMessage(kWhatSenderNotify, id());
34090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSender = new Sender(mNetSession, notify);
341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
34290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSenderLooper = new ALooper;
34390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSenderLooper->setName("sender_looper");
344efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
34590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSenderLooper->start(
34690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            false /* runOnCallingThread */,
34790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            false /* canCallJava */,
34890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            PRIORITY_AUDIO);
349efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
35090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSenderLooper->registerHandler(mSender);
351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
35290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    err = mSender->init(clientIP, clientRtp, clientRtcp, transportMode);
353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
35490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (err != OK) {
35590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return err;
356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
36790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return mSender->getRTPPort();
368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mLastLifesignUs;
372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
381bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
382bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
383bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
384bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::finishPlay() {
38592f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber    // XXX Give the dongle a second to bind its sockets.
38692f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber    (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
387bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
388bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
389bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
390bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
39190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return mSender->finishInit();
392bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
393bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
394bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
39590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSender->scheduleSendSR();
396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
397e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
39896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
399e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
400e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
401bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    sp<AMessage> notify = mNotify->dup();
402bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->setInt32("what", kWhatSessionEstablished);
403bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->post();
404bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
405e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
41496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() {
41596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGI("destroyAsync");
416a438123bd96c7faf145683876702387efe5628d9Andreas Huber
41796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
41896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mTracks.valueAt(i)->stopAsync();
419a438123bd96c7faf145683876702387efe5628d9Andreas Huber    }
420a438123bd96c7faf145683876702387efe5628d9Andreas Huber}
421a438123bd96c7faf145683876702387efe5628d9Andreas Huber
422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &msg) {
424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatConverterNotify:
426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
4276360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            if (mWeAreDead) {
4286360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                ALOGV("dropping msg '%s' because we're dead",
4296360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                      msg->debugString().c_str());
4306360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
4316360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                break;
4326360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            }
4336360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t trackIndex;
438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Converter::kWhatAccessUnit) {
441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
442d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
44528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (packetizerTrackIndex < 0) {
446d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    packetizerTrackIndex =
447d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mPacketizer->addTrack(track->getFormat());
448d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
44928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    CHECK_GE(packetizerTrackIndex, 0);
450d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
45128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    track->setPacketizerTrackIndex(packetizerTrackIndex);
452b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
45328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    if (allTracksHavePacketizerIndex()) {
45428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                        status_t err = packetizeQueuedAccessUnits();
455b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
456b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                        if (err != OK) {
457ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                            notifySessionDead();
458b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                            break;
459b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                        }
460b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                    }
46128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                }
462b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
46328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                sp<ABuffer> accessUnit;
46428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
46628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (!allTracksHavePacketizerIndex()) {
46728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    track->queueAccessUnit(accessUnit);
46828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    break;
46928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                }
470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
47190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                track->queueOutputBuffer(accessUnit);
472774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
47390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                drainAccessUnits();
47428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                break;
475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else if (what == Converter::kWhatEOS) {
476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGI("output EOS on track %d", trackIndex);
479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_GE(index, 0);
482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Converter> &converter =
484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(index)->converter();
485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                looper()->unregisterHandler(converter->id());
486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.removeItemsAt(index);
488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (mTracks.isEmpty()) {
490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("Reached EOS");
491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                status_t err;
496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findInt32("err", &err));
497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGE("converter signaled error %d", err);
499ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber
500ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                notifySessionDead();
501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
50590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatSenderNotify:
50690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
50790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            int32_t what;
50890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findInt32("what", &what));
50990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
51090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (what == Sender::kWhatInitDone) {
51190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                onFinishPlay2();
51290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else if (what == Sender::kWhatSessionDead) {
51390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notifySessionDead();
51490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            } else {
51590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                TRESPASS();
51690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
51790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
51890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
51990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
52090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
521bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        case kWhatFinishPlay:
522bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        {
523bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            onFinishPlay();
524bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            break;
525bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        }
526bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
52796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatTrackNotify:
52896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
52996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
53096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
53196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
53296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            size_t trackIndex;
53396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
53496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
53596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == Track::kWhatStopped) {
53677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                ALOGI("Track %d stopped", trackIndex);
53796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
53877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                sp<Track> track = mTracks.valueFor(trackIndex);
53977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                looper()->unregisterHandler(track->id());
54077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                mTracks.removeItem(trackIndex);
54177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                track.clear();
54277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
54377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                if (!mTracks.isEmpty()) {
54477245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                    ALOGI("not all tracks are stopped yet");
54596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    break;
54696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
54796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
54890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mSenderLooper->unregisterHandler(mSender->id());
54990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mSender.clear();
55090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                mSenderLooper.clear();
55190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
55296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mPacketizer.clear();
55396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
55490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                sp<AMessage> notify = mNotify->dup();
55590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->setInt32("what", kWhatSessionDestroyed);
55690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                notify->post();
55790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
55890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            break;
55990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
56096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
56190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        case kWhatPacketize:
56290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        {
56390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            size_t trackIndex;
56490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
56596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
56690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            sp<ABuffer> accessUnit;
56790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            CHECK(msg->findBuffer("accessUnit", &accessUnit));
56896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
56990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#if 0
57090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if ((ssize_t)trackIndex == mVideoTrackIndex) {
57190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                int64_t nowUs = ALooper::GetNowUs();
57290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                static int64_t prevNowUs = 0ll;
57396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
57490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                ALOGI("sending AU, dNowUs=%lld us", nowUs - prevNowUs);
57590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
57690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                prevNowUs = nowUs;
57796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
57890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber#endif
57990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
58096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
58196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
58296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
588e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) {
589e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    mPacketizer = new TSPacketizer;
590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
591e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = addVideoSource();
592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
593e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
594e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
595e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
596e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
597e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return addAudioSource(usePCMAudio);
598e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
600e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource(
6014a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
602e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio, size_t *numInputBuffers) {
603e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !isVideo);
604e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!isRepeaterSource || isVideo);
605e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
606e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> pullLooper = new ALooper;
607e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->setName("pull_looper");
608e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
609e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->start(
610e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
611e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
612ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
614e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> codecLooper = new ALooper;
615e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->setName("codec_looper");
616e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
617e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->start(
618e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
619e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
620ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
621e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
622e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t trackIndex;
623e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
624e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<AMessage> notify;
625e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
626e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    trackIndex = mTracks.size();
627e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> format;
629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(err, (status_t)OK);
631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
632e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
633e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32("store-metadata-in-buffers", true);
634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
635e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32(
636e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber                "color-format", OMX_COLOR_FormatAndroidOpaque);
637e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
639e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify = new AMessage(kWhatConverterNotify, id());
640e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify->setSize("trackIndex", trackIndex);
641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> converter =
643e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        new Converter(notify, codecLooper, format, usePCMAudio);
6443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
6453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (converter->initCheck() != OK) {
6463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        return converter->initCheck();
6473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
64866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    looper()->registerHandler(converter);
650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
65196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
65296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
65396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
65496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<MediaPuller> puller = new MediaPuller(source, notify);
65596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    pullLooper->registerHandler(puller);
65696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
657e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (numInputBuffers != NULL) {
658e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        *numInputBuffers = converter->getInputBufferCount();
659e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
66066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
66196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(kWhatTrackNotify, id());
66296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
66396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
66496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<Track> track = new Track(
66596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify, pullLooper, codecLooper, puller, converter);
66696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
6674a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (isRepeaterSource) {
6684a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
6694a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
6704a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
67196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    looper()->registerHandler(track);
67296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
67396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mTracks.add(trackIndex, track);
674e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
675e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
676e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mVideoTrackIndex = trackIndex;
677e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
678e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
679e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
680e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
681e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
682e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource() {
683e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
684e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
685af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    source->setUseAbsoluteTimestamps();
686af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber
6878d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#if 1
6884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> videoSource =
6894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        new RepeaterSource(source, 30.0 /* rateHz */);
6908d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#endif
6914a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
6928d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#if 1
693e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t numInputBuffers;
6944a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    status_t err = addSource(
6954a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            true /* isVideo */, videoSource, true /* isRepeaterSource */,
696e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
6978d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#else
6988d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber    size_t numInputBuffers;
6998d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber    status_t err = addSource(
7008d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber            true /* isVideo */, source, false /* isRepeaterSource */,
701e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
7028d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#endif
703e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
704e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
705e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
706e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
70766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
7085a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber    err = source->setMaxAcquiredBufferCount(numInputBuffers);
70966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    CHECK_EQ(err, (status_t)OK);
71066e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
7110b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    mBufferQueue = source->getBufferQueue();
7120b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
713e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
714e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
715e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
716e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
717082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber    sp<AudioSource> audioSource = new AudioSource(
7181646a0fed94c30a44128b3c379736def4b332033Andreas Huber            AUDIO_SOURCE_REMOTE_SUBMIX,
719082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber            48000 /* sampleRate */,
7201646a0fed94c30a44128b3c379736def4b332033Andreas Huber            2 /* channelCount */);
721082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
7227977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    if (audioSource->initCheck() == OK) {
723e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return addSource(
7244a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber                false /* isVideo */, audioSource, false /* isRepeaterSource */,
725e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                usePCMAudio, NULL /* numInputBuffers */);
7267977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    }
727e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
728e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    ALOGW("Unable to instantiate audio source");
729082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
7330b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Hubersp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
7340b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    return mBufferQueue;
7350b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
7360b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
7370b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::width() const {
738207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber    return 1280;
7390b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
7400b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
7410b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::height() const {
742207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber    return 720;
7430b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
7440b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
745496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() {
746496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
747496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        const sp<Track> &track = mTracks.valueAt(i);
748496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7494a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->requestIDRFrame();
750496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
751496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
752496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
75328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberbool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
75428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mAllTracksHavePacketizerIndex) {
75528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return true;
75628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
75728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
75828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
75928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
76028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            return false;
76128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
76228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
76328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
76428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mAllTracksHavePacketizerIndex = true;
76528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
76628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return true;
76728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
76828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
76928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
77090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        size_t trackIndex, const sp<ABuffer> &accessUnit,
77190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        sp<ABuffer> *packets) {
77228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    const sp<Track> &track = mTracks.valueFor(trackIndex);
77328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
77428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint32_t flags = 0;
77528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
77628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    bool isHDCPEncrypted = false;
77728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint64_t inputCTR;
77828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint8_t HDCP_private_data[16];
77928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mHDCP != NULL && !track->isAudio()) {
78028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        isHDCPEncrypted = true;
78128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
78228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        status_t err = mHDCP->encrypt(
783e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber                accessUnit->data(), accessUnit->size(),
78428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                trackIndex  /* streamCTR */,
78528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                &inputCTR,
78628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                accessUnit->data());
78728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
78828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (err != OK) {
78928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ALOGE("Failed to HDCP-encrypt media data (err %d)",
79028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                  err);
79128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
79228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            return err;
79328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
79428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
79528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[0] = 0x00;
79628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
79728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[1] =
79828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((trackIndex >> 30) & 3) << 1) | 1;
79928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
80028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
80128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
80228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[3] =
80328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((trackIndex >> 15) & 0x7f) << 1) | 1;
80428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
80528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
80628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
80728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[5] =
80828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ((trackIndex & 0x7f) << 1) | 1;
80928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
81028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[6] = 0x00;
81128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
81228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[7] =
81328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 60) & 0x0f) << 1) | 1;
81428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
81528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
81628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
81728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[9] =
81828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 45) & 0x7f) << 1) | 1;
81928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
82028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
82128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
82228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[11] =
82328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 30) & 0x7f) << 1) | 1;
82428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
82528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
82628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
82728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[13] =
82828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 15) & 0x7f) << 1) | 1;
82928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
83028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
83128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
83228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[15] =
83328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ((inputCTR & 0x7f) << 1) | 1;
83428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
835e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#if 0
836e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        ALOGI("HDCP_private_data:");
837e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
838e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber
839e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
840e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(13), 0);
841e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
842e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
843e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
844e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
845e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
846e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
847e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(11), 0);
848e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
849e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
850e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
851e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
852e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
853e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
854e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
855e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
856e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
857e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
858e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#endif
859e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber
86028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::IS_ENCRYPTED;
86128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
86228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
86328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    int64_t timeUs = ALooper::GetNowUs();
86428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
86528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::EMIT_PCR;
86628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
86728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
86828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        mPrevTimeUs = timeUs;
86928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
87028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
87128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mPacketizer->packetize(
87290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            track->packetizerTrackIndex(), accessUnit, packets, flags,
873019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber            !isHDCPEncrypted ? NULL : HDCP_private_data,
87490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data),
87590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            track->isAudio() ? 2 : 0 /* numStuffingBytes */);
87628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
87728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return OK;
87828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
87928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
88028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
88128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    for (;;) {
88228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        bool gotMoreData = false;
88328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        for (size_t i = 0; i < mTracks.size(); ++i) {
88428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            size_t trackIndex = mTracks.keyAt(i);
88528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            const sp<Track> &track = mTracks.valueAt(i);
88628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
88728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
88828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            if (accessUnit != NULL) {
88990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                track->queueOutputBuffer(accessUnit);
89028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                gotMoreData = true;
89128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            }
89228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
89328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
89428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (!gotMoreData) {
89528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            break;
89628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
89728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
89828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
89928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return OK;
90028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
90128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
902ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() {
903ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    // Inform WifiDisplaySource of our premature death (wish).
904ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    sp<AMessage> notify = mNotify->dup();
905ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->setInt32("what", kWhatSessionDead);
906ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->post();
907ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
908ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    mWeAreDead = true;
909ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber}
910ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
91190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Hubervoid WifiDisplaySource::PlaybackSession::drainAccessUnits() {
91290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ALOGV("audio/video has %d/%d buffers ready.",
91390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mTracks.valueFor(1)->countQueuedOutputBuffers(),
91490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            mTracks.valueFor(0)->countQueuedOutputBuffers());
91590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
91690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    while (drainAccessUnit()) {
91790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
91890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
91990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huberbool WifiDisplaySource::PlaybackSession::drainAccessUnit() {
92190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    ssize_t minTrackIndex = -1;
92290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    int64_t minTimeUs = -1ll;
92390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
92590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        const sp<Track> &track = mTracks.valueAt(i);
92690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
92790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        int64_t timeUs;
92890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        if (track->hasOutputBuffer(&timeUs)) {
92990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            if (minTrackIndex < 0 || timeUs < minTimeUs) {
93090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                minTrackIndex = mTracks.keyAt(i);
93190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber                minTimeUs = timeUs;
93290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            }
93390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        } else if (!track->isSuspended()) {
93490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // We still consider this track "live", so it should keep
93590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // delivering output data whose time stamps we'll have to
93690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            // consider for proper interleaving.
93790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber            return false;
93890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        }
93990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
94090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
94190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (minTrackIndex < 0) {
94290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        return false;
94390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
94490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
94590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    const sp<Track> &track = mTracks.valueFor(minTrackIndex);
94690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> accessUnit = track->dequeueOutputBuffer();
94790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
94890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    sp<ABuffer> packets;
94990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    status_t err = packetizeAccessUnit(minTrackIndex, accessUnit, &packets);
95090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
95190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if (err != OK) {
95290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        notifySessionDead();
95390a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
95490a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
95590a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    if ((ssize_t)minTrackIndex == mVideoTrackIndex) {
95690a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber        packets->meta()->setInt32("isVideo", 1);
95790a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    }
95890a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    mSender->queuePackets(minTimeUs, packets);
95990a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
96090a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber    return true;
96190a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber}
96290a92053219ae50ddf4bb54e3d54db2d309e2b8dAndreas Huber
963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
965