summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/wifi-display
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-10-09 15:53:34 -0700
committerAndreas Huber <andih@google.com>2012-10-09 15:53:34 -0700
commitd243c04534d1b74bd66625c5c96a9b918d8838bf (patch)
tree04bbffe2ae0e6fdaaac8d89cb535476952403cf9 /media/libstagefright/wifi-display
parent2458d482c4822c6f9e6274f5bd12b6aea095a9cd (diff)
downloadframeworks_av-d243c04534d1b74bd66625c5c96a9b918d8838bf.zip
frameworks_av-d243c04534d1b74bd66625c5c96a9b918d8838bf.tar.gz
frameworks_av-d243c04534d1b74bd66625c5c96a9b918d8838bf.tar.bz2
Switch audio mode based on dongle's capabilities
properly parse rtp port and use it to setup session. Change-Id: Ic7521cb867143278196c3ce4b19a74ecc2703d8e related-to-bug: 7318719
Diffstat (limited to 'media/libstagefright/wifi-display')
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp99
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.h2
2 files changed, 93 insertions, 8 deletions
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index d856bac..8ab9abe 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -36,6 +36,8 @@
#include <arpa/inet.h>
#include <cutils/properties.h>
+#include <ctype.h>
+
namespace android {
WifiDisplaySource::WifiDisplaySource(
@@ -46,6 +48,7 @@ WifiDisplaySource::WifiDisplaySource(
mClient(client),
mSessionID(0),
mStopReplyID(0),
+ mChosenRTPPort(-1),
mUsingPCMAudio(false),
mClientSessionID(0),
mReaperPending(false),
@@ -532,11 +535,6 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) {
transportString = "TCP";
}
- if (property_get("media.wfd.use-pcm-audio", val, NULL)
- && (!strcasecmp("true", val) || !strcmp("1", val))) {
- ALOGI("Using PCM audio.");
- mUsingPCMAudio = true;
- }
// For 720p60:
// use "30 00 02 02 00000040 00000000 00000000 00 0000 0000 00 none none\r\n"
// For 720p30:
@@ -548,11 +546,11 @@ status_t WifiDisplaySource::sendM4(int32_t sessionID) {
"28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
"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 19000 0 mode=play\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());
+ mClientInfo.mLocalIP.c_str(), transportString.c_str(), mChosenRTPPort);
AString request = "SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0\r\n";
AppendCommonResponse(&request, mNextCSeq);
@@ -649,6 +647,36 @@ status_t WifiDisplaySource::onReceiveM1Response(
return OK;
}
+// sink_audio_list := ("LPCM"|"AAC"|"AC3" HEXDIGIT*8 HEXDIGIT*2)
+// (", " sink_audio_list)*
+static void GetAudioModes(const char *s, const char *prefix, uint32_t *modes) {
+ *modes = 0;
+
+ size_t prefixLen = strlen(prefix);
+
+ while (*s != '0') {
+ if (!strncmp(s, prefix, prefixLen) && s[prefixLen] == ' ') {
+ unsigned latency;
+ if (sscanf(&s[prefixLen + 1], "%08x %02x", modes, &latency) != 2) {
+ *modes = 0;
+ }
+
+ return;
+ }
+
+ char *commaPos = strchr(s, ',');
+ if (commaPos != NULL) {
+ s = commaPos + 1;
+
+ while (isspace(*s)) {
+ ++s;
+ }
+ } else {
+ break;
+ }
+ }
+}
+
status_t WifiDisplaySource::onReceiveM3Response(
int32_t sessionID, const sp<ParsedMessage> &msg) {
int32_t statusCode;
@@ -667,8 +695,63 @@ status_t WifiDisplaySource::onReceiveM3Response(
return ERROR_MALFORMED;
}
-#if REQUIRE_HDCP
AString value;
+ if (!params->findParameter("wfd_client_rtp_ports", &value)) {
+ ALOGE("Sink doesn't report its choice of wfd_client_rtp_ports.");
+ return ERROR_MALFORMED;
+ }
+
+ unsigned port0, port1;
+ if (sscanf(value.c_str(),
+ "RTP/AVP/UDP;unicast %u %u mode=play",
+ &port0,
+ &port1) != 2
+ || port0 == 0 || port0 > 65535 || port1 != 0) {
+ ALOGE("Sink chose its wfd_client_rtp_ports poorly (%s)",
+ value.c_str());
+
+ return ERROR_MALFORMED;
+ }
+
+ mChosenRTPPort = port0;
+
+ if (!params->findParameter("wfd_audio_codecs", &value)) {
+ ALOGE("Sink doesn't report its choice of wfd_audio_codecs.");
+ return ERROR_MALFORMED;
+ }
+
+ if (value == "none") {
+ ALOGE("Sink doesn't support audio at all.");
+ return ERROR_UNSUPPORTED;
+ }
+
+ uint32_t modes;
+ GetAudioModes(value.c_str(), "AAC", &modes);
+
+ bool supportsAAC = (modes & 1) != 0; // AAC 2ch 48kHz
+
+ GetAudioModes(value.c_str(), "LPCM", &modes);
+
+ bool supportsPCM = (modes & 2) != 0; // LPCM 2ch 48kHz
+
+ char val[PROPERTY_VALUE_MAX];
+ if (supportsPCM
+ && property_get("media.wfd.use-pcm-audio", val, NULL)
+ && (!strcasecmp("true", val) || !strcmp("1", val))) {
+ ALOGI("Using PCM audio.");
+ mUsingPCMAudio = true;
+ } else if (supportsAAC) {
+ ALOGI("Using AAC audio.");
+ mUsingPCMAudio = false;
+ } else if (supportsPCM) {
+ ALOGI("Using PCM audio.");
+ mUsingPCMAudio = true;
+ } else {
+ ALOGI("Sink doesn't support an audio format we do.");
+ return ERROR_UNSUPPORTED;
+ }
+
+#if REQUIRE_HDCP
if (!params->findParameter("wfd_content_protection", &value)) {
ALOGE("Sink doesn't appear to support content protection.");
return -EACCES;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.h b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
index 0692cde..9e748dd 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.h
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.h
@@ -114,6 +114,8 @@ private:
uint32_t mStopReplyID;
+ int32_t mChosenRTPPort; // extracted from "wfd_client_rtp_ports"
+
bool mUsingPCMAudio;
int32_t mClientSessionID;