Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0216af1 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Revive the code to support TCP interleaved transport"

parents 6bb6f2f9 7cc0c29d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1091,7 +1091,6 @@ void ANetworkSession::threadLoop() {
                                  clientSocket);

                            sp<Session> clientSession =
                                // using socket sd as sessionID
                                new Session(
                                        mNextSessionID++,
                                        Session::CONNECTED,
+13 −5
Original line number Diff line number Diff line
@@ -35,11 +35,19 @@

namespace android {

#if 0
// static
const int64_t DirectRenderer::kPacketLostDelayUs = 80000ll;

// static
const int64_t DirectRenderer::kPacketLateDelayUs = 60000ll;
#else
// static
const int64_t DirectRenderer::kPacketLostDelayUs = 1000000ll;

// static
const int64_t DirectRenderer::kPacketLateDelayUs = -1ll;
#endif

DirectRenderer::DirectRenderer(
        const sp<AMessage> &notifyLost,
@@ -309,11 +317,11 @@ void DirectRenderer::dequeueAccessUnits() {
void DirectRenderer::schedulePacketLost() {
    sp<AMessage> msg;

#if 1
    if (kPacketLateDelayUs > 0ll) {
        msg = new AMessage(kWhatPacketLate, id());
        msg->setInt32("generation", mPacketLostGeneration);
        msg->post(kPacketLateDelayUs);
#endif
    }

    msg = new AMessage(kWhatPacketLost, id());
    msg->setInt32("generation", mPacketLostGeneration);
+47 −6
Original line number Diff line number Diff line
@@ -253,6 +253,8 @@ RTPSink::RTPSink(
      mRTPPort(0),
      mRTPSessionID(0),
      mRTCPSessionID(0),
      mRTPClientSessionID(0),
      mRTCPClientSessionID(0),
      mFirstArrivalTimeUs(-1ll),
      mNumPacketsReceived(0ll),
      mRegression(1000),
@@ -260,6 +262,14 @@ RTPSink::RTPSink(
}

RTPSink::~RTPSink() {
    if (mRTCPClientSessionID != 0) {
        mNetSession->destroySession(mRTCPClientSessionID);
    }

    if (mRTPClientSessionID != 0) {
        mNetSession->destroySession(mRTPClientSessionID);
    }

    if (mRTCPSessionID != 0) {
        mNetSession->destroySession(mRTCPSessionID);
    }
@@ -269,8 +279,8 @@ RTPSink::~RTPSink() {
    }
}

status_t RTPSink::init(bool useTCPInterleaving) {
    if (useTCPInterleaving) {
status_t RTPSink::init(bool usingTCPTransport, bool usingTCPInterleaving) {
    if (usingTCPInterleaving) {
        return OK;
    }

@@ -280,8 +290,16 @@ status_t RTPSink::init(bool useTCPInterleaving) {
    sp<AMessage> rtcpNotify = new AMessage(kWhatRTCPNotify, id());
    for (clientRtp = 15550;; clientRtp += 2) {
        int32_t rtpSession;
        status_t err = mNetSession->createUDPSession(
        status_t err;
        struct in_addr ifaceAddr;
        if (usingTCPTransport) {
            ifaceAddr.s_addr = INADDR_ANY;
            err = mNetSession->createTCPDatagramSession(
                        ifaceAddr, clientRtp, rtpNotify, &rtpSession);
        } else {
            err = mNetSession->createUDPSession(
                        clientRtp, rtpNotify, &rtpSession);
        }

        if (err != OK) {
            ALOGI("failed to create RTP socket on port %d", clientRtp);
@@ -289,8 +307,13 @@ status_t RTPSink::init(bool useTCPInterleaving) {
        }

        int32_t rtcpSession;
        if (usingTCPTransport) {
            err = mNetSession->createTCPDatagramSession(
                    ifaceAddr, clientRtp + 1, rtcpNotify, &rtcpSession);
        } else {
            err = mNetSession->createUDPSession(
                    clientRtp + 1, rtcpNotify, &rtcpSession);
        }

        if (err == OK) {
            mRTPPort = clientRtp;
@@ -367,6 +390,24 @@ void RTPSink::onMessageReceived(const sp<AMessage> &msg) {
                    break;
                }

                case ANetworkSession::kWhatClientConnected:
                {
                    int32_t sessionID;
                    CHECK(msg->findInt32("sessionID", &sessionID));
                    ALOGI("TCP session %d now connected", sessionID);

                    int32_t serverPort;
                    CHECK(msg->findInt32("server-port", &serverPort));

                    if (serverPort == mRTPPort) {
                        mRTPClientSessionID = sessionID;
                    } else {
                        CHECK_EQ(serverPort, mRTPPort + 1);
                        mRTCPClientSessionID = sessionID;
                    }
                    break;
                }

                default:
                    TRESPASS();
            }
+7 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ struct RTPSink : public AHandler {
    // If TCP interleaving is used, no UDP sockets are created, instead
    // incoming RTP/RTCP packets (arriving on the RTSP control connection)
    // are manually injected by WifiDisplaySink.
    status_t init(bool useTCPInterleaving);
    status_t init(bool usingTCPTransport, bool usingTCPInterleaving);

    status_t connect(
            const char *host, int32_t remoteRtpPort, int32_t remoteRtcpPort);
@@ -79,8 +79,12 @@ private:
    KeyedVector<uint32_t, sp<Source> > mSources;

    int32_t mRTPPort;
    int32_t mRTPSessionID;
    int32_t mRTCPSessionID;

    int32_t mRTPSessionID;   // in TCP unicast mode these are just server
    int32_t mRTCPSessionID;  // sockets. No data is transferred through them.

    int32_t mRTPClientSessionID;  // in TCP unicast mode
    int32_t mRTCPClientSessionID;

    int64_t mFirstArrivalTimeUs;
    int64_t mNumPacketsReceived;
+54 −70
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaErrors.h>

#include <cutils/properties.h>

namespace android {

WifiDisplaySink::WifiDisplaySink(
@@ -37,6 +39,8 @@ WifiDisplaySink::WifiDisplaySink(
      mNetSession(netSession),
      mSurfaceTex(bufferProducer),
      mNotify(notify),
      mUsingTCPTransport(false),
      mUsingTCPInterleaving(false),
      mSessionID(0),
      mNextCSeq(1) {
#if 1
@@ -141,17 +145,8 @@ void WifiDisplaySink::onMessageReceived(const sp<AMessage> &msg) {
            sleep(2);  // XXX

            int32_t sourcePort;

            if (msg->findString("setupURI", &mSetupURI)) {
                AString path, user, pass;
                CHECK(ParseURL(
                            mSetupURI.c_str(),
                            &mRTSPHost, &sourcePort, &path, &user, &pass)
                        && user.empty() && pass.empty());
            } else {
            CHECK(msg->findString("sourceHost", &mRTSPHost));
            CHECK(msg->findInt32("sourcePort", &sourcePort));
            }

            sp<AMessage> notify = new AMessage(kWhatRTSPNotify, id());

@@ -208,13 +203,6 @@ void WifiDisplaySink::onMessageReceived(const sp<AMessage> &msg) {
                {
                    ALOGI("We're now connected.");
                    mState = CONNECTED;

                    if (!mSetupURI.empty()) {
                        status_t err =
                            sendDescribe(mSessionID, mSetupURI.c_str());

                        CHECK_EQ(err, (status_t)OK);
                    }
                    break;
                }

@@ -226,7 +214,7 @@ void WifiDisplaySink::onMessageReceived(const sp<AMessage> &msg) {

                case ANetworkSession::kWhatBinaryData:
                {
                    CHECK(sUseTCPInterleaving);
                    CHECK(mUsingTCPInterleaving);

                    int32_t channel;
                    CHECK(msg->findInt32("channel", &channel));
@@ -312,20 +300,6 @@ status_t WifiDisplaySink::onReceiveM2Response(
    return OK;
}

status_t WifiDisplaySink::onReceiveDescribeResponse(
        int32_t sessionID, const sp<ParsedMessage> &msg) {
    int32_t statusCode;
    if (!msg->getStatusCode(&statusCode)) {
        return ERROR_MALFORMED;
    }

    if (statusCode != 200) {
        return ERROR_UNSUPPORTED;
    }

    return sendSetup(sessionID, mSetupURI.c_str());
}

status_t WifiDisplaySink::onReceiveSetupResponse(
        int32_t sessionID, const sp<ParsedMessage> &msg) {
    int32_t statusCode;
@@ -365,12 +339,11 @@ status_t WifiDisplaySink::onReceiveSetupResponse(

    return sendPlay(
            sessionID,
            !mSetupURI.empty()
                ? mSetupURI.c_str() : "rtsp://x.x.x.x:x/wfd1.0/streamid=0");
            "rtsp://x.x.x.x:x/wfd1.0/streamid=0");
}

status_t WifiDisplaySink::configureTransport(const sp<ParsedMessage> &msg) {
    if (sUseTCPInterleaving) {
    if (mUsingTCPTransport) {
        return OK;
    }

@@ -514,11 +487,45 @@ void WifiDisplaySink::onGetParameterRequest(
        int32_t sessionID,
        int32_t cseq,
        const sp<ParsedMessage> &data) {
    AString body = "wfd_video_formats: ";
    AString body;

    if (mState == CONNECTED) {
        mUsingTCPTransport = false;
        mUsingTCPInterleaving = false;

        char val[PROPERTY_VALUE_MAX];
        if (property_get("media.wfd-sink.tcp-mode", val, NULL)) {
            if (!strcasecmp("true", val) || !strcmp("1", val)) {
                ALOGI("Using TCP unicast transport.");
                mUsingTCPTransport = true;
                mUsingTCPInterleaving = false;
            } else if (!strcasecmp("interleaved", val)) {
                ALOGI("Using TCP interleaved transport.");
                mUsingTCPTransport = true;
                mUsingTCPInterleaving = true;
            }
        }

        body = "wfd_video_formats: ";
        body.append(mSinkSupportedVideoFormats.getFormatSpec());

        body.append(
                "\r\nwfd_audio_codecs: AAC 0000000F 00\r\n"
            "wfd_client_rtp_ports: RTP/AVP/UDP;unicast 19000 0 mode=play\r\n");
                "wfd_client_rtp_ports: RTP/AVP/");

        if (mUsingTCPTransport) {
            body.append("TCP;");
            if (mUsingTCPInterleaving) {
                body.append("interleaved");
            } else {
                body.append("unicast 19000 0");
            }
        } else {
            body.append("UDP;unicast 19000 0");
        }

        body.append(" mode=play\r\n");
    }

    AString response = "RTSP/1.0 200 OK\r\n";
    AppendCommonResponse(&response, cseq);
@@ -531,38 +538,13 @@ void WifiDisplaySink::onGetParameterRequest(
    CHECK_EQ(err, (status_t)OK);
}

status_t WifiDisplaySink::sendDescribe(int32_t sessionID, const char *uri) {
    uri = "rtsp://xwgntvx.is.livestream-api.com/livestreamiphone/wgntv";
    uri = "rtsp://v2.cache6.c.youtube.com/video.3gp?cid=e101d4bf280055f9&fmt=18";

    AString request = StringPrintf("DESCRIBE %s RTSP/1.0\r\n", uri);
    AppendCommonResponse(&request, mNextCSeq);

    request.append("Accept: application/sdp\r\n");
    request.append("\r\n");

    status_t err = mNetSession->sendRequest(
            sessionID, request.c_str(), request.size());

    if (err != OK) {
        return err;
    }

    registerResponseHandler(
            sessionID, mNextCSeq, &WifiDisplaySink::onReceiveDescribeResponse);

    ++mNextCSeq;

    return OK;
}

status_t WifiDisplaySink::sendSetup(int32_t sessionID, const char *uri) {
    sp<AMessage> notify = new AMessage(kWhatRTPSinkNotify, id());

    mRTPSink = new RTPSink(mNetSession, mSurfaceTex, notify);
    looper()->registerHandler(mRTPSink);

    status_t err = mRTPSink->init(sUseTCPInterleaving);
    status_t err = mRTPSink->init(mUsingTCPTransport, mUsingTCPInterleaving);

    if (err != OK) {
        looper()->unregisterHandler(mRTPSink->id());
@@ -574,15 +556,17 @@ status_t WifiDisplaySink::sendSetup(int32_t sessionID, const char *uri) {

    AppendCommonResponse(&request, mNextCSeq);

    if (sUseTCPInterleaving) {
    if (mUsingTCPInterleaving) {
        request.append("Transport: RTP/AVP/TCP;interleaved=0-1\r\n");
    } else {
        int32_t rtpPort = mRTPSink->getRTPPort();

        request.append(
                StringPrintf(
                    "Transport: RTP/AVP/UDP;unicast;client_port=%d-%d\r\n",
                    rtpPort, rtpPort + 1));
                    "Transport: RTP/AVP/%s;unicast;client_port=%d-%d\r\n",
                    mUsingTCPTransport ? "TCP" : "UDP",
                    rtpPort,
                    rtpPort + 1));
    }

    request.append("\r\n");
Loading