PlaybackSession.cpp revision ea4bbfdcad9478ea19257fb19a32de68a2dfd958
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/*
2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright 2012, The Android Open Source Project
3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License.
6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at
7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *     http://www.apache.org/licenses/LICENSE-2.0
9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software
11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and
14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License.
15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */
16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat//#define LOG_NDEBUG 0
18fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#define LOG_TAG "PlaybackSession"
19f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <utils/Log.h>
20fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
21f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "PlaybackSession.h"
22a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
23a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "Converter.h"
24a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "MediaPuller.h"
25f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "RepeaterSource.h"
26f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "TSPacketizer.h"
27fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <binder/IServiceManager.h>
29ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include <gui/ISurfaceComposer.h>
30a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <gui/SurfaceComposerClient.h>
31a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/IHDCP.h>
32a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/foundation/ABuffer.h>
33a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/foundation/ADebug.h>
34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/AMessage.h>
35a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/foundation/hexdump.h>
36a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/AudioSource.h>
37a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/DataSource.h>
38f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/MediaDefs.h>
39a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/MediaErrors.h>
40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/MediaExtractor.h>
41dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat#include <media/stagefright/MediaSource.h>
42dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat#include <media/stagefright/MetaData.h>
43a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/MPEG2TSWriter.h>
44a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/SurfaceMediaSource.h>
45a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/Utils.h>
46a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
47a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <OMX_IVCommon.h>
48a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatnamespace android {
50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
51ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatstatic size_t kMaxRTPPacketSize = 1500;
52f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic size_t kMaxNumTSPacketsPerRTPPacket = (kMaxRTPPacketSize - 12) / 188;
53f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
54f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstruct WifiDisplaySource::PlaybackSession::Track : public RefBase {
55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    Track(const sp<ALooper> &pullLooper,
56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat          const sp<ALooper> &codecLooper,
57f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat          const sp<MediaPuller> &mediaPuller,
58f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat          const sp<Converter> &converter);
59ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat
60f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    Track(const sp<AMessage> &format);
61f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<AMessage> getFormat();
63f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    bool isAudio() const;
64a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
65a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    const sp<Converter> &converter() const;
66a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    ssize_t packetizerTrackIndex() const;
67a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
68a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    void setPacketizerTrackIndex(size_t index);
69a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
70a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    status_t start();
71a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    status_t stop();
72a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
73a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatprotected:
74a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    virtual ~Track();
75a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
76ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatprivate:
77fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    sp<ALooper> mPullLooper;
78f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<ALooper> mCodecLooper;
79fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    sp<MediaPuller> mMediaPuller;
80f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<Converter> mConverter;
81f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<AMessage> mFormat;
82fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    bool mStarted;
83fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    ssize_t mPacketizerTrackIndex;
84fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    bool mIsAudio;
85fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
86a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    static bool IsAudioFormat(const sp<AMessage> &format);
87a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
88a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    DISALLOW_EVIL_CONSTRUCTORS(Track);
89a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat};
90a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
91a2677e4ad01f250b0765f04adf0acfa6627efc98San MehatWifiDisplaySource::PlaybackSession::Track::Track(
92a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<ALooper> &pullLooper,
93a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<ALooper> &codecLooper,
94a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<MediaPuller> &mediaPuller,
9597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat        const sp<Converter> &converter)
96a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    : mPullLooper(pullLooper),
97a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mCodecLooper(codecLooper),
98a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mMediaPuller(mediaPuller),
99fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat      mConverter(converter),
100a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mStarted(false),
101fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat      mPacketizerTrackIndex(-1),
102a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) {
103a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
104a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
105a2677e4ad01f250b0765f04adf0acfa6627efc98San MehatWifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format)
106a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    : mFormat(format),
107fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat      mPacketizerTrackIndex(-1),
108a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mIsAudio(IsAudioFormat(mFormat)) {
109a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
110a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
111a2677e4ad01f250b0765f04adf0acfa6627efc98San MehatWifiDisplaySource::PlaybackSession::Track::~Track() {
112a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    stop();
113a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
114a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
115a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat// static
11697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatbool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
117f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        const sp<AMessage> &format) {
118fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    AString mime;
119f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    CHECK(format->findString("mime", &mime));
120f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
121f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    return !strncasecmp(mime.c_str(), "audio/", 6);
122f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
123f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
124f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatsp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
125fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    if (mFormat != NULL) {
126ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat        return mFormat;
127da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    }
128da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root
1297b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    return mConverter->getOutputFormat();
1307b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat}
1317b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat
1327b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehatbool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
1337b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    return mIsAudio;
13497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat}
1357b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat
1367b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehatconst sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
1377b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    return mConverter;
138a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
139fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
140fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehatssize_t WifiDisplaySource::PlaybackSession::Track::packetizerTrackIndex() const {
141fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    return mPacketizerTrackIndex;
14259abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat}
143fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
144fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehatvoid WifiDisplaySource::PlaybackSession::Track::setPacketizerTrackIndex(size_t index) {
145fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    CHECK_LT(mPacketizerTrackIndex, 0);
146fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    mPacketizerTrackIndex = index;
147fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat}
148a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
14997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehatstatus_t WifiDisplaySource::PlaybackSession::Track::start() {
150a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (mStarted) {
151fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat        return INVALID_OPERATION;
152fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    }
153a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
15497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    status_t err = OK;
155fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat
156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (mMediaPuller != NULL) {
157fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat        err = mMediaPuller->start();
158fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    }
159a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
160a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (err == OK) {
161a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mStarted = true;
162a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
163a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
164fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    return err;
165fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat}
166ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat
167da62e7c00259f6b98696cedb7d031f04951caef0Kenny Rootstatus_t WifiDisplaySource::PlaybackSession::Track::stop() {
168da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    if (!mStarted) {
1697b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat        return INVALID_OPERATION;
1707b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    }
1717b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat
1727b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    status_t err = OK;
1737b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat
1747b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    if (mMediaPuller != NULL) {
1757b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat        err = mMediaPuller->stop();
1767b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    }
17797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat
1787b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat    mConverter.clear();
1797b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat
18059abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat    mStarted = false;
1812a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat
1822a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat    return err;
1832a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat}
1842a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat
185dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat////////////////////////////////////////////////////////////////////////////////
18697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat
187dd9b8e92aaf330b48ddb40a7380588ef92b53de6San MehatWifiDisplaySource::PlaybackSession::PlaybackSession(
188dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat        const sp<ANetworkSession> &netSession,
189a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<AMessage> &notify,
19097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat        const in_addr &interfaceAddr,
191a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<IHDCP> &hdcp)
192dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat    : mNetSession(netSession),
193dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat      mNotify(notify),
19459abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat      mInterfaceAddr(interfaceAddr),
19559abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat      mHDCP(hdcp),
196a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mLastLifesignUs(),
19797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat      mVideoTrackIndex(-1),
198a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
1992a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat      mPrevTimeUs(-1ll),
2002a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat      mTransportMode(TRANSPORT_UDP),
2012a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat      mRTPChannel(0),
20259abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat      mRTCPChannel(0),
203a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTPPort(0),
20497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat      mRTPSessionID(0),
205a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTCPSessionID(0),
206a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#if ENABLE_RETRANSMISSION
207a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTPRetransmissionSessionID(0),
208a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTCPRetransmissionSessionID(0),
209a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif
210da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root      mClientRTPPort(0),
211da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root      mClientRTCPPort(0),
212a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTPConnected(false),
213a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTCPConnected(false),
214a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTPSeqNo(0),
215a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#if ENABLE_RETRANSMISSION
216a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mRTPRetransmissionSeqNo(0),
21797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat#endif
2187b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mLastNTPTime(0),
2197b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mLastRTPTime(0),
2207b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mNumRTPSent(0),
2217b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mNumRTPOctetsSent(0),
22297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat      mNumSRsSent(0),
2237b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mSendSRPending(false),
2247b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mFirstPacketTimeUs(-1ll),
2257b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat      mHistoryLength(0),
226a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      mTotalBytesSent(0ll)
227a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#if LOG_TRANSPORT_STREAM
228a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat      ,mLogFile(NULL)
229a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif
230a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat{
231a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    mTSQueue->setRange(0, 12);
232a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
2332a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat#if LOG_TRANSPORT_STREAM
2342a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat    mLogFile = fopen("/system/etc/log.ts", "wb");
2352a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat#endif
2362a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat}
2372a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat
2382a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehatstatus_t WifiDisplaySource::PlaybackSession::init(
23959abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat        const char *clientIP, int32_t clientRtp, int32_t clientRtcp,
240a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        TransportMode transportMode) {
241a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    mClientIP = clientIP;
242a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
243da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    status_t err = setupPacketizer();
244da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root
24597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    if (err != OK) {
246fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat        return err;
247fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    }
248ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat
249da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    mTransportMode = transportMode;
250da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root
251a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (transportMode == TRANSPORT_TCP_INTERLEAVED) {
252a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTPChannel = clientRtp;
25397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat        mRTCPChannel = clientRtcp;
254a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTPPort = 0;
255a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTPSessionID = 0;
256a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTCPSessionID = 0;
257a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
258a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        updateLiveness();
259fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat        return OK;
260fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    }
261ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat
262da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    mRTPChannel = 0;
263da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root    mRTCPChannel = 0;
264a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
265a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (mTransportMode == TRANSPORT_TCP) {
26697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat        // XXX This is wrong, we need to allocate sockets here, we only
267a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        // need to do this because the dongles are not establishing their
268a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        // end until after PLAY instead of before SETUP.
269a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTPPort = 20000;
270a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTPSessionID = 0;
271a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mRTCPSessionID = 0;
272a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mClientRTPPort = clientRtp;
273a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        mClientRTCPPort = clientRtcp;
274a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
275a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        updateLiveness();
276a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        return OK;
277a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
278a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
279a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    int serverRtp;
280a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
281a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
282a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
283a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
284a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#if ENABLE_RETRANSMISSION
285a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> rtpRetransmissionNotify =
286a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        new AMessage(kWhatRTPRetransmissionNotify, id());
2874ba8948dc16463053e21cda5744f519a555080d0San Mehat
28897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    sp<AMessage> rtcpRetransmissionNotify =
289a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        new AMessage(kWhatRTCPRetransmissionNotify, id());
290a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif
291a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
29297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat    for (serverRtp = 15550;; serverRtp += 2) {
293a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        int32_t rtpSession;
294a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        if (mTransportMode == TRANSPORT_UDP) {
295fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat            err = mNetSession->createUDPSession(
29649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        serverRtp, clientIP, clientRtp,
297dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat                        rtpNotify, &rtpSession);
298a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        } else {
299dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat            err = mNetSession->createTCPDatagramSession(
300a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        serverRtp, clientIP, clientRtp,
301dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat                        rtpNotify, &rtpSession);
302dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat        }
303a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
304dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat        if (err != OK) {
305a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            ALOGI("failed to create RTP socket on port %d", serverRtp);
306a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            continue;
307dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat        }
308dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat
309a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        int32_t rtcpSession = 0;
310a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
311a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        if (clientRtcp >= 0) {
312a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            if (mTransportMode == TRANSPORT_UDP) {
313a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                err = mNetSession->createUDPSession(
314a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        serverRtp + 1, clientIP, clientRtcp,
315a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        rtcpNotify, &rtcpSession);
316dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat            } else {
317a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                err = mNetSession->createTCPDatagramSession(
318a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        serverRtp + 1, clientIP, clientRtcp,
31949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        rtcpNotify, &rtcpSession);
320            }
321
322            if (err != OK) {
323                ALOGI("failed to create RTCP socket on port %d", serverRtp + 1);
324
325                mNetSession->destroySession(rtpSession);
326                continue;
327            }
328        }
329
330#if ENABLE_RETRANSMISSION
331        if (mTransportMode == TRANSPORT_UDP) {
332            int32_t rtpRetransmissionSession;
333
334            err = mNetSession->createUDPSession(
335                        serverRtp + kRetransmissionPortOffset,
336                        clientIP,
337                        clientRtp + kRetransmissionPortOffset,
338                        rtpRetransmissionNotify,
339                        &rtpRetransmissionSession);
340
341            if (err != OK) {
342                mNetSession->destroySession(rtcpSession);
343                mNetSession->destroySession(rtpSession);
344                continue;
345            }
346
347            CHECK_GE(clientRtcp, 0);
348
349            int32_t rtcpRetransmissionSession;
350            err = mNetSession->createUDPSession(
351                        serverRtp + 1 + kRetransmissionPortOffset,
352                        clientIP,
353                        clientRtp + 1 + kRetransmissionPortOffset,
354                        rtcpRetransmissionNotify,
355                        &rtcpRetransmissionSession);
356
357            if (err != OK) {
358                mNetSession->destroySession(rtpRetransmissionSession);
359                mNetSession->destroySession(rtcpSession);
360                mNetSession->destroySession(rtpSession);
361                continue;
362            }
363
364            mRTPRetransmissionSessionID = rtpRetransmissionSession;
365            mRTCPRetransmissionSessionID = rtcpRetransmissionSession;
366
367            ALOGI("rtpRetransmissionSessionID = %d, "
368                  "rtcpRetransmissionSessionID = %d",
369                  rtpRetransmissionSession, rtcpRetransmissionSession);
370        }
371#endif
372
373        mRTPPort = serverRtp;
374        mRTPSessionID = rtpSession;
375        mRTCPSessionID = rtcpSession;
376
377        ALOGI("rtpSessionID = %d, rtcpSessionID = %d", rtpSession, rtcpSession);
378        break;
379    }
380
381    if (mRTPPort == 0) {
382        return UNKNOWN_ERROR;
383    }
384
385    updateLiveness();
386
387    return OK;
388}
389
390WifiDisplaySource::PlaybackSession::~PlaybackSession() {
391#if LOG_TRANSPORT_STREAM
392    if (mLogFile != NULL) {
393        fclose(mLogFile);
394        mLogFile = NULL;
395    }
396#endif
397}
398
399int32_t WifiDisplaySource::PlaybackSession::getRTPPort() const {
400    return mRTPPort;
401}
402
403int64_t WifiDisplaySource::PlaybackSession::getLastLifesignUs() const {
404    return mLastLifesignUs;
405}
406
407void WifiDisplaySource::PlaybackSession::updateLiveness() {
408    mLastLifesignUs = ALooper::GetNowUs();
409}
410
411status_t WifiDisplaySource::PlaybackSession::play() {
412    updateLiveness();
413
414    return OK;
415}
416
417status_t WifiDisplaySource::PlaybackSession::finishPlay() {
418    // XXX Give the dongle 3 secs to bind its sockets.
419    (new AMessage(kWhatFinishPlay, id()))->post(3000000ll);
420    return OK;
421}
422
423status_t WifiDisplaySource::PlaybackSession::onFinishPlay() {
424    if (mTransportMode != TRANSPORT_TCP) {
425        return onFinishPlay2();
426    }
427
428    sp<AMessage> rtpNotify = new AMessage(kWhatRTPNotify, id());
429
430    status_t err = mNetSession->createTCPDatagramSession(
431                mRTPPort, mClientIP.c_str(), mClientRTPPort,
432                rtpNotify, &mRTPSessionID);
433
434    if (err != OK) {
435        return err;
436    }
437
438    if (mClientRTCPPort >= 0) {
439        sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
440
441        err = mNetSession->createTCPDatagramSession(
442                mRTPPort + 1, mClientIP.c_str(), mClientRTCPPort,
443                rtcpNotify, &mRTCPSessionID);
444    }
445
446    return err;
447}
448
449status_t WifiDisplaySource::PlaybackSession::onFinishPlay2() {
450    if (mRTCPSessionID != 0) {
451        scheduleSendSR();
452    }
453
454    for (size_t i = 0; i < mTracks.size(); ++i) {
455        status_t err = mTracks.editValueAt(i)->start();
456
457        if (err != OK) {
458            for (size_t j = 0; j < i; ++j) {
459                mTracks.editValueAt(j)->stop();
460            }
461
462            return err;
463        }
464    }
465
466    sp<AMessage> notify = mNotify->dup();
467    notify->setInt32("what", kWhatSessionEstablished);
468    notify->post();
469
470    return OK;
471}
472
473status_t WifiDisplaySource::PlaybackSession::pause() {
474    updateLiveness();
475
476    return OK;
477}
478
479status_t WifiDisplaySource::PlaybackSession::destroy() {
480    mTracks.clear();
481
482    mPacketizer.clear();
483
484    mTracks.clear();
485
486#if ENABLE_RETRANSMISSION
487    if (mRTCPRetransmissionSessionID != 0) {
488        mNetSession->destroySession(mRTCPRetransmissionSessionID);
489    }
490
491    if (mRTPRetransmissionSessionID != 0) {
492        mNetSession->destroySession(mRTPRetransmissionSessionID);
493    }
494#endif
495
496    if (mRTCPSessionID != 0) {
497        mNetSession->destroySession(mRTCPSessionID);
498    }
499
500    if (mRTPSessionID != 0) {
501        mNetSession->destroySession(mRTPSessionID);
502    }
503
504    return OK;
505}
506
507void WifiDisplaySource::PlaybackSession::onMessageReceived(
508        const sp<AMessage> &msg) {
509    switch (msg->what()) {
510        case kWhatRTPNotify:
511        case kWhatRTCPNotify:
512#if ENABLE_RETRANSMISSION
513        case kWhatRTPRetransmissionNotify:
514        case kWhatRTCPRetransmissionNotify:
515#endif
516        {
517            int32_t reason;
518            CHECK(msg->findInt32("reason", &reason));
519
520            switch (reason) {
521                case ANetworkSession::kWhatError:
522                {
523                    int32_t sessionID;
524                    CHECK(msg->findInt32("sessionID", &sessionID));
525
526                    int32_t err;
527                    CHECK(msg->findInt32("err", &err));
528
529                    int32_t errorOccuredDuringSend;
530                    CHECK(msg->findInt32("send", &errorOccuredDuringSend));
531
532                    AString detail;
533                    CHECK(msg->findString("detail", &detail));
534
535                    if ((msg->what() == kWhatRTPNotify
536#if ENABLE_RETRANSMISSION
537                            || msg->what() == kWhatRTPRetransmissionNotify
538#endif
539                        ) && !errorOccuredDuringSend) {
540                        // This is ok, we don't expect to receive anything on
541                        // the RTP socket.
542                        break;
543                    }
544
545                    ALOGE("An error occurred during %s in session %d "
546                          "(%d, '%s' (%s)).",
547                          errorOccuredDuringSend ? "send" : "receive",
548                          sessionID,
549                          err,
550                          detail.c_str(),
551                          strerror(-err));
552
553                    mNetSession->destroySession(sessionID);
554
555                    if (sessionID == mRTPSessionID) {
556                        mRTPSessionID = 0;
557                    } else if (sessionID == mRTCPSessionID) {
558                        mRTCPSessionID = 0;
559                    }
560#if ENABLE_RETRANSMISSION
561                    else if (sessionID == mRTPRetransmissionSessionID) {
562                        mRTPRetransmissionSessionID = 0;
563                    } else if (sessionID == mRTCPRetransmissionSessionID) {
564                        mRTCPRetransmissionSessionID = 0;
565                    }
566#endif
567
568                    // Inform WifiDisplaySource of our premature death (wish).
569                    sp<AMessage> notify = mNotify->dup();
570                    notify->setInt32("what", kWhatSessionDead);
571                    notify->post();
572                    break;
573                }
574
575                case ANetworkSession::kWhatDatagram:
576                {
577                    int32_t sessionID;
578                    CHECK(msg->findInt32("sessionID", &sessionID));
579
580                    sp<ABuffer> data;
581                    CHECK(msg->findBuffer("data", &data));
582
583                    status_t err;
584                    if (msg->what() == kWhatRTCPNotify
585#if ENABLE_RETRANSMISSION
586                            || msg->what() == kWhatRTCPRetransmissionNotify
587#endif
588                       )
589                    {
590                        err = parseRTCP(data);
591                    }
592                    break;
593                }
594
595                case ANetworkSession::kWhatConnected:
596                {
597                    CHECK_EQ(mTransportMode, TRANSPORT_TCP);
598
599                    int32_t sessionID;
600                    CHECK(msg->findInt32("sessionID", &sessionID));
601
602                    if (sessionID == mRTPSessionID) {
603                        CHECK(!mRTPConnected);
604                        mRTPConnected = true;
605                        ALOGI("RTP Session now connected.");
606                    } else if (sessionID == mRTCPSessionID) {
607                        CHECK(!mRTCPConnected);
608                        mRTCPConnected = true;
609                        ALOGI("RTCP Session now connected.");
610                    } else {
611                        TRESPASS();
612                    }
613
614                    if (mRTPConnected
615                            && (mClientRTCPPort < 0 || mRTCPConnected)) {
616                        onFinishPlay2();
617                    }
618                    break;
619                }
620
621                default:
622                    TRESPASS();
623            }
624            break;
625        }
626
627        case kWhatSendSR:
628        {
629            mSendSRPending = false;
630
631            if (mRTCPSessionID == 0) {
632                break;
633            }
634
635            onSendSR();
636
637            scheduleSendSR();
638            break;
639        }
640
641        case kWhatMediaPullerNotify:
642        {
643            int32_t what;
644            CHECK(msg->findInt32("what", &what));
645
646            if (what == MediaPuller::kWhatEOS) {
647                ALOGI("input eos");
648
649                for (size_t i = 0; i < mTracks.size(); ++i) {
650                    mTracks.valueAt(i)->converter()->signalEOS();
651                }
652            } else {
653                CHECK_EQ(what, MediaPuller::kWhatAccessUnit);
654
655                size_t trackIndex;
656                CHECK(msg->findSize("trackIndex", &trackIndex));
657
658                sp<ABuffer> accessUnit;
659                CHECK(msg->findBuffer("accessUnit", &accessUnit));
660
661                mTracks.valueFor(trackIndex)->converter()
662                    ->feedAccessUnit(accessUnit);
663            }
664            break;
665        }
666
667        case kWhatConverterNotify:
668        {
669            int32_t what;
670            CHECK(msg->findInt32("what", &what));
671
672            size_t trackIndex;
673            CHECK(msg->findSize("trackIndex", &trackIndex));
674
675            if (what == Converter::kWhatAccessUnit) {
676                const sp<Track> &track = mTracks.valueFor(trackIndex);
677
678                uint32_t flags = 0;
679
680                ssize_t packetizerTrackIndex = track->packetizerTrackIndex();
681                if (packetizerTrackIndex < 0) {
682                    flags = TSPacketizer::EMIT_PAT_AND_PMT;
683
684                    packetizerTrackIndex =
685                        mPacketizer->addTrack(track->getFormat());
686
687                    if (packetizerTrackIndex >= 0) {
688                        track->setPacketizerTrackIndex(packetizerTrackIndex);
689                    }
690                }
691
692                if (packetizerTrackIndex >= 0) {
693                    sp<ABuffer> accessUnit;
694                    CHECK(msg->findBuffer("accessUnit", &accessUnit));
695
696                    bool isHDCPEncrypted = false;
697                    uint64_t inputCTR;
698                    uint8_t HDCP_private_data[16];
699                    if (mHDCP != NULL && !track->isAudio()) {
700                        isHDCPEncrypted = true;
701
702                        status_t err = mHDCP->encrypt(
703                                accessUnit->data(), accessUnit->size(),
704                                trackIndex  /* streamCTR */,
705                                &inputCTR,
706                                accessUnit->data());
707
708                        if (err != OK) {
709                            ALOGI("Failed to HDCP-encrypt media data (err %d)",
710                                  err);
711
712                            // Inform WifiDisplaySource of our premature death
713                            // (wish).
714                            sp<AMessage> notify = mNotify->dup();
715                            notify->setInt32("what", kWhatSessionDead);
716                            notify->post();
717                            break;
718                        }
719
720                        HDCP_private_data[0] = 0x00;
721
722                        HDCP_private_data[1] =
723                            (((trackIndex >> 30) & 3) << 1) | 1;
724
725                        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;
726
727                        HDCP_private_data[3] =
728                            (((trackIndex >> 15) & 0x7f) << 1) | 1;
729
730                        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;
731
732                        HDCP_private_data[5] =
733                            ((trackIndex & 0x7f) << 1) | 1;
734
735                        HDCP_private_data[6] = 0x00;
736
737                        HDCP_private_data[7] =
738                            (((inputCTR >> 60) & 0x0f) << 1) | 1;
739
740                        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;
741
742                        HDCP_private_data[9] =
743                            (((inputCTR >> 45) & 0x7f) << 1) | 1;
744
745                        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;
746
747                        HDCP_private_data[11] =
748                            (((inputCTR >> 30) & 0x7f) << 1) | 1;
749
750                        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;
751
752                        HDCP_private_data[13] =
753                            (((inputCTR >> 15) & 0x7f) << 1) | 1;
754
755                        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;
756
757                        HDCP_private_data[15] =
758                            ((inputCTR & 0x7f) << 1) | 1;
759
760                        flags |= TSPacketizer::IS_ENCRYPTED;
761                    }
762
763                    int64_t timeUs;
764                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
765
766                    if (mPrevTimeUs < 0ll || mPrevTimeUs + 100000ll >= timeUs) {
767                        flags |= TSPacketizer::EMIT_PCR;
768                        mPrevTimeUs = timeUs;
769                    }
770
771                    sp<ABuffer> packets;
772                    mPacketizer->packetize(
773                            packetizerTrackIndex, accessUnit, &packets, flags,
774                            isHDCPEncrypted ? NULL : HDCP_private_data,
775                            isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));
776
777                    for (size_t offset = 0;
778                            offset < packets->size(); offset += 188) {
779                        bool lastTSPacket = (offset + 188 >= packets->size());
780
781                        // We're only going to flush video, audio packets are
782                        // much more frequent and would waste all that space
783                        // available in a full sized UDP packet.
784                        bool flush =
785                            lastTSPacket
786                                && ((ssize_t)trackIndex == mVideoTrackIndex);
787
788                        appendTSData(
789                                packets->data() + offset,
790                                188,
791                                true /* timeDiscontinuity */,
792                                flush);
793                    }
794
795#if LOG_TRANSPORT_STREAM
796                    if (mLogFile != NULL) {
797                        fwrite(packets->data(), 1, packets->size(), mLogFile);
798                    }
799#endif
800                }
801            } else if (what == Converter::kWhatEOS) {
802                CHECK_EQ(what, Converter::kWhatEOS);
803
804                ALOGI("output EOS on track %d", trackIndex);
805
806                ssize_t index = mTracks.indexOfKey(trackIndex);
807                CHECK_GE(index, 0);
808
809                const sp<Converter> &converter =
810                    mTracks.valueAt(index)->converter();
811                looper()->unregisterHandler(converter->id());
812
813                mTracks.removeItemsAt(index);
814
815                if (mTracks.isEmpty()) {
816                    ALOGI("Reached EOS");
817                }
818            } else {
819                CHECK_EQ(what, Converter::kWhatError);
820
821                status_t err;
822                CHECK(msg->findInt32("err", &err));
823
824                ALOGE("converter signaled error %d", err);
825
826                // Inform WifiDisplaySource of our premature death (wish).
827                sp<AMessage> notify = mNotify->dup();
828                notify->setInt32("what", kWhatSessionDead);
829                notify->post();
830            }
831            break;
832        }
833
834        case kWhatFinishPlay:
835        {
836            onFinishPlay();
837            break;
838        }
839
840        default:
841            TRESPASS();
842    }
843}
844
845status_t WifiDisplaySource::PlaybackSession::setupPacketizer() {
846    mPacketizer = new TSPacketizer;
847
848    status_t err = addVideoSource();
849
850    if (err != OK) {
851        return err;
852    }
853
854    return addAudioSource();
855}
856
857status_t WifiDisplaySource::PlaybackSession::addSource(
858        bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) {
859    sp<ALooper> pullLooper = new ALooper;
860    pullLooper->setName("pull_looper");
861
862    pullLooper->start(
863            false /* runOnCallingThread */,
864            false /* canCallJava */,
865            PRIORITY_AUDIO);
866
867    sp<ALooper> codecLooper = new ALooper;
868    codecLooper->setName("codec_looper");
869
870    codecLooper->start(
871            false /* runOnCallingThread */,
872            false /* canCallJava */,
873            PRIORITY_AUDIO);
874
875    size_t trackIndex;
876
877    sp<AMessage> notify;
878
879    trackIndex = mTracks.size();
880
881    notify = new AMessage(kWhatMediaPullerNotify, id());
882    notify->setSize("trackIndex", trackIndex);
883    sp<MediaPuller> puller = new MediaPuller(source, notify);
884    pullLooper->registerHandler(puller);
885
886    sp<AMessage> format;
887    status_t err = convertMetaDataToMessage(source->getFormat(), &format);
888    CHECK_EQ(err, (status_t)OK);
889
890    if (isVideo) {
891        format->setInt32("store-metadata-in-buffers", true);
892
893        format->setInt32(
894                "color-format", OMX_COLOR_FormatAndroidOpaque);
895    }
896
897    notify = new AMessage(kWhatConverterNotify, id());
898    notify->setSize("trackIndex", trackIndex);
899
900    sp<Converter> converter =
901        new Converter(notify, codecLooper, format);
902    CHECK_EQ(converter->initCheck(), (status_t)OK);
903
904    looper()->registerHandler(converter);
905
906    if (numInputBuffers != NULL) {
907        *numInputBuffers = converter->getInputBufferCount();
908    }
909
910    mTracks.add(trackIndex, new Track(pullLooper, codecLooper, puller, converter));
911
912    if (isVideo) {
913        mVideoTrackIndex = trackIndex;
914    }
915
916    return OK;
917}
918
919status_t WifiDisplaySource::PlaybackSession::addVideoSource() {
920    sp<SurfaceMediaSource> source = new SurfaceMediaSource(width(), height());
921
922    sp<MediaSource> videoSource =
923            new RepeaterSource(source, 30.0 /* rateHz */);
924
925    size_t numInputBuffers;
926    status_t err = addSource(true /* isVideo */, videoSource, &numInputBuffers);
927
928    if (err != OK) {
929        return err;
930    }
931
932    err = source->setMaxAcquiredBufferCount(numInputBuffers);
933    CHECK_EQ(err, (status_t)OK);
934
935    mBufferQueue = source->getBufferQueue();
936
937    return OK;
938}
939
940status_t WifiDisplaySource::PlaybackSession::addAudioSource() {
941    sp<AudioSource> audioSource = new AudioSource(
942            AUDIO_SOURCE_REMOTE_SUBMIX,
943            48000 /* sampleRate */,
944            2 /* channelCount */);
945
946    if (audioSource->initCheck() == OK) {
947        audioSource->setUseLooperTime(true);
948
949        return addSource(
950                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
951    }
952
953    ALOGW("Unable to instantiate audio source");
954
955    return OK;
956}
957
958sp<ISurfaceTexture> WifiDisplaySource::PlaybackSession::getSurfaceTexture() {
959    return mBufferQueue;
960}
961
962int32_t WifiDisplaySource::PlaybackSession::width() const {
963    return 1280;
964}
965
966int32_t WifiDisplaySource::PlaybackSession::height() const {
967    return 720;
968}
969
970void WifiDisplaySource::PlaybackSession::scheduleSendSR() {
971    if (mSendSRPending) {
972        return;
973    }
974
975    mSendSRPending = true;
976    (new AMessage(kWhatSendSR, id()))->post(kSendSRIntervalUs);
977}
978
979void WifiDisplaySource::PlaybackSession::addSR(const sp<ABuffer> &buffer) {
980    uint8_t *data = buffer->data() + buffer->size();
981
982    // TODO: Use macros/utility functions to clean up all the bitshifts below.
983
984    data[0] = 0x80 | 0;
985    data[1] = 200;  // SR
986    data[2] = 0;
987    data[3] = 6;
988    data[4] = kSourceID >> 24;
989    data[5] = (kSourceID >> 16) & 0xff;
990    data[6] = (kSourceID >> 8) & 0xff;
991    data[7] = kSourceID & 0xff;
992
993    data[8] = mLastNTPTime >> (64 - 8);
994    data[9] = (mLastNTPTime >> (64 - 16)) & 0xff;
995    data[10] = (mLastNTPTime >> (64 - 24)) & 0xff;
996    data[11] = (mLastNTPTime >> 32) & 0xff;
997    data[12] = (mLastNTPTime >> 24) & 0xff;
998    data[13] = (mLastNTPTime >> 16) & 0xff;
999    data[14] = (mLastNTPTime >> 8) & 0xff;
1000    data[15] = mLastNTPTime & 0xff;
1001
1002    data[16] = (mLastRTPTime >> 24) & 0xff;
1003    data[17] = (mLastRTPTime >> 16) & 0xff;
1004    data[18] = (mLastRTPTime >> 8) & 0xff;
1005    data[19] = mLastRTPTime & 0xff;
1006
1007    data[20] = mNumRTPSent >> 24;
1008    data[21] = (mNumRTPSent >> 16) & 0xff;
1009    data[22] = (mNumRTPSent >> 8) & 0xff;
1010    data[23] = mNumRTPSent & 0xff;
1011
1012    data[24] = mNumRTPOctetsSent >> 24;
1013    data[25] = (mNumRTPOctetsSent >> 16) & 0xff;
1014    data[26] = (mNumRTPOctetsSent >> 8) & 0xff;
1015    data[27] = mNumRTPOctetsSent & 0xff;
1016
1017    buffer->setRange(buffer->offset(), buffer->size() + 28);
1018}
1019
1020void WifiDisplaySource::PlaybackSession::addSDES(const sp<ABuffer> &buffer) {
1021    uint8_t *data = buffer->data() + buffer->size();
1022    data[0] = 0x80 | 1;
1023    data[1] = 202;  // SDES
1024    data[4] = kSourceID >> 24;
1025    data[5] = (kSourceID >> 16) & 0xff;
1026    data[6] = (kSourceID >> 8) & 0xff;
1027    data[7] = kSourceID & 0xff;
1028
1029    size_t offset = 8;
1030
1031    data[offset++] = 1;  // CNAME
1032
1033    static const char *kCNAME = "someone@somewhere";
1034    data[offset++] = strlen(kCNAME);
1035
1036    memcpy(&data[offset], kCNAME, strlen(kCNAME));
1037    offset += strlen(kCNAME);
1038
1039    data[offset++] = 7;  // NOTE
1040
1041    static const char *kNOTE = "Hell's frozen over.";
1042    data[offset++] = strlen(kNOTE);
1043
1044    memcpy(&data[offset], kNOTE, strlen(kNOTE));
1045    offset += strlen(kNOTE);
1046
1047    data[offset++] = 0;
1048
1049    if ((offset % 4) > 0) {
1050        size_t count = 4 - (offset % 4);
1051        switch (count) {
1052            case 3:
1053                data[offset++] = 0;
1054            case 2:
1055                data[offset++] = 0;
1056            case 1:
1057                data[offset++] = 0;
1058        }
1059    }
1060
1061    size_t numWords = (offset / 4) - 1;
1062    data[2] = numWords >> 8;
1063    data[3] = numWords & 0xff;
1064
1065    buffer->setRange(buffer->offset(), buffer->size() + offset);
1066}
1067
1068// static
1069uint64_t WifiDisplaySource::PlaybackSession::GetNowNTP() {
1070    uint64_t nowUs = ALooper::GetNowUs();
1071
1072    nowUs += ((70ll * 365 + 17) * 24) * 60 * 60 * 1000000ll;
1073
1074    uint64_t hi = nowUs / 1000000ll;
1075    uint64_t lo = ((1ll << 32) * (nowUs % 1000000ll)) / 1000000ll;
1076
1077    return (hi << 32) | lo;
1078}
1079
1080void WifiDisplaySource::PlaybackSession::onSendSR() {
1081    sp<ABuffer> buffer = new ABuffer(1500);
1082    buffer->setRange(0, 0);
1083
1084    addSR(buffer);
1085    addSDES(buffer);
1086
1087    if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1088        sp<AMessage> notify = mNotify->dup();
1089        notify->setInt32("what", kWhatBinaryData);
1090        notify->setInt32("channel", mRTCPChannel);
1091        notify->setBuffer("data", buffer);
1092        notify->post();
1093    } else {
1094        sendPacket(mRTCPSessionID, buffer->data(), buffer->size());
1095    }
1096
1097    ++mNumSRsSent;
1098}
1099
1100ssize_t WifiDisplaySource::PlaybackSession::appendTSData(
1101        const void *data, size_t size, bool timeDiscontinuity, bool flush) {
1102    CHECK_EQ(size, 188);
1103
1104    CHECK_LE(mTSQueue->size() + size, mTSQueue->capacity());
1105
1106    memcpy(mTSQueue->data() + mTSQueue->size(), data, size);
1107    mTSQueue->setRange(0, mTSQueue->size() + size);
1108
1109    if (flush || mTSQueue->size() == mTSQueue->capacity()) {
1110        // flush
1111
1112        int64_t nowUs = ALooper::GetNowUs();
1113        if (mFirstPacketTimeUs < 0ll) {
1114            mFirstPacketTimeUs = nowUs;
1115        }
1116
1117        // 90kHz time scale
1118        uint32_t rtpTime = ((nowUs - mFirstPacketTimeUs) * 9ll) / 100ll;
1119
1120        uint8_t *rtp = mTSQueue->data();
1121        rtp[0] = 0x80;
1122        rtp[1] = 33 | (timeDiscontinuity ? (1 << 7) : 0);  // M-bit
1123        rtp[2] = (mRTPSeqNo >> 8) & 0xff;
1124        rtp[3] = mRTPSeqNo & 0xff;
1125        rtp[4] = rtpTime >> 24;
1126        rtp[5] = (rtpTime >> 16) & 0xff;
1127        rtp[6] = (rtpTime >> 8) & 0xff;
1128        rtp[7] = rtpTime & 0xff;
1129        rtp[8] = kSourceID >> 24;
1130        rtp[9] = (kSourceID >> 16) & 0xff;
1131        rtp[10] = (kSourceID >> 8) & 0xff;
1132        rtp[11] = kSourceID & 0xff;
1133
1134        ++mRTPSeqNo;
1135        ++mNumRTPSent;
1136        mNumRTPOctetsSent += mTSQueue->size() - 12;
1137
1138        mLastRTPTime = rtpTime;
1139        mLastNTPTime = GetNowNTP();
1140
1141        if (mTransportMode == TRANSPORT_TCP_INTERLEAVED) {
1142            sp<AMessage> notify = mNotify->dup();
1143            notify->setInt32("what", kWhatBinaryData);
1144
1145            sp<ABuffer> data = new ABuffer(mTSQueue->size());
1146            memcpy(data->data(), rtp, mTSQueue->size());
1147
1148            notify->setInt32("channel", mRTPChannel);
1149            notify->setBuffer("data", data);
1150            notify->post();
1151        } else {
1152            sendPacket(mRTPSessionID, rtp, mTSQueue->size());
1153
1154            mTotalBytesSent += mTSQueue->size();
1155            int64_t delayUs = ALooper::GetNowUs() - mFirstPacketTimeUs;
1156
1157            if (delayUs > 0ll) {
1158                ALOGV("approx. net bandwidth used: %.2f Mbit/sec",
1159                        mTotalBytesSent * 8.0 / delayUs);
1160            }
1161        }
1162
1163        mTSQueue->setInt32Data(mRTPSeqNo - 1);
1164        mHistory.push_back(mTSQueue);
1165        ++mHistoryLength;
1166
1167        if (mHistoryLength > kMaxHistoryLength) {
1168            mTSQueue = *mHistory.begin();
1169            mHistory.erase(mHistory.begin());
1170
1171            --mHistoryLength;
1172        } else {
1173            mTSQueue = new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188);
1174        }
1175
1176        mTSQueue->setRange(0, 12);
1177    }
1178
1179    return size;
1180}
1181
1182status_t WifiDisplaySource::PlaybackSession::parseRTCP(
1183        const sp<ABuffer> &buffer) {
1184    const uint8_t *data = buffer->data();
1185    size_t size = buffer->size();
1186
1187    while (size > 0) {
1188        if (size < 8) {
1189            // Too short to be a valid RTCP header
1190            return ERROR_MALFORMED;
1191        }
1192
1193        if ((data[0] >> 6) != 2) {
1194            // Unsupported version.
1195            return ERROR_UNSUPPORTED;
1196        }
1197
1198        if (data[0] & 0x20) {
1199            // Padding present.
1200
1201            size_t paddingLength = data[size - 1];
1202
1203            if (paddingLength + 12 > size) {
1204                // If we removed this much padding we'd end up with something
1205                // that's too short to be a valid RTP header.
1206                return ERROR_MALFORMED;
1207            }
1208
1209            size -= paddingLength;
1210        }
1211
1212        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
1213
1214        if (size < headerLength) {
1215            // Only received a partial packet?
1216            return ERROR_MALFORMED;
1217        }
1218
1219        switch (data[1]) {
1220            case 200:
1221            case 201:  // RR
1222            case 202:  // SDES
1223            case 203:
1224            case 204:  // APP
1225                break;
1226
1227#if ENABLE_RETRANSMISSION
1228            case 205:  // TSFB (transport layer specific feedback)
1229                parseTSFB(data, headerLength);
1230                break;
1231#endif
1232
1233            case 206:  // PSFB (payload specific feedback)
1234                hexdump(data, headerLength);
1235                break;
1236
1237            default:
1238            {
1239                ALOGW("Unknown RTCP packet type %u of size %d",
1240                     (unsigned)data[1], headerLength);
1241                break;
1242            }
1243        }
1244
1245        data += headerLength;
1246        size -= headerLength;
1247    }
1248
1249    return OK;
1250}
1251
1252#if ENABLE_RETRANSMISSION
1253status_t WifiDisplaySource::PlaybackSession::parseTSFB(
1254        const uint8_t *data, size_t size) {
1255    if ((data[0] & 0x1f) != 1) {
1256        return ERROR_UNSUPPORTED;  // We only support NACK for now.
1257    }
1258
1259    uint32_t srcId = U32_AT(&data[8]);
1260    if (srcId != kSourceID) {
1261        return ERROR_MALFORMED;
1262    }
1263
1264    for (size_t i = 12; i < size; i += 4) {
1265        uint16_t seqNo = U16_AT(&data[i]);
1266        uint16_t blp = U16_AT(&data[i + 2]);
1267
1268        List<sp<ABuffer> >::iterator it = mHistory.begin();
1269        bool foundSeqNo = false;
1270        while (it != mHistory.end()) {
1271            const sp<ABuffer> &buffer = *it;
1272
1273            uint16_t bufferSeqNo = buffer->int32Data() & 0xffff;
1274
1275            bool retransmit = false;
1276            if (bufferSeqNo == seqNo) {
1277                retransmit = true;
1278            } else if (blp != 0) {
1279                for (size_t i = 0; i < 16; ++i) {
1280                    if ((blp & (1 << i))
1281                        && (bufferSeqNo == ((seqNo + i + 1) & 0xffff))) {
1282                        blp &= ~(1 << i);
1283                        retransmit = true;
1284                    }
1285                }
1286            }
1287
1288            if (retransmit) {
1289                ALOGI("retransmitting seqNo %d", bufferSeqNo);
1290
1291                sp<ABuffer> retransRTP = new ABuffer(2 + buffer->size());
1292                uint8_t *rtp = retransRTP->data();
1293                memcpy(rtp, buffer->data(), 12);
1294                rtp[2] = (mRTPRetransmissionSeqNo >> 8) & 0xff;
1295                rtp[3] = mRTPRetransmissionSeqNo & 0xff;
1296                rtp[12] = (bufferSeqNo >> 8) & 0xff;
1297                rtp[13] = bufferSeqNo & 0xff;
1298                memcpy(&rtp[14], buffer->data() + 12, buffer->size() - 12);
1299
1300                ++mRTPRetransmissionSeqNo;
1301
1302                sendPacket(
1303                        mRTPRetransmissionSessionID,
1304                        retransRTP->data(), retransRTP->size());
1305
1306                if (bufferSeqNo == seqNo) {
1307                    foundSeqNo = true;
1308                }
1309
1310                if (foundSeqNo && blp == 0) {
1311                    break;
1312                }
1313            }
1314
1315            ++it;
1316        }
1317
1318        if (!foundSeqNo || blp != 0) {
1319            ALOGI("Some sequence numbers were no longer available for "
1320                  "retransmission");
1321        }
1322    }
1323
1324    return OK;
1325}
1326#endif
1327
1328void WifiDisplaySource::PlaybackSession::requestIDRFrame() {
1329    for (size_t i = 0; i < mTracks.size(); ++i) {
1330        const sp<Track> &track = mTracks.valueAt(i);
1331
1332        track->converter()->requestIDRFrame();
1333    }
1334}
1335
1336status_t WifiDisplaySource::PlaybackSession::sendPacket(
1337        int32_t sessionID, const void *data, size_t size) {
1338    return mNetSession->sendRequest(sessionID, data, size);
1339}
1340
1341}  // namespace android
1342
1343