status_t WifiDisplaySource::sendM16(int32_t sessionID) { AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); CHECK_EQ(sessionID, mClientSessionID); request.append( AStringPrintf("Session: %d\r\n", mClientInfo.mPlaybackSessionID)); request.append("\r\n"); // Empty body status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM16Response); ++mNextCSeq; scheduleKeepAlive(sessionID); return OK; }
status_t WifiDisplaySource::sendM3(int32_t sessionID) { AString body = "wfd_content_protection\r\n" "wfd_video_formats\r\n" "wfd_audio_codecs\r\n" "wfd_client_rtp_ports\r\n"; AString request = "GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); request.append("Content-Type: text/parameters\r\n"); request.append(AStringPrintf("Content-Length: %d\r\n", body.size())); request.append("\r\n"); request.append(body); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM3Response); ++mNextCSeq; return OK; }
status_t WifiDisplaySource::sendM4(int32_t sessionID) { CHECK_EQ(sessionID, mClientSessionID); AString body; if (mSinkSupportsVideo) { body.append("wfd_video_formats: "); VideoFormats chosenVideoFormat; chosenVideoFormat.disableAll(); chosenVideoFormat.setNativeResolution( mChosenVideoResolutionType, mChosenVideoResolutionIndex); chosenVideoFormat.setProfileLevel( mChosenVideoResolutionType, mChosenVideoResolutionIndex, mChosenVideoProfile, mChosenVideoLevel); body.append(chosenVideoFormat.getFormatSpec(true /* forM4Message */)); body.append("\r\n"); } if (mSinkSupportsAudio) { body.append( AStringPrintf("wfd_audio_codecs: %s\r\n", (mUsingPCMAudio ? "LPCM 00000002 00" // 2 ch PCM 48kHz : "AAC 00000001 00"))); // 2 ch AAC 48kHz } body.append( AStringPrintf( "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n", mClientInfo.mLocalIP.c_str())); body.append( AStringPrintf( "wfd_client_rtp_ports: %s\r\n", mWfdClientRtpPorts.c_str())); AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); request.append("Content-Type: text/parameters\r\n"); request.append(AStringPrintf("Content-Length: %d\r\n", body.size())); request.append("\r\n"); request.append(body); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM4Response); ++mNextCSeq; return OK; }
status_t WifiDisplaySource::sendTrigger( int32_t sessionID, TriggerType triggerType) { AString body = "wfd_trigger_method: "; switch (triggerType) { case TRIGGER_SETUP: body.append("SETUP"); break; case TRIGGER_TEARDOWN: ALOGI("Sending TEARDOWN trigger."); body.append("TEARDOWN"); break; case TRIGGER_PAUSE: body.append("PAUSE"); break; case TRIGGER_PLAY: body.append("PLAY"); break; default: TRESPASS(); } body.append("\r\n"); AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); request.append("Content-Type: text/parameters\r\n"); request.append(AStringPrintf("Content-Length: %d\r\n", body.size())); request.append("\r\n"); request.append(body); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM5Response); ++mNextCSeq; return OK; }
status_t WifiDisplaySource::sendM1(int32_t sessionID) { AString request = "OPTIONS * RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); request.append( "Require: org.wfa.wfd1.0\r\n" "\r\n"); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM1Response); ++mNextCSeq; return OK; }
status_t WifiDisplaySource::sendM4(int32_t sessionID) { // wfd_video_formats: // 1 byte "native" // 1 byte "preferred-display-mode-supported" 0 or 1 // one or more avc codec structures // 1 byte profile // 1 byte level // 4 byte CEA mask // 4 byte VESA mask // 4 byte HH mask // 1 byte latency // 2 byte min-slice-slice // 2 byte slice-enc-params // 1 byte framerate-control-support // max-hres (none or 2 byte) // max-vres (none or 2 byte) CHECK_EQ(sessionID, mClientSessionID); AString transportString = "UDP"; char val[PROPERTY_VALUE_MAX]; if (property_get("media.wfd.enable-tcp", val, NULL) && (!strcasecmp("true", val) || !strcmp("1", val))) { ALOGI("Using TCP transport."); transportString = "TCP"; } // For 720p60: // use "30 00 02 02 00000040 00000000 00000000 00 0000 0000 00 none none\r\n" // For 720p30: // use "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n" // For 720p24: // use "78 00 02 02 00008000 00000000 00000000 00 0000 0000 00 none none\r\n" // For 1080p30: // use "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n" AString body = StringPrintf( "wfd_video_formats: " #if defined(USE_1080P) "38 00 02 02 00000080 00000000 00000000 00 0000 0000 00 none none\r\n" #elif defined(USE_480P) "08 00 02 02 00000010 00000000 00000000 00 0000 0000 00 none none\r\n" #else //if defined(USE_720P) default "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n" #endif "wfd_audio_codecs: %s\r\n" "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n" "wfd_client_rtp_ports: RTP/AVP/%s;unicast %d 0 mode=play\r\n", (mUsingPCMAudio ? "LPCM 00000002 00" // 2 ch PCM 48kHz : "AAC 00000001 00"), // 2 ch AAC 48kHz mClientInfo.mLocalIP.c_str(), transportString.c_str(), mChosenRTPPort); AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n"; AppendCommonResponse(&request, mNextCSeq); request.append("Content-Type: text/parameters\r\n"); request.append(StringPrintf("Content-Length: %d\r\n", body.size())); request.append("\r\n"); request.append(body); status_t err = mNetSession->sendRequest(sessionID, request.c_str(), request.size()); if (err != OK) { return err; } registerResponseHandler( sessionID, mNextCSeq, &WifiDisplaySource::onReceiveM4Response); ++mNextCSeq; return OK; }