1fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber/*
2fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * Copyright 2012, The Android Open Source Project
3fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber *
4fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * you may not use this file except in compliance with the License.
6fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * You may obtain a copy of the License at
7fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber *
8fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
9fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber *
10fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * Unless required by applicable law or agreed to in writing, software
11fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * See the License for the specific language governing permissions and
14fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber * limitations under the License.
15fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber */
16fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
17fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#ifndef WIFI_DISPLAY_SINK_H_
18fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
19fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#define WIFI_DISPLAY_SINK_H_
20fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
21fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "ANetworkSession.h"
22fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
23fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include <gui/Surface.h>
24fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include <media/stagefright/foundation/AHandler.h>
25fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
26fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubernamespace android {
27fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
28fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstruct ParsedMessage;
29fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstruct RTPSink;
30fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
31fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber// Represents the RTSP client acting as a wifi display sink.
32fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber// Connects to a wifi display source and renders the incoming
33fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber// transport stream using a MediaPlayer instance.
34fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstruct WifiDisplaySink : public AHandler {
35fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    WifiDisplaySink(
36fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const sp<ANetworkSession> &netSession,
37fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const sp<ISurfaceTexture> &surfaceTex = NULL);
38fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
39fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void start(const char *sourceHost, int32_t sourcePort);
40fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void start(const char *uri);
41fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
42fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberprotected:
43fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    virtual ~WifiDisplaySink();
44fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    virtual void onMessageReceived(const sp<AMessage> &msg);
45fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
46fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberprivate:
47fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    enum State {
48fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        UNDEFINED,
49fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        CONNECTING,
50fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        CONNECTED,
51fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        PAUSED,
52fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        PLAYING,
53fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    };
54fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
55fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    enum {
56fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        kWhatStart,
57fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        kWhatRTSPNotify,
58fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        kWhatStop,
59fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    };
60fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
61fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    struct ResponseID {
62fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        int32_t mSessionID;
63fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        int32_t mCSeq;
64fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
65fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        bool operator<(const ResponseID &other) const {
66fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            return mSessionID < other.mSessionID
67fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                || (mSessionID == other.mSessionID
68fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                        && mCSeq < other.mCSeq);
69fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
70fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    };
71fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
72fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    typedef status_t (WifiDisplaySink::*HandleRTSPResponseFunc)(
73fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, const sp<ParsedMessage> &msg);
74fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
75fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    static const bool sUseTCPInterleaving = false;
76fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
77fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    State mState;
78fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    sp<ANetworkSession> mNetSession;
79fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    sp<ISurfaceTexture> mSurfaceTex;
80fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    AString mSetupURI;
81fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    AString mRTSPHost;
82fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    int32_t mSessionID;
83fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
84fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    int32_t mNextCSeq;
85fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
86fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    KeyedVector<ResponseID, HandleRTSPResponseFunc> mResponseHandlers;
87fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
88fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    sp<RTPSink> mRTPSink;
89fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    AString mPlaybackSessionID;
90fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    int32_t mPlaybackSessionTimeoutSecs;
91fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
92fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t sendM2(int32_t sessionID);
93fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t sendDescribe(int32_t sessionID, const char *uri);
94fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t sendSetup(int32_t sessionID, const char *uri);
95fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t sendPlay(int32_t sessionID, const char *uri);
96fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
97fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t onReceiveM2Response(
98fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, const sp<ParsedMessage> &msg);
99fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
100fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t onReceiveDescribeResponse(
101fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, const sp<ParsedMessage> &msg);
102fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
103fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t onReceiveSetupResponse(
104fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, const sp<ParsedMessage> &msg);
105fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
106fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t configureTransport(const sp<ParsedMessage> &msg);
107fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
108fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    status_t onReceivePlayResponse(
109fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, const sp<ParsedMessage> &msg);
110fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
111fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void registerResponseHandler(
112fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID, int32_t cseq, HandleRTSPResponseFunc func);
113fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
114fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void onReceiveClientData(const sp<AMessage> &msg);
115fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
116fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void onOptionsRequest(
117fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID,
118fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t cseq,
119fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const sp<ParsedMessage> &data);
120fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
121fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void onGetParameterRequest(
122fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID,
123fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t cseq,
124fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const sp<ParsedMessage> &data);
125fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
126fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void onSetParameterRequest(
127fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID,
128fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t cseq,
129fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const sp<ParsedMessage> &data);
130fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
131fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    void sendErrorResponse(
132fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t sessionID,
133fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const char *errorDetail,
134fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            int32_t cseq);
135fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
136fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    static void AppendCommonResponse(AString *response, int32_t cseq);
137fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
138fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    bool ParseURL(
139fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            const char *url, AString *host, int32_t *port, AString *path,
140fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            AString *user, AString *pass);
141fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
142fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(WifiDisplaySink);
143fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber};
144fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
145fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}  // namespace android
146fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
147fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#endif  // WIFI_DISPLAY_SINK_H_
148