PlaybackSession.cpp revision 774df0dce0116c69b6d17f2e4a4912e06138e575
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"
24d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "RepeaterSource.h"
25d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "Serializer.h"
26d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "TSPacketizer.h"
27d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
28d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <binder/IServiceManager.h>
29d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/ISurfaceComposer.h>
30d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <gui/SurfaceComposerClient.h>
31d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
32d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/ADebug.h>
33d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/AMessage.h>
34d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/foundation/hexdump.h>
35d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/DataSource.h>
36d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaDefs.h>
37d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaErrors.h>
38d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaExtractor.h>
39d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MediaSource.h>
40d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MetaData.h>
41d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/MPEG2TSWriter.h>
42d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/SurfaceMediaSource.h>
43d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <media/stagefright/Utils.h>
44d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <ui/DisplayInfo.h>
45d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
46d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include <OMX_IVCommon.h>
47d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
48d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#define FAKE_VIDEO      0
49d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
50d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubernamespace android {
51d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
52d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxRTPPacketSize = 1500;
53d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
54d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
55d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstruct WifiDisplaySource::PlaybackSession::Track : public RefBase {
56d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    Track(const sp<Converter> &converter);
57d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    Track(const sp<AMessage> &format);
58d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
59d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> getFormat();
60d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
61d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<Converter> &converter() const;
62d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t packetizerTrackIndex() const;
63d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
64d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void setPacketizerTrackIndex(size_t index);
65d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
66d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprotected:
67d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    virtual ~Track();
68d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
69d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberprivate:
70d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> mConverter;
71d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> mFormat;
72d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t mPacketizerTrackIndex;
73d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
74d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DISALLOW_EVIL_CONSTRUCTORS(Track);
75d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber};
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
77d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::Track(const sp<Converter> &converter)
78d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mConverter(converter),
79d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mPacketizerTrackIndex(-1) {
80d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
81d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
82d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format)
83d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mFormat(format),
84d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mPacketizerTrackIndex(-1) {
85d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
86d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
87d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::Track::~Track() {
88d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
89d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
90d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubersp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
91d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mFormat != NULL) {
92d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return mFormat;
93d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
94d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
95d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter->getOutputFormat();
96d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
97d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
98d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
99d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mConverter;
100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mPacketizerTrackIndex;
104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_LT(mPacketizerTrackIndex, 0);
108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mPacketizerTrackIndex = index;
109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber////////////////////////////////////////////////////////////////////////////////
112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::PlaybackSession(
114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ANetworkSession> &netSession,
115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &notify)
116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    : mNetSession(netSession),
117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNotify(notify),
118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastLifesignUs(),
119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mPrevTimeUs(-1ll),
121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mUseInterleavedTCP(false),
122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPChannel(0),
123d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTCPChannel(0),
124d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPPort(0),
125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPSessionID(0),
126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTCPSessionID(0),
127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mRTPSeqNo(0),
128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastNTPTime(0),
129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mLastRTPTime(0),
130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumRTPSent(0),
131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumRTPOctetsSent(0),
132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mNumSRsSent(0),
133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mSendSRPending(false),
134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber      mFirstPacketTimeUs(-1ll),
135774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber      mHistoryLength(0)
136774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
137774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber      ,mLogFile(NULL)
138774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
139774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber{
140d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTSQueue->setRange(0, 12);
141774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
142774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
143774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    mLogFile = fopen("/system/etc/log.ts", "wb");
144774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::init(
148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bool useInterleavedTCP) {
150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = setupPacketizer();
151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (err != OK) {
153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return err;
154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (useInterleavedTCP) {
157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mUseInterleavedTCP = true;
158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPChannel = clientRtp;
159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTCPChannel = clientRtcp;
160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPPort = 0;
161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTPSessionID = 0;
162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mRTCPSessionID = 0;
163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        updateLiveness();
165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return OK;
166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
167d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mUseInterleavedTCP = false;
169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mRTPChannel = 0;
170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mRTCPChannel = 0;
171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int serverRtp;
173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    for (serverRtp = 15550;; serverRtp += 2) {
177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int32_t rtpSession;
178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mNetSession->createUDPSession(
179d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    serverRtp, clientIP, clientRtp,
180d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    rtpNotify, &rtpSession);
181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("failed to create RTP socket on port %d", serverRtp);
184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            continue;
185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (clientRtcp < 0) {
188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // No RTCP.
189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTPPort = serverRtp;
191d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTPSessionID = rtpSession;
192d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTCPSessionID = 0;
193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("rtpSessionId = %d", rtpSession);
195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int32_t rtcpSession;
199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mNetSession->createUDPSession(
200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                serverRtp + 1, clientIP, clientRtcp,
201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                rtcpNotify, &rtcpSession);
202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err == OK) {
204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTPPort = serverRtp;
205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTPSessionID = rtpSession;
206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mRTCPSessionID = rtcpSession;
207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNetSession->destroySession(rtpSession);
214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTPPort == 0) {
217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return UNKNOWN_ERROR;
218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas HuberWifiDisplaySource::PlaybackSession::~PlaybackSession() {
226774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
227774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    if (mLogFile != NULL) {
228774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber        fclose(mLogFile);
229774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber        mLogFile = NULL;
230774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber    }
231774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
232774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTracks.clear();
234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mCodecLooper != NULL) {
236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodecLooper->stop();
237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodecLooper.clear();
238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mPacketizer.clear();
241d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
242d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<IServiceManager> sm = defaultServiceManager();
243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(service != NULL);
246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
247d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mSerializer != NULL) {
248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mSerializer->stop();
249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        looper()->unregisterHandler(mSerializer->id());
251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mSerializer.clear();
252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mSerializerLooper != NULL) {
255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mSerializerLooper->stop();
256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mSerializerLooper.clear();
257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2592dff0f6a7bf06a878ad0890d93dc9c1ef0b5a107Andreas Huber    service->connectDisplay(NULL);
2602dff0f6a7bf06a878ad0890d93dc9c1ef0b5a107Andreas Huber
261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTCPSessionID != 0) {
262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNetSession->destroySession(mRTCPSessionID);
263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
264d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTPSessionID != 0) {
266d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNetSession->destroySession(mRTPSessionID);
267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mRTPPort;
272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberint64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mLastLifesignUs;
276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::updateLiveness() {
279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mLastLifesignUs = ALooper::GetNowUs();
280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::play() {
283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mRTCPSessionID != 0) {
286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        scheduleSendSR();
287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return mSerializer->start();
290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::pause() {
293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    updateLiveness();
294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onMessageReceived(
299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<AMessage> &msg) {
300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    switch (msg->what()) {
301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatRTPNotify:
302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatRTCPNotify:
303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t reason;
305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("reason", &reason));
306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            switch (reason) {
308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                case ANetworkSession::kWhatError:
309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                {
310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t sessionID;
311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t err;
314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("err", &err));
315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t errorOccuredDuringSend;
317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    AString detail;
320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findString("detail", &detail));
321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (msg->what() == kWhatRTPNotify
323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                            && !errorOccuredDuringSend) {
324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        // This is ok, we don't expect to receive anything on
325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        // the RTP socket.
326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        break;
327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
329d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGE("An error occurred during %s in session %d "
330d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          "(%d, '%s' (%s)).",
331d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          errorOccuredDuringSend ? "send" : "receive",
332d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          sessionID,
333d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          err,
334d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          detail.c_str(),
335d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                          strerror(-err));
336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mNetSession->destroySession(sessionID);
338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (sessionID == mRTPSessionID) {
340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mRTPSessionID = 0;
341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    } else if (sessionID == mRTCPSessionID) {
342d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mRTCPSessionID = 0;
343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    // Inform WifiDisplaySource of our premature death (wish).
346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<AMessage> notify = mNotify->dup();
347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    notify->setInt32("what", kWhatSessionDead);
348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    notify->post();
349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    break;
350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
352d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                case ANetworkSession::kWhatDatagram:
353d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                {
354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int32_t sessionID;
355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findInt32("sessionID", &sessionID));
356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<ABuffer> data;
358d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findBuffer("data", &data));
359d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    status_t err;
361d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (msg->what() == kWhatRTCPNotify) {
362d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        err = parseRTCP(data);
363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    break;
365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                default:
368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    TRESPASS();
369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatSendSR:
374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mSendSRPending = false;
376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (mRTCPSessionID == 0) {
378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            onSendSR();
382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            scheduleSendSR();
384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatSerializerNotify:
388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
390d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Serializer::kWhatEOS) {
393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGI("input eos");
394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                for (size_t i = 0; i < mTracks.size(); ++i) {
396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO
397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    msg->setInt32("what", Converter::kWhatEOS);
399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    msg->setSize("trackIndex", i);
400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    msg->post();
401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(i)->converter()->signalEOS();
403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Serializer::kWhatAccessUnit);
407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                size_t trackIndex;
409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findSize("trackIndex", &trackIndex));
410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<ABuffer> accessUnit;
412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findBuffer("accessUnit", &accessUnit));
413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
414d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO
415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                int64_t timeUs;
416d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
417d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
418d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                void *mbuf;
419d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(accessUnit->meta()->findPointer("mediaBuffer", &mbuf));
420d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
421d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ((MediaBuffer *)mbuf)->release();
422d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mbuf = NULL;
423d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
424d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                sp<AMessage> msg = new AMessage(kWhatConverterNotify, id());
425d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                msg->setInt32("what", Converter::kWhatAccessUnit);
426d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                msg->setSize("trackIndex", trackIndex);
427d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                msg->setBuffer("accessUnit", accessUnit);
428d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                msg->post();
429d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
430d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.valueFor(trackIndex)->converter()
431d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ->feedAccessUnit(accessUnit);
432d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
433d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
434d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
435d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
436d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
437d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        case kWhatConverterNotify:
438d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        {
439d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            int32_t what;
440d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findInt32("what", &what));
441d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
442d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t trackIndex;
443d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            CHECK(msg->findSize("trackIndex", &trackIndex));
444d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
445d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (what == Converter::kWhatAccessUnit) {
446d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Track> &track = mTracks.valueFor(trackIndex);
447d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
448d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                uint32_t flags = 0;
449d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
450d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
451d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (packetizerTrackIndex < 0) {
452d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    flags = TSPacketizer::EMIT_PAT_AND_PMT;
453d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
454d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    packetizerTrackIndex =
455d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mPacketizer->addTrack(track->getFormat());
456d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
457d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (packetizerTrackIndex >= 0) {
458d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        track->setPacketizerTrackIndex(packetizerTrackIndex);
459d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
460d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
461d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
462d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (packetizerTrackIndex >= 0) {
463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<ABuffer> accessUnit;
464d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    int64_t timeUs;
467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) {
470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        flags |= TSPacketizer::EMIT_PCR;
471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mPrevTimeUs = timeUs;
472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    sp<ABuffer> packets;
475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mPacketizer->packetize(
476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                            packetizerTrackIndex, accessUnit, &packets, flags);
477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    for (size_t offset = 0;
479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                            offset < packets->size(); offset += 188) {
480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        bool lastTSPacket = (offset + 188 >= packets->size());
481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        appendTSData(
483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                                packets->data() + offset,
484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                                188,
485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                                true /* timeDiscontinuity */,
486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                                lastTSPacket /* flush */);
487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    }
488774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber
489774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#if LOG_TRANSPORT_STREAM
490774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber                    if (mLogFile != NULL) {
491774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber                        fwrite(packets->data(), 1, packets->size(), mLogFile);
492774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber                    }
493774df0dce0116c69b6d17f2e4a4912e06138e575Andreas Huber#endif
494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else if (what == Converter::kWhatEOS) {
496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatEOS);
497d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
498d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGI("output EOS on track %d", trackIndex);
499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ssize_t index = mTracks.indexOfKey(trackIndex);
501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_GE(index, 0);
502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if !FAKE_VIDEO
504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                const sp<Converter> &converter =
505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mTracks.valueAt(index)->converter();
506d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                looper()->unregisterHandler(converter->id());
507d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
509d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mTracks.removeItemsAt(index);
510d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
511d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                if (mTracks.isEmpty()) {
512d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("Reached EOS");
513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                }
514d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            } else {
515d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK_EQ(what, Converter::kWhatError);
516d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                status_t err;
518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                CHECK(msg->findInt32("err", &err));
519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGE("converter signaled error %d", err);
521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            break;
523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        default:
526d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            TRESPASS();
527d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
528d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSerializerNotify, id());
532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSerializerLooper = new ALooper;
534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSerializerLooper->start();
535d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
536d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSerializer = new Serializer(
537d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO
538d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            true /* throttled */
539d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
540d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            false /* throttled */
541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
542d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            , msg);
543d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSerializerLooper->registerHandler(mSerializer);
544d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
545d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mPacketizer = new TSPacketizer;
546d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
547d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if FAKE_VIDEO
548d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DataSource::RegisterDefaultSniffers();
549d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
550d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<DataSource> dataSource =
551d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        DataSource::CreateFromURI(
552d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                "/system/etc/inception_1500.mp4");
553d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
554d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(dataSource != NULL);
555d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
556d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
557d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(extractor != NULL);
558d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
559d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool haveAudio = false;
560d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    bool haveVideo = false;
561d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    for (size_t i = 0; i < extractor->countTracks(); ++i) {
562d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<MetaData> meta = extractor->getTrackMetaData(i);
563d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
564d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const char *mime;
565d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK(meta->findCString(kKeyMIMEType, &mime));
566d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
567d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bool useTrack = false;
568d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (!strncasecmp(mime, "audio/", 6) && !haveAudio) {
569d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            useTrack = true;
570d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            haveAudio = true;
571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else if (!strncasecmp(mime, "video/", 6) && !haveVideo) {
572d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            useTrack = true;
573d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            haveVideo = true;
574d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
575d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
576d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (!useTrack) {
577d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            continue;
578d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
579d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
580d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<MediaSource> source = extractor->getTrack(i);
581d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
582d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ssize_t index = mSerializer->addSource(source);
583d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK_GE(index, 0);
584d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
585d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<AMessage> format;
586d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        status_t err = convertMetaDataToMessage(source->getFormat(), &format);
587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK_EQ(err, (status_t)OK);
588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mTracks.add(index, new Track(format));
590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
591d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(haveAudio || haveVideo);
592d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
593d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mCodecLooper = new ALooper;
594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mCodecLooper->start();
595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    DisplayInfo info;
597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    SurfaceComposerClient::getDisplayInfo(0, &info);
598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    // sp<SurfaceMediaSource> source = new SurfaceMediaSource(info.w, info.h);
600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<SurfaceMediaSource> source = new SurfaceMediaSource(720, 1280);
601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<IServiceManager> sm = defaultServiceManager();
603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<ISurfaceComposer> service = interface_cast<ISurfaceComposer>(binder);
605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK(service != NULL);
606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
607d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    service->connectDisplay(source->getBufferQueue());
608d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if 0
610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    {
611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("reading buffer");
612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK_EQ((status_t)OK, source->start());
614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        MediaBuffer *mbuf;
615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        CHECK_EQ((status_t)OK, source->read(&mbuf));
616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mbuf->release();
617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mbuf = NULL;
618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
619d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("got buffer");
620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
621d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
622d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if 0
624d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t index = mSerializer->addSource(source);
625d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ssize_t index = mSerializer->addSource(
627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            new RepeaterSource(source, 30.0 /* rateHz */));
628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_GE(index, 0);
631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> format;
633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(err, (status_t)OK);
635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    format->setInt32("store-metadata-in-buffers", true);
637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    format->setInt32(
639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            "color-format", OMX_COLOR_FormatAndroidOpaque);
640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<AMessage> notify = new AMessage(kWhatConverterNotify, id());
642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    notify->setSize("trackIndex", index);
643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<Converter> converter =
645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        new Converter(notify, mCodecLooper, format);
646d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
647d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    looper()->registerHandler(converter);
648d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
649d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTracks.add(index, new Track(converter));
650d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
651d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
652d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
655d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::scheduleSendSR() {
656d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mSendSRPending) {
657d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return;
658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mSendSRPending = true;
661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
662d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
664d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
665d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
666d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    // TODO: Use macros/utility functions to clean up all the bitshifts below.
668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[0] = 0x80 | 0;
670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[1] = 200;  // SR
671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[2] = 0;
672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[3] = 6;
673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[4] = kSourceID >> 24;
674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
676d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[7] = kSourceID & 0xff;
677d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[8] = mLastNTPTime >> (64 - 8);
679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
680d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[11] = (mLastNTPTime >> 32) & 0xff;
682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[12] = (mLastNTPTime >> 24) & 0xff;
683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[13] = (mLastNTPTime >> 16) & 0xff;
684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[14] = (mLastNTPTime >> 8) & 0xff;
685d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[15] = mLastNTPTime & 0xff;
686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
687d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[16] = (mLastRTPTime >> 24) & 0xff;
688d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[17] = (mLastRTPTime >> 16) & 0xff;
689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[18] = (mLastRTPTime >> 8) & 0xff;
690d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[19] = mLastRTPTime & 0xff;
691d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
692d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[20] = mNumRTPSent >> 24;
693d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[21] = (mNumRTPSent >> 16) & 0xff;
694d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[22] = (mNumRTPSent >> 8) & 0xff;
695d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[23] = mNumRTPSent & 0xff;
696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
697d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[24] = mNumRTPOctetsSent >> 24;
698d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
700d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[27] = mNumRTPOctetsSent & 0xff;
701d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + 28);
703d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint8_t *data = buffer->data() + buffer->size();
707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[0] = 0x80 | 1;
708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[1] = 202;  // SDES
709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[4] = kSourceID >> 24;
710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[5] = (kSourceID >> 16) & 0xff;
711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[6] = (kSourceID >> 8) & 0xff;
712d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[7] = kSourceID & 0xff;
713d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
714d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t offset = 8;
715d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 1;  // CNAME
717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    static const char *kCNAME = "someone@somewhere";
719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = strlen(kCNAME);
720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(&data[offset], kCNAME, strlen(kCNAME));
722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    offset += strlen(kCNAME);
723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 7;  // NOTE
725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    static const char *kNOTE = "Hell's frozen over.";
727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = strlen(kNOTE);
728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(&data[offset], kNOTE, strlen(kNOTE));
730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    offset += strlen(kNOTE);
731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[offset++] = 0;
733d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
734d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if ((offset % 4) > 0) {
735d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t count = 4 - (offset % 4);
736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        switch (count) {
737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 3:
738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 2:
740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 1:
742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                data[offset++] = 0;
743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t numWords = (offset / 4) - 1;
747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[2] = numWords >> 8;
748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    data[3] = numWords & 0xff;
749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(buffer->offset(), buffer->size() + offset);
751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
753d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber// static
754d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberuint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
755d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t nowUs = ALooper::GetNowUs();
756d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
757d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
758d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
759d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t hi = nowUs / 1000000ll;
760d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
761d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
762d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return (hi << 32) | lo;
763d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
765d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Hubervoid WifiDisplaySource::PlaybackSession::onSendSR() {
766d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    sp<ABuffer> buffer = new ABuffer(1500);
767d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    buffer->setRange(0, 0);
768d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
769d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    addSR(buffer);
770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    addSDES(buffer);
771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (mUseInterleavedTCP) {
773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        sp<AMessage> notify = mNotify->dup();
774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setInt32("what", kWhatBinaryData);
775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setInt32("channel", mRTCPChannel);
776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->setBuffer("data", buffer);
777d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        notify->post();
778d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    } else {
779d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNetSession->sendRequest(
780d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mRTCPSessionID, buffer->data(), buffer->size());
781d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
782d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    ++mNumSRsSent;
784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberssize_t WifiDisplaySource::PlaybackSession::appendTSData(
787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_EQ(size, 188);
789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    mTSQueue->setRange(0, mTSQueue->size() + size);
794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // flush
797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        int64_t nowUs = ALooper::GetNowUs();
799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (mFirstPacketTimeUs < 0ll) {
800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mFirstPacketTimeUs = nowUs;
801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
803d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // 90kHz time scale
804d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
805d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
806d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint8_t *rtp = mTSQueue->data();
807d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[0] = 0x80;
808d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
809d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
810d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[3] = mRTPSeqNo & 0xff;
811d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[4] = rtpTime >> 24;
812d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[5] = (rtpTime >> 16) & 0xff;
813d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[6] = (rtpTime >> 8) & 0xff;
814d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[7] = rtpTime & 0xff;
815d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[8] = kSourceID >> 24;
816d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[9] = (kSourceID >> 16) & 0xff;
817d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[10] = (kSourceID >> 8) & 0xff;
818d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        rtp[11] = kSourceID & 0xff;
819d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
820d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mRTPSeqNo;
821d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mNumRTPSent;
822d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mNumRTPOctetsSent += mTSQueue->size() - 12;
823d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
824d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLastRTPTime = rtpTime;
825d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mLastNTPTime = GetNowNTP();
826d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
827d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (mUseInterleavedTCP) {
828d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<AMessage> notify = mNotify->dup();
829d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("what", kWhatBinaryData);
830d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
831d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            sp<ABuffer> data = new ABuffer(mTSQueue->size());
832d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            memcpy(data->data(), rtp, mTSQueue->size());
833d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
834d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setInt32("channel", mRTPChannel);
835d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->setBuffer("data", data);
836d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            notify->post();
837d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
838d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mNetSession->sendRequest(
839d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    mRTPSessionID, rtp, mTSQueue->size());
840d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
841d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
842d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mTSQueue->setInt32Data(mRTPSeqNo - 1);
843d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mHistory.push_back(mTSQueue);
844d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ++mHistoryLength;
845d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
846d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (mHistoryLength > kMaxHistoryLength) {
847d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mTSQueue = *mHistory.begin();
848d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mHistory.erase(mHistory.begin());
849d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
850d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            --mHistoryLength;
851d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
853d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
854d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
855d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mTSQueue->setRange(0, 12);
856d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
857d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
858d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return size;
859d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
860d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
861d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseRTCP(
862d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const sp<ABuffer> &buffer) {
863d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const uint8_t *data = buffer->data();
864d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    size_t size = buffer->size();
865d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
866d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    while (size > 0) {
867d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (size < 8) {
868d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Too short to be a valid RTCP header
869d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_MALFORMED;
870d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
871d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
872d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if ((data[0] >> 6) != 2) {
873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Unsupported version.
874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_UNSUPPORTED;
875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (data[0] & 0x20) {
878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Padding present.
879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size_t paddingLength = data[size - 1];
881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (paddingLength + 12 > size) {
883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                // If we removed this much padding we'd end up with something
884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                // that's too short to be a valid RTP header.
885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                return ERROR_MALFORMED;
886d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
887d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            size -= paddingLength;
889d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
890d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
891d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
892d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
893d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (size < headerLength) {
894d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            // Only received a partial packet?
895d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return ERROR_MALFORMED;
896d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
897d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        switch (data[1]) {
899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 200:
900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 201:  // RR
901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 202:  // SDES
902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 203:
903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 204:  // APP
904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
905d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
906d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 205:  // TSFB (transport layer specific feedback)
907d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                parseTSFB(data, headerLength);
908d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
909d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
910d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            case 206:  // PSFB (payload specific feedback)
911d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                hexdump(data, headerLength);
912d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
913d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
914d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            default:
915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            {
916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ALOGW("Unknown RTCP packet type %u of size %d",
917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                     (unsigned)data[1], headerLength);
918d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
919d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
921d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
922d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        data += headerLength;
923d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        size -= headerLength;
924d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
925d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
926d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
927d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
928d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
929d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huberstatus_t WifiDisplaySource::PlaybackSession::parseTSFB(
930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        const uint8_t *data, size_t size) {
931d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if ((data[0] & 0x1f) != 1) {
932d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_UNSUPPORTED;  // We only support NACK for now.
933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t srcId = U32_AT(&data[8]);
936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (srcId != kSourceID) {
937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        return ERROR_MALFORMED;
938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    for (size_t i = 12; i < size; i += 4) {
941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint16_t seqNo = U16_AT(&data[i]);
942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        uint16_t blp = U16_AT(&data[i + 2]);
943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        List<sp<ABuffer> >::iterator it = mHistory.begin();
945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bool found = false;
946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        while (it != mHistory.end()) {
947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            const sp<ABuffer> &buffer = *it;
948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            if (bufferSeqNo == seqNo) {
952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mNetSession->sendRequest(
953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                        mRTPSessionID, buffer->data(), buffer->size());
954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                found = true;
956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                break;
957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            }
958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ++it;
960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (found) {
963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("retransmitting seqNo %d", seqNo);
964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        } else {
965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGI("seqNo %d no longer available", seqNo);
966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
968d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
969d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    return OK;
970d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}
971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber}  // namespace android
973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
974