PlaybackSession.cpp revision e7bd24af08ef0722fb124a550662bcec48c56f86
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"
26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "TSPacketizer.h"
27e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include "include/avc_utils.h"
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h>
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h>
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h>
32b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber#include <media/IHDCP.h>
33e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#include <media/stagefright/foundation/ABitReader.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h>
38082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber#include <media/stagefright/AudioSource.h>
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h>
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaExtractor.h>
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h>
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h>
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h>
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h>
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h>
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxRTPPacketSize = 1500;
54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public AHandler {
5796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
5896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatStopped,
5996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
6096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
6196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    Track(const sp<AMessage> &notify,
6296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber          const sp<ALooper> &pullLooper,
63e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<ALooper> &codecLooper,
64e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<MediaPuller> &mediaPuller,
65e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber          const sp<Converter> &converter);
66e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
674a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void setRepeaterSource(const sp<RepeaterSource> &source);
684a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> getFormat();
70b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool isAudio() const;
71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<Converter> &converter() const;
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t packetizerTrackIndex() const;
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void setPacketizerTrackIndex(size_t index);
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
77e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t start();
7896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    void stopAsync();
7996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
8028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    void queueAccessUnit(const sp<ABuffer> &accessUnit);
8128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> dequeueAccessUnit();
8228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
834a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    void requestIDRFrame();
844a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected:
8696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    virtual ~Track();
88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate:
9096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    enum {
9196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        kWhatMediaPullerStopped,
9296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    };
9396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
9496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> mNotify;
95e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mPullLooper;
96e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> mCodecLooper;
97e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<MediaPuller> mMediaPuller;
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> mConverter;
99e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    bool mStarted;
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t mPacketizerTrackIndex;
101b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    bool mIsAudio;
10228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    List<sp<ABuffer> > mQueuedAccessUnits;
1034a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> mRepeaterSource;
104b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
105b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    static bool IsAudioFormat(const sp<AMessage> &format);
106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber};
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
110e1957358f11031a554c57d4fb46988dd6044acc1Andreas HuberWifiDisplaySource::PlaybackSession::Track::Track(
11196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &notify,
112e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &pullLooper,
113e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<ALooper> &codecLooper,
114e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<MediaPuller> &mediaPuller,
115e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        const sp<Converter> &converter)
11696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    : mNotify(notify),
11796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber      mPullLooper(pullLooper),
118e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mCodecLooper(codecLooper),
119e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mMediaPuller(mediaPuller),
120e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mConverter(converter),
121e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mStarted(false),
122b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mPacketizerTrackIndex(-1),
123b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) {
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
12796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
130b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber// static
131b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
132b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<AMessage> &format) {
133b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    AString mime;
134b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    CHECK(format->findString("mime", &mime));
135b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
136b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return !strncasecmp(mime.c_str(), "audio/", 6);
137b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
138b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter->getOutputFormat();
141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
143b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huberbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
144b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber    return mIsAudio;
145b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber}
146b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter;
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mPacketizerTrackIndex;
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_LT(mPacketizerTrackIndex, 0);
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mPacketizerTrackIndex = index;
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
160e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
161ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    ALOGV("Track::start isAudio=%d", mIsAudio);
162ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
16396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    CHECK(!mStarted);
164e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
165e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = OK;
166e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
167e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (mMediaPuller != NULL) {
168e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        err = mMediaPuller->start();
169e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
170e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
171e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err == OK) {
172e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mStarted = true;
173e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
174e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
175e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return err;
176e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
177e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
17896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::stopAsync() {
17996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGV("Track::stopAsync isAudio=%d", mIsAudio);
180ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
18196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mConverter->shutdownAsync();
18296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
18396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
184e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
185ad0d97c7cf620e96a0b088dd9461645a3f8900b7Andreas Huber    if (mStarted && mMediaPuller != NULL) {
1864a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        if (mRepeaterSource != NULL) {
1874a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            // Let's unblock MediaPuller's MediaSource::read().
1884a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            mRepeaterSource->wakeUp();
1894a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        }
1904a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
19196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mMediaPuller->stopAsync(msg);
19296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    } else {
19396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        msg->post();
194e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
19596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber}
196e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
19796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::onMessageReceived(
19896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        const sp<AMessage> &msg) {
19996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    switch (msg->what()) {
20096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatMediaPullerStopped:
20196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
20296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mConverter.clear();
203a438123bd96c7faf145683876702387efe5628d9Andreas Huber
20496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            mStarted = false;
205e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
20696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            sp<AMessage> notify = mNotify->dup();
20796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->setInt32("what", kWhatStopped);
20896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify->post();
20977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
21077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber            ALOGI("kWhatStopped %s posted", mIsAudio ? "audio" : "video");
21196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
21296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
21396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
21496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        default:
21596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            TRESPASS();
21696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    }
217e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
218e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
21928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::queueAccessUnit(
22028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        const sp<ABuffer> &accessUnit) {
22128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.push_back(accessUnit);
22228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
22328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
22428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Hubersp<ABuffer> WifiDisplaySource::PlaybackSession::Track::dequeueAccessUnit() {
22528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mQueuedAccessUnits.empty()) {
22628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return NULL;
22728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
22828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
22928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> accessUnit = *mQueuedAccessUnits.begin();
23028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    CHECK(accessUnit != NULL);
23128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
23228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mQueuedAccessUnits.erase(mQueuedAccessUnits.begin());
23328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
23428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return accessUnit;
23528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
23628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
2374a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
2384a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        const sp<RepeaterSource> &source) {
2394a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mRepeaterSource = source;
2404a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2414a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2424a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Hubervoid WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
2434a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mIsAudio) {
2444a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        return;
2454a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2464a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2474a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (mRepeaterSource != NULL) {
2484a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        mRepeaterSource->wakeUp();
2494a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
2504a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
2514a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    mConverter->requestIDRFrame();
2524a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber}
2534a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber////////////////////////////////////////////////////////////////////////////////
255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ANetworkSession> &netSession,
2580b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber        const sp<AMessage> &notify,
259bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        const in_addr &interfaceAddr,
260b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber        const sp<IHDCP> &hdcp)
261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mNetSession(netSession),
262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
263bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mInterfaceAddr(interfaceAddr),
264b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber      mHDCP(hdcp),
265ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber      mWeAreDead(false),
266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastLifesignUs(),
267e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber      mVideoTrackIndex(-1),
268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mPrevTimeUs(-1ll),
270bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mTransportMode(TRANSPORT_UDP),
27128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber      mAllTracksHavePacketizerIndex(false),
272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPChannel(0),
273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTCPChannel(0),
274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPPort(0),
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPSessionID(0),
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTCPSessionID(0),
277efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
278efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber      mRTPRetransmissionSessionID(0),
279efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber      mRTCPRetransmissionSessionID(0),
280efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
281bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mClientRTPPort(0),
282bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mClientRTCPPort(0),
283bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mRTPConnected(false),
284bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber      mRTCPConnected(false),
285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPSeqNo(0),
286efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
287efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber      mRTPRetransmissionSeqNo(0),
288efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastNTPTime(0),
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastRTPTime(0),
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumRTPSent(0),
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumRTPOctetsSent(0),
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumSRsSent(0),
294887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber      mSendSRPending(false)
295887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber#if ENABLE_RETRANSMISSION
296887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber      ,mHistoryLength(0)
297887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber#endif
29877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH
299ee178668818eb4f43ff40735405f8fc42372620fAndreas Huber      ,mFirstPacketTimeUs(-1ll)
30077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber      ,mTotalBytesSent(0ll)
30177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif
302774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
303774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber      ,mLogFile(NULL)
304774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
305774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber{
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTSQueue->setRange(0, 12);
307774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
308774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
309774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    mLogFile = fopen("/system/etc/log.ts", "wb");
310774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
315e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        TransportMode transportMode,
316e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio) {
317bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    mClientIP = clientIP;
318bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
319e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    status_t err = setupPacketizer(usePCMAudio);
320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
325bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    mTransportMode = transportMode;
326bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
327bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (transportMode == TRANSPORT_TCP_INTERLEAVED) {
328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPChannel = clientRtp;
329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTCPChannel = clientRtcp;
330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPPort = 0;
331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPSessionID = 0;
332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTCPSessionID = 0;
333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        updateLiveness();
335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return OK;
336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mRTPChannel = 0;
339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mRTCPChannel = 0;
340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
341bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (mTransportMode == TRANSPORT_TCP) {
342bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        // XXX This is wrong, we need to allocate sockets here, we only
343bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        // need to do this because the dongles are not establishing their
344bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        // end until after PLAY instead of before SETUP.
345bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        mRTPPort = 20000;
346bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        mRTPSessionID = 0;
347bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        mRTCPSessionID = 0;
348bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        mClientRTPPort = clientRtp;
349bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        mClientRTCPPort = clientRtcp;
350bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
351bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        updateLiveness();
352bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        return OK;
353bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    }
354bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int serverRtp;
356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
359efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
360efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
361efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber    sp<AMessage> rtpRetransmissionNotify =
362efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        new AMessage(kWhatRTPRetransmissionNotify, id());
363efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
364efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber    sp<AMessage> rtcpRetransmissionNotify =
365efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        new AMessage(kWhatRTCPRetransmissionNotify, id());
366efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
367efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    for (serverRtp = 15550;; serverRtp += 2) {
369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int32_t rtpSession;
370bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        if (mTransportMode == TRANSPORT_UDP) {
371bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            err = mNetSession->createUDPSession(
372bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        serverRtp, clientIP, clientRtp,
373bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        rtpNotify, &rtpSession);
374bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        } else {
375bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            err = mNetSession->createTCPDatagramSession(
376bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        serverRtp, clientIP, clientRtp,
377bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        rtpNotify, &rtpSession);
378bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        }
379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("failed to create RTP socket on port %d", serverRtp);
382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            continue;
383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
385efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        int32_t rtcpSession = 0;
386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
387efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        if (clientRtcp >= 0) {
388efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            if (mTransportMode == TRANSPORT_UDP) {
389efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                err = mNetSession->createUDPSession(
390efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        serverRtp + 1, clientIP, clientRtcp,
391efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        rtcpNotify, &rtcpSession);
392efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            } else {
393efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                err = mNetSession->createTCPDatagramSession(
394efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        serverRtp + 1, clientIP, clientRtcp,
395efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        rtcpNotify, &rtcpSession);
396efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            }
397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
398efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            if (err != OK) {
399efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
400efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
401efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtpSession);
402efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                continue;
403efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            }
404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
406efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
407bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        if (mTransportMode == TRANSPORT_UDP) {
408efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            int32_t rtpRetransmissionSession;
409efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
410bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            err = mNetSession->createUDPSession(
411efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        serverRtp + kRetransmissionPortOffset,
412efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        clientIP,
413efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        clientRtp + kRetransmissionPortOffset,
414efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        rtpRetransmissionNotify,
415efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        &rtpRetransmissionSession);
416efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
417efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            if (err != OK) {
418efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtcpSession);
419efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtpSession);
420efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                continue;
421efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            }
422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
423efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            CHECK_GE(clientRtcp, 0);
424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
425efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            int32_t rtcpRetransmissionSession;
426efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            err = mNetSession->createUDPSession(
427efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        serverRtp + 1 + kRetransmissionPortOffset,
428efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        clientIP,
429efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        clientRtp + 1 + kRetransmissionPortOffset,
430efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        rtcpRetransmissionNotify,
431efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        &rtcpRetransmissionSession);
432efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
433efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            if (err != OK) {
434efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtpRetransmissionSession);
435efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtcpSession);
436efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                mNetSession->destroySession(rtpSession);
437efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                continue;
438efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            }
439efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
440efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            mRTPRetransmissionSessionID = rtpRetransmissionSession;
441efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            mRTCPRetransmissionSessionID = rtcpRetransmissionSession;
442efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
443efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            ALOGI("rtpRetransmissionSessionID = %d, "
444efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                  "rtcpRetransmissionSessionID = %d",
445efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                  rtpRetransmissionSession, rtcpRetransmissionSession);
446d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
447efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
448efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
449efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        mRTPPort = serverRtp;
450efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        mRTPSessionID = rtpSession;
451efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        mRTCPSessionID = rtcpSession;
452d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
453efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
454efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        break;
455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTPPort == 0) {
458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return UNKNOWN_ERROR;
459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
467774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
468774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    if (mLogFile != NULL) {
469774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber        fclose(mLogFile);
470774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber        mLogFile = NULL;
471774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    }
472774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mRTPPort;
477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mLastLifesignUs;
481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
490bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
491bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
492bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
493bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::finishPlay() {
49492f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber    // XXX Give the dongle a second to bind its sockets.
49592f655fe351a5f2eb7d36123d2b687d6e7e3e913Andreas Huber    (new AMessage(kWhatFinishPlay, id()))->post(1000000ll);
496bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return OK;
497bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
498bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
499bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
500bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (mTransportMode != TRANSPORT_TCP) {
501bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        return onFinishPlay2();
502bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    }
503bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
504bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
505bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
506bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    status_t err = mNetSession->createTCPDatagramSession(
507bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                mRTPPort, mClientIP.c_str(), mClientRTPPort,
508bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                rtpNotify, &mRTPSessionID);
509bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
510bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (err != OK) {
511bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        return err;
512bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    }
513bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
514bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (mClientRTCPPort >= 0) {
515bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
516bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
517bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        err = mNetSession->createTCPDatagramSession(
518bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort,
519bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                rtcpNotify, &mRTCPSessionID);
520bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    }
521bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
522bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return err;
523bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
524bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
525bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTCPSessionID != 0) {
527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        scheduleSendSR();
528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
530e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
53196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        CHECK_EQ((status_t)OK, mTracks.editValueAt(i)->start());
532e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
533e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
534bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    sp<AMessage> notify = mNotify->dup();
535bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->setInt32("what", kWhatSessionEstablished);
536bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    notify->post();
537bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
538e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
540d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
54796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Hubervoid WifiDisplaySource::PlaybackSession::destroyAsync() {
54896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    ALOGI("destroyAsync");
549a438123bd96c7faf145683876702387efe5628d9Andreas Huber
55096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
55196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        mTracks.valueAt(i)->stopAsync();
552a438123bd96c7faf145683876702387efe5628d9Andreas Huber    }
553a438123bd96c7faf145683876702387efe5628d9Andreas Huber}
554a438123bd96c7faf145683876702387efe5628d9Andreas Huber
555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &msg) {
557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatRTPNotify:
559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatRTCPNotify:
560efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
561efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        case kWhatRTPRetransmissionNotify:
562efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        case kWhatRTCPRetransmissionNotify:
563efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t reason;
566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("reason", &reason));
567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            switch (reason) {
569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                case ANetworkSession::kWhatError:
570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                {
571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t sessionID;
572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t err;
575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("err", &err));
576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t errorOccuredDuringSend;
578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    AString detail;
581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findString("detail", &detail));
582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
583efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    if ((msg->what() == kWhatRTPNotify
584efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
585efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                            || msg->what() == kWhatRTPRetransmissionNotify
586efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
587efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        ) && !errorOccuredDuringSend) {
588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        // This is ok, we don't expect to receive anything on
589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        // the RTP socket.
590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        break;
591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGE("An error occurred during %s in session %d "
594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          "(%d, '%s' (%s)).",
595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          errorOccuredDuringSend ? "send" : "receive",
596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          sessionID,
597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          err,
598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          detail.c_str(),
599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          strerror(-err));
600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mNetSession->destroySession(sessionID);
602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (sessionID == mRTPSessionID) {
604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mRTPSessionID = 0;
605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    } else if (sessionID == mRTCPSessionID) {
606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mRTCPSessionID = 0;
607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
608efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
609efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    else if (sessionID == mRTPRetransmissionSessionID) {
610efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        mRTPRetransmissionSessionID = 0;
611efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    } else if (sessionID == mRTCPRetransmissionSessionID) {
612efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        mRTCPRetransmissionSessionID = 0;
613efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    }
614efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
616ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                    notifySessionDead();
617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    break;
618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                case ANetworkSession::kWhatDatagram:
621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                {
622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t sessionID;
623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<ABuffer> data;
626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findBuffer("data", &data));
627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    status_t err;
629efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    if (msg->what() == kWhatRTCPNotify
630efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
631efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                            || msg->what() == kWhatRTCPRetransmissionNotify
632efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
633efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                       )
634efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    {
635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        err = parseRTCP(data);
636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    break;
638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
640bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                case ANetworkSession::kWhatConnected:
641bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                {
642bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    CHECK_EQ(mTransportMode, TRANSPORT_TCP);
643bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
644bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    int32_t sessionID;
645bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
646bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
647bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    if (sessionID == mRTPSessionID) {
648bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        CHECK(!mRTPConnected);
649bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        mRTPConnected = true;
650bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        ALOGI("RTP Session now connected.");
651bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    } else if (sessionID == mRTCPSessionID) {
652bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        CHECK(!mRTCPConnected);
653bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        mRTCPConnected = true;
654bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        ALOGI("RTCP Session now connected.");
655bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    } else {
656bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        TRESPASS();
657bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    }
658bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
659bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    if (mRTPConnected
660bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                            && (mClientRTCPPort < 0 || mRTCPConnected)) {
661bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                        onFinishPlay2();
662bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    }
663bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                    break;
664bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber                }
665bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                default:
667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    TRESPASS();
668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatSendSR:
673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mSendSRPending = false;
675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (mRTCPSessionID == 0) {
677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            onSendSR();
681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleSendSR();
683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatConverterNotify:
687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
6886360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            if (mWeAreDead) {
6896360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                ALOGV("dropping msg '%s' because we're dead",
6906360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                      msg->debugString().c_str());
6916360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
6926360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber                break;
6936360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber            }
6946360758ce2d171169d2a21e30266547ee4ac0fecAndreas Huber
695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t trackIndex;
699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Converter::kWhatAccessUnit) {
702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
70628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (packetizerTrackIndex < 0) {
707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    packetizerTrackIndex =
708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mPacketizer->addTrack(track->getFormat());
709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
71028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    CHECK_GE(packetizerTrackIndex, 0);
711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
71228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    track->setPacketizerTrackIndex(packetizerTrackIndex);
713b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
71428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    if (allTracksHavePacketizerIndex()) {
71528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                        status_t err = packetizeQueuedAccessUnits();
716b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
717b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                        if (err != OK) {
718ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                            notifySessionDead();
719b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                            break;
720b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                        }
721b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber                    }
72228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                }
723b8c7bd418f0ee5b88923b0e0817e3a4acc53cf8dAndreas Huber
72428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                sp<ABuffer> accessUnit;
72528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
72728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (!allTracksHavePacketizerIndex()) {
72828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    track->queueAccessUnit(accessUnit);
72928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    break;
73028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                }
731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
73228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
733774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
73428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (err != OK) {
735ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                    notifySessionDead();
736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
73728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                break;
738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else if (what == Converter::kWhatEOS) {
739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGI("output EOS on track %d", trackIndex);
742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_GE(index, 0);
745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Converter> &converter =
747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(index)->converter();
748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                looper()->unregisterHandler(converter->id());
749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.removeItemsAt(index);
751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (mTracks.isEmpty()) {
753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("Reached EOS");
754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                status_t err;
759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findInt32("err", &err));
760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGE("converter signaled error %d", err);
762ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber
763ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber                notifySessionDead();
764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
768bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        case kWhatFinishPlay:
769bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        {
770bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            onFinishPlay();
771bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            break;
772bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        }
773bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
77496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        case kWhatTrackNotify:
77596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        {
77696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            int32_t what;
77796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findInt32("what", &what));
77896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
77996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            size_t trackIndex;
78096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
78196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
78296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            if (what == Track::kWhatStopped) {
78377245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                ALOGI("Track %d stopped", trackIndex);
78496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
78577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                sp<Track> track = mTracks.valueFor(trackIndex);
78677245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                looper()->unregisterHandler(track->id());
78777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                mTracks.removeItem(trackIndex);
78877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                track.clear();
78977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
79077245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                if (!mTracks.isEmpty()) {
79177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber                    ALOGI("not all tracks are stopped yet");
79296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    break;
79396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
79496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
79596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                mPacketizer.clear();
79696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
79796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#if ENABLE_RETRANSMISSION
79896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (mRTCPRetransmissionSessionID != 0) {
79996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    mNetSession->destroySession(mRTCPRetransmissionSessionID);
80096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
80196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
80296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (mRTPRetransmissionSessionID != 0) {
80396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    mNetSession->destroySession(mRTPRetransmissionSessionID);
80496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
80596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber#endif
80696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
80796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (mRTCPSessionID != 0) {
80896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    mNetSession->destroySession(mRTCPSessionID);
80996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
81096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
81196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                if (mRTPSessionID != 0) {
81296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                    mNetSession->destroySession(mRTPSessionID);
81396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                }
81496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
81596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                sp<AMessage> notify = mNotify->dup();
81696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                notify->setInt32("what", kWhatSessionDestroyed);
81796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber                notify->post();
81896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            }
81996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            break;
82096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        }
82196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
822d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
823d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
824d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
827e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer(bool usePCMAudio) {
828e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    mPacketizer = new TSPacketizer;
829d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
830e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    status_t err = addVideoSource();
831d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
832e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
833e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
834e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
835e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
836e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    return addAudioSource(usePCMAudio);
837e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
838d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
839e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addSource(
8404a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
841e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        bool usePCMAudio, size_t *numInputBuffers) {
842e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!usePCMAudio || !isVideo);
843e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber    CHECK(!isRepeaterSource || isVideo);
844e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber
845e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> pullLooper = new ALooper;
846e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->setName("pull_looper");
847e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
848e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    pullLooper->start(
849e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
850e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
851ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
853e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<ALooper> codecLooper = new ALooper;
854e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->setName("codec_looper");
855e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
856e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    codecLooper->start(
857e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* runOnCallingThread */,
858e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber            false /* canCallJava */,
859ea4bbfdcad9478ea19257fb19a32de68a2dfd958Andreas Huber            PRIORITY_AUDIO);
860e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
861e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t trackIndex;
862e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
863e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<AMessage> notify;
864e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
865e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    trackIndex = mTracks.size();
866e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
867d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> format;
868d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
869d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(err, (status_t)OK);
870d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
871e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
872e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32("store-metadata-in-buffers", true);
873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
874e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        format->setInt32(
875e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber                "color-format", OMX_COLOR_FormatAndroidOpaque);
876e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
878e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify = new AMessage(kWhatConverterNotify, id());
879e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    notify->setSize("trackIndex", trackIndex);
880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> converter =
882e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber        new Converter(notify, codecLooper, format, usePCMAudio);
8833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
8843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (converter->initCheck() != OK) {
8853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        return converter->initCheck();
8863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
88766e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    looper()->registerHandler(converter);
889d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
89096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(Converter::kWhatMediaPullerNotify, converter->id());
89196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
89296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
89396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<MediaPuller> puller = new MediaPuller(source, notify);
89496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    pullLooper->registerHandler(puller);
89596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
896e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (numInputBuffers != NULL) {
897e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        *numInputBuffers = converter->getInputBufferCount();
898e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
89966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
90096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify = new AMessage(kWhatTrackNotify, id());
90196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    notify->setSize("trackIndex", trackIndex);
90296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
90396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    sp<Track> track = new Track(
90496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber            notify, pullLooper, codecLooper, puller, converter);
90596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
9064a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    if (isRepeaterSource) {
9074a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
9084a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    }
9094a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
91096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    looper()->registerHandler(track);
91196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
91296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber    mTracks.add(trackIndex, track);
913e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
914e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (isVideo) {
915e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        mVideoTrackIndex = trackIndex;
916e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
917e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
918e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
919e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
920e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
921e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addVideoSource() {
922e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
923e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
924af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber    source->setUseAbsoluteTimestamps();
925af5dd7753e62353411cf0daf3b513c38818e9662Andreas Huber
9268d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#if 1
9274a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    sp<RepeaterSource> videoSource =
9284a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        new RepeaterSource(source, 30.0 /* rateHz */);
9298d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#endif
9304a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber
9318d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#if 1
932e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    size_t numInputBuffers;
9334a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber    status_t err = addSource(
9344a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber            true /* isVideo */, videoSource, true /* isRepeaterSource */,
935e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
9368d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#else
9378d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber    size_t numInputBuffers;
9388d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber    status_t err = addSource(
9398d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber            true /* isVideo */, source, false /* isRepeaterSource */,
940e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber            false /* usePCMAudio */, &numInputBuffers);
9418d16bbc5a354d302abfd912b8d88d9c7feb3948fAndreas Huber#endif
942e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
943e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    if (err != OK) {
944e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return err;
945e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    }
94666e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
9475a832f87b680ead3606c4448a0a82c0e556d1b93Andreas Huber    err = source->setMaxAcquiredBufferCount(numInputBuffers);
94866e72bc85fb762876baff60ef29de729da93cf26Andreas Huber    CHECK_EQ(err, (status_t)OK);
94966e72bc85fb762876baff60ef29de729da93cf26Andreas Huber
9500b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    mBufferQueue = source->getBufferQueue();
9510b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
952e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    return OK;
953e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber}
954e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
955e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::addAudioSource(bool usePCMAudio) {
956082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber    sp<AudioSource> audioSource = new AudioSource(
9571646a0fed94c30a44128b3c379736def4b332033Andreas Huber            AUDIO_SOURCE_REMOTE_SUBMIX,
958082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber            48000 /* sampleRate */,
9591646a0fed94c30a44128b3c379736def4b332033Andreas Huber            2 /* channelCount */);
960082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
9617977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    if (audioSource->initCheck() == OK) {
962e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber        return addSource(
9634a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber                false /* isVideo */, audioSource, false /* isRepeaterSource */,
964e7bd24af08ef0722fb124a550662bcec48c56f86Andreas Huber                usePCMAudio, NULL /* numInputBuffers */);
9657977e85f7287f2b0e7a5de94e853e6073736e03bAndreas Huber    }
966e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber
967e1957358f11031a554c57d4fb46988dd6044acc1Andreas Huber    ALOGW("Unable to instantiate audio source");
968082830f92373a1b9e512dbbfb940187ffa1c2c6fAndreas Huber
969d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9720b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Hubersp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
9730b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber    return mBufferQueue;
9740b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
9750b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
9760b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::width() const {
977207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber    return 1280;
9780b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
9790b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
9800b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huberint32_t WifiDisplaySource::PlaybackSession::height() const {
981207e18540fefbaf530a4fdf506d266f34ddec84fAndreas Huber    return 720;
9820b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber}
9830b73d4730202fcad53aefc4314a06e7b95f442f0Andreas Huber
984d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::scheduleSendSR() {
985d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mSendSRPending) {
986d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
987d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
988d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
989d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSendSRPending = true;
990d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
991d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
992d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
993d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
994d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
995d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
996d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    // TODO: Use macros/utility functions to clean up all the bitshifts below.
997d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
998d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[0] = 0x80 | 0;
999d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[1] = 200;  // SR
1000d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[2] = 0;
1001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[3] = 6;
1002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[4] = kSourceID >> 24;
1003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
1004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
1005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[7] = kSourceID & 0xff;
1006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[8] = mLastNTPTime >> (64 - 8);
1008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
1009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
1010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[11] = (mLastNTPTime >> 32) & 0xff;
1011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[12] = (mLastNTPTime >> 24) & 0xff;
1012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[13] = (mLastNTPTime >> 16) & 0xff;
1013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[14] = (mLastNTPTime >> 8) & 0xff;
1014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[15] = mLastNTPTime & 0xff;
1015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[16] = (mLastRTPTime >> 24) & 0xff;
1017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[17] = (mLastRTPTime >> 16) & 0xff;
1018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[18] = (mLastRTPTime >> 8) & 0xff;
1019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[19] = mLastRTPTime & 0xff;
1020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[20] = mNumRTPSent >> 24;
1022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[21] = (mNumRTPSent >> 16) & 0xff;
1023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[22] = (mNumRTPSent >> 8) & 0xff;
1024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[23] = mNumRTPSent & 0xff;
1025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1026d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[24] = mNumRTPOctetsSent >> 24;
1027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[27] = mNumRTPOctetsSent & 0xff;
1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 28);
1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[0] = 0x80 | 1;
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[1] = 202;  // SDES
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[4] = kSourceID >> 24;
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[7] = kSourceID & 0xff;
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t offset = 8;
1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 1;  // CNAME
1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    static const char *kCNAME = "someone@somewhere";
1048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = strlen(kCNAME);
1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(&data[offset], kCNAME, strlen(kCNAME));
1051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    offset += strlen(kCNAME);
1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 7;  // NOTE
1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    static const char *kNOTE = "Hell's frozen over.";
1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = strlen(kNOTE);
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(&data[offset], kNOTE, strlen(kNOTE));
1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    offset += strlen(kNOTE);
1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 0;
1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if ((offset % 4) > 0) {
1064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t count = 4 - (offset % 4);
1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        switch (count) {
1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 3:
1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 2:
1069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 1:
1071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
1072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t numWords = (offset / 4) - 1;
1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[2] = numWords >> 8;
1077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[3] = numWords & 0xff;
1078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + offset);
1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber// static
1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t nowUs = ALooper::GetNowUs();
1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
1087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t hi = nowUs / 1000000ll;
1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
1090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return (hi << 32) | lo;
1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onSendSR() {
1095d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<ABuffer> buffer = new ABuffer(1500);
1096d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(0, 0);
1097d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    addSR(buffer);
1099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    addSDES(buffer);
1100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1101bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<AMessage> notify = mNotify->dup();
1103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setInt32("what", kWhatBinaryData);
1104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setInt32("channel", mRTCPChannel);
1105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setBuffer("data", buffer);
1106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->post();
1107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
1108bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
1109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ++mNumSRsSent;
1112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::appendTSData(
1115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
1116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(size, 188);
1117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
1119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
1121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTSQueue->setRange(0, mTSQueue->size() + size);
1122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
1124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // flush
1125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
112777245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber
112877245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH
1129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (mFirstPacketTimeUs < 0ll) {
1130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mFirstPacketTimeUs = nowUs;
1131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
113277245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif
1133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // 90kHz time scale
113577245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber        uint32_t rtpTime = (nowUs * 9ll) / 100ll;
1136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint8_t *rtp = mTSQueue->data();
1138d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[0] = 0x80;
1139d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
1140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
1141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[3] = mRTPSeqNo & 0xff;
1142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[4] = rtpTime >> 24;
1143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[5] = (rtpTime >> 16) & 0xff;
1144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[6] = (rtpTime >> 8) & 0xff;
1145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[7] = rtpTime & 0xff;
1146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[8] = kSourceID >> 24;
1147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[9] = (kSourceID >> 16) & 0xff;
1148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[10] = (kSourceID >> 8) & 0xff;
1149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[11] = kSourceID & 0xff;
1150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mRTPSeqNo;
1152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mNumRTPSent;
1153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNumRTPOctetsSent += mTSQueue->size() - 12;
1154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLastRTPTime = rtpTime;
1156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLastNTPTime = GetNowNTP();
1157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1158bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
1160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatBinaryData);
1161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(data->data(), rtp, mTSQueue->size());
1164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("channel", mRTPChannel);
1166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setBuffer("data", data);
1167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
1168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
1169bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
1170dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber
117177245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#if TRACK_BANDWIDTH
1172dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber            mTotalBytesSent += mTSQueue->size();
1173dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1174dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber
1175dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber            if (delayUs > 0ll) {
1176ee178668818eb4f43ff40735405f8fc42372620fAndreas Huber                ALOGI("approx. net bandwidth used: %.2f Mbit/sec",
1177dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber                        mTotalBytesSent * 8.0 / delayUs);
1178dca352880e210e0ca0ff39de074540d3640ecfabAndreas Huber            }
117977245813007cf903b4b73f5d0cd20313fbf0e510Andreas Huber#endif
1180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1182887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber#if ENABLE_RETRANSMISSION
1183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1184887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber
1185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mHistory.push_back(mTSQueue);
1186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mHistoryLength;
1187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (mHistoryLength > kMaxHistoryLength) {
1189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mTSQueue = *mHistory.begin();
1190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mHistory.erase(mHistory.begin());
1191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            --mHistoryLength;
1193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
1194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1196887070dbe6b6258ba04f988fd90c3ac856d2e5bfAndreas Huber#endif
1197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mTSQueue->setRange(0, 12);
1199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return size;
1202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseRTCP(
1205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ABuffer> &buffer) {
1206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const uint8_t *data = buffer->data();
1207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t size = buffer->size();
1208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (size > 0) {
1210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (size < 8) {
1211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Too short to be a valid RTCP header
1212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_MALFORMED;
1213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if ((data[0] >> 6) != 2) {
1216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Unsupported version.
1217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_UNSUPPORTED;
1218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (data[0] & 0x20) {
1221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Padding present.
1222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t paddingLength = data[size - 1];
1224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (paddingLength + 12 > size) {
1226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                // If we removed this much padding we'd end up with something
1227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                // that's too short to be a valid RTP header.
1228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                return ERROR_MALFORMED;
1229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
1230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size -= paddingLength;
1232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (size < headerLength) {
1237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Only received a partial packet?
1238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_MALFORMED;
1239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        switch (data[1]) {
1242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 200:
1243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 201:  // RR
1244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 202:  // SDES
1245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 203:
1246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 204:  // APP
1247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
1248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1249efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
1250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 205:  // TSFB (transport layer specific feedback)
1251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                parseTSFB(data, headerLength);
1252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
1253efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
1254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 206:  // PSFB (payload specific feedback)
1256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                hexdump(data, headerLength);
1257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
1258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            default:
1260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            {
1261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGW("Unknown RTCP packet type %u of size %d",
1262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                     (unsigned)data[1], headerLength);
1263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
1264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
1265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        data += headerLength;
1268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size -= headerLength;
1269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
1272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1274efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#if ENABLE_RETRANSMISSION
1275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseTSFB(
1276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const uint8_t *data, size_t size) {
1277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if ((data[0] & 0x1f) != 1) {
1278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t srcId = U32_AT(&data[8]);
1282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (srcId != kSourceID) {
1283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_MALFORMED;
1284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    for (size_t i = 12; i < size; i += 4) {
1287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint16_t seqNo = U16_AT(&data[i]);
1288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint16_t blp = U16_AT(&data[i + 2]);
1289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        List<sp<ABuffer> >::iterator it = mHistory.begin();
1291efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        bool foundSeqNo = false;
1292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        while (it != mHistory.end()) {
1293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            const sp<ABuffer> &buffer = *it;
1294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1297efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            bool retransmit = false;
1298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (bufferSeqNo == seqNo) {
1299efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                retransmit = true;
1300efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            } else if (blp != 0) {
1301efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                for (size_t i = 0; i < 16; ++i) {
1302efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    if ((blp & (1 << i))
1303efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1304efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        blp &= ~(1 << i);
1305efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        retransmit = true;
1306efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    }
1307efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                }
1308efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            }
1309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1310efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            if (retransmit) {
1311efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1312efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
1313efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1314efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                uint8_t *rtp = retransRTP->data();
1315efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                memcpy(rtp, buffer->data(), 12);
1316efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1317efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1318efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1319efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                rtp[13] = bufferSeqNo & 0xff;
1320efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1321efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
1322efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                ++mRTPRetransmissionSeqNo;
1323efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
1324efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                sendPacket(
1325efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        mRTPRetransmissionSessionID,
1326efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                        retransRTP->data(), retransRTP->size());
1327efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
1328efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                if (bufferSeqNo == seqNo) {
1329efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    foundSeqNo = true;
1330efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                }
1331efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber
1332efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                if (foundSeqNo && blp == 0) {
1333efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                    break;
1334efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                }
1335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
1336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ++it;
1338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1340efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber        if (!foundSeqNo || blp != 0) {
1341efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber            ALOGI("Some sequence numbers were no longer available for "
1342efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber                  "retransmission");
1343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
1344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
1345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
1347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
1348efd9c63dc846dd3dea2c979fe2a9d6770e73f9acAndreas Huber#endif
1349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
1352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        const sp<Track> &track = mTracks.valueAt(i);
1353496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
13544a8b9a2363b7b7b4f98022e6d9aae8b8aa8e35e5Andreas Huber        track->requestIDRFrame();
1355496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
1356496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
1357496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1358bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huberstatus_t WifiDisplaySource::PlaybackSession::sendPacket(
1359bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber        int32_t sessionID, const void *data, size_t size) {
1360bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber    return mNetSession->sendRequest(sessionID, data, size);
1361bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber}
1362bd08e2f93bafd02abf2c25d740e9fb8bce455a99Andreas Huber
136328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberbool WifiDisplaySource::PlaybackSession::allTracksHavePacketizerIndex() {
136428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mAllTracksHavePacketizerIndex) {
136528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        return true;
136628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
136728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
136828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    for (size_t i = 0; i < mTracks.size(); ++i) {
136928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (mTracks.valueAt(i)->packetizerTrackIndex() < 0) {
137028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            return false;
137128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
137228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
137328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
137428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mAllTracksHavePacketizerIndex = true;
137528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
137628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return true;
137728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
137828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
137928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeAccessUnit(
1380c6920dfdca378a168a2168f4a64d21af4d37d539Andreas Huber        size_t trackIndex, const sp<ABuffer> &accessUnit) {
138128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    const sp<Track> &track = mTracks.valueFor(trackIndex);
138228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
138328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint32_t flags = 0;
138428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
138528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    bool isHDCPEncrypted = false;
138628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint64_t inputCTR;
138728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    uint8_t HDCP_private_data[16];
138828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mHDCP != NULL && !track->isAudio()) {
138928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        isHDCPEncrypted = true;
139028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
139128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        status_t err = mHDCP->encrypt(
1392e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber                accessUnit->data(), accessUnit->size(),
139328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                trackIndex  /* streamCTR */,
139428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                &inputCTR,
139528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                accessUnit->data());
139628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
139728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (err != OK) {
139828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ALOGE("Failed to HDCP-encrypt media data (err %d)",
139928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                  err);
140028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
140128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            return err;
140228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
140328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
140428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[0] = 0x00;
140528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
140628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[1] =
140728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((trackIndex >> 30) & 3) << 1) | 1;
140828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
140928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
141028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
141128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[3] =
141228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((trackIndex >> 15) & 0x7f) << 1) | 1;
141328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
141428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
141528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
141628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[5] =
141728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ((trackIndex & 0x7f) << 1) | 1;
141828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
141928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[6] = 0x00;
142028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
142128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[7] =
142228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 60) & 0x0f) << 1) | 1;
142328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
142428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
142528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
142628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[9] =
142728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 45) & 0x7f) << 1) | 1;
142828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
142928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
143028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
143128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[11] =
143228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 30) & 0x7f) << 1) | 1;
143328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
143428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
143528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
143628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[13] =
143728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            (((inputCTR >> 15) & 0x7f) << 1) | 1;
143828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
143928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
144028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
144128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        HDCP_private_data[15] =
144228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            ((inputCTR & 0x7f) << 1) | 1;
144328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
1444e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#if 0
1445e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        ALOGI("HDCP_private_data:");
1446e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        hexdump(HDCP_private_data, sizeof(HDCP_private_data));
1447e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber
1448e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        ABitReader br(HDCP_private_data, sizeof(HDCP_private_data));
1449e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(13), 0);
1450e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(2), (trackIndex >> 30) & 3);
1451e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1452e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (trackIndex >> 15) & 0x7fff);
1453e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1454e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), trackIndex & 0x7fff);
1455e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1456e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(11), 0);
1457e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(4), (inputCTR >> 60) & 0xf);
1458e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1459e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 45) & 0x7fff);
1460e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1461e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 30) & 0x7fff);
1462e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1463e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), (inputCTR >> 15) & 0x7fff);
1464e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1465e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(15), inputCTR & 0x7fff);
1466e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber        CHECK_EQ(br.getBits(1), 1u);
1467e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber#endif
1468e399acc9d9f3b7af72106c4209e4bb40de37aa6aAndreas Huber
146928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::IS_ENCRYPTED;
147028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
147128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
147228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    int64_t timeUs = ALooper::GetNowUs();
147328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll <= timeUs) {
147428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::EMIT_PCR;
147528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        flags |= TSPacketizer::EMIT_PAT_AND_PMT;
147628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
147728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        mPrevTimeUs = timeUs;
147828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
147928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
148028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    sp<ABuffer> packets;
148128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    mPacketizer->packetize(
148228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            track->packetizerTrackIndex(), accessUnit, &packets, flags,
1483019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber            !isHDCPEncrypted ? NULL : HDCP_private_data,
1484019aabab44e396d9a68c8126c9e0745162a4603aAndreas Huber            !isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));
148528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
148628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    for (size_t offset = 0;
148728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            offset < packets->size(); offset += 188) {
148828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        bool lastTSPacket = (offset + 188 >= packets->size());
148928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
149028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        // We're only going to flush video, audio packets are
149128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        // much more frequent and would waste all that space
149228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        // available in a full sized UDP packet.
149328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        bool flush =
149428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            lastTSPacket
149528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                && ((ssize_t)trackIndex == mVideoTrackIndex);
149628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
149728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        appendTSData(
149828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                packets->data() + offset,
149928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                188,
150028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                true /* timeDiscontinuity */,
150128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                flush);
150228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
150328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
150428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#if LOG_TRANSPORT_STREAM
150528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    if (mLogFile != NULL) {
150628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        fwrite(packets->data(), 1, packets->size(), mLogFile);
150728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
150828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber#endif
150928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
151028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return OK;
151128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
151228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
151328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::packetizeQueuedAccessUnits() {
151428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    for (;;) {
151528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        bool gotMoreData = false;
151628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        for (size_t i = 0; i < mTracks.size(); ++i) {
151728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            size_t trackIndex = mTracks.keyAt(i);
151828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            const sp<Track> &track = mTracks.valueAt(i);
151928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
152028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            sp<ABuffer> accessUnit = track->dequeueAccessUnit();
152128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            if (accessUnit != NULL) {
152228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                status_t err = packetizeAccessUnit(trackIndex, accessUnit);
152328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
152428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                if (err != OK) {
152528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                    return err;
152628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                }
152728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
152828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber                gotMoreData = true;
152928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            }
153028e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
153128e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
153228e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        if (!gotMoreData) {
153328e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber            break;
153428e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber        }
153528e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    }
153628e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
153728e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber    return OK;
153828e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber}
153928e17ed7e2fbb254fb99481b74db85e427c905eeAndreas Huber
1540ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Hubervoid WifiDisplaySource::PlaybackSession::notifySessionDead() {
1541ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    // Inform WifiDisplaySource of our premature death (wish).
1542ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    sp<AMessage> notify = mNotify->dup();
1543ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->setInt32("what", kWhatSessionDead);
1544ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    notify->post();
1545ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1546ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber    mWeAreDead = true;
1547ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber}
1548ef7d3793fa9bbfb25253626ede9a020ee9280a17Andreas Huber
1549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
1550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1551