From ccf8b5667049a9e3165a80635071bd3bcd0a38ae Mon Sep 17 00:00:00 2001 From: "fischman@webrtc.org" Date: Tue, 3 Sep 2013 19:02:11 +0000 Subject: [PATCH] AppRTCDemo(android): prefer ISAC for audio codec. R=wu@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2126004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4666 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../appspot/apprtc/AppRTCDemoActivity.java | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java index 936cb2bd7..7c673d813 100644 --- a/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java +++ b/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java @@ -62,6 +62,8 @@ import org.webrtc.VideoTrack; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Main Activity of the AppRTCDemo Android app demonstrating interoperability @@ -289,6 +291,55 @@ public class AppRTCDemoActivity extends Activity } } + // Mangle SDP to prefer ISAC/16000 over any other audio codec. + private String preferISAC(String sdpDescription) { + String[] lines = sdpDescription.split("\n"); + int mLineIndex = -1; + String isac16kRtpMap = null; + Pattern isac16kPattern = + Pattern.compile("^a=rtpmap:(\\d+) ISAC/16000[\r]?$"); + for (int i = 0; + (i < lines.length) && (mLineIndex == -1 || isac16kRtpMap == null); + ++i) { + if (lines[i].startsWith("m=audio ")) { + mLineIndex = i; + continue; + } + Matcher isac16kMatcher = isac16kPattern.matcher(lines[i]); + if (isac16kMatcher.matches()) { + isac16kRtpMap = isac16kMatcher.group(1); + continue; + } + } + if (mLineIndex == -1) { + Log.d(TAG, "No m=audio line, so can't prefer iSAC"); + return sdpDescription; + } + if (isac16kRtpMap == null) { + Log.d(TAG, "No ISAC/16000 line, so can't prefer iSAC"); + return sdpDescription; + } + String[] origMLineParts = lines[mLineIndex].split(" "); + StringBuilder newMLine = new StringBuilder(); + int origPartIndex = 0; + // Format is: m= ... + newMLine.append(origMLineParts[origPartIndex++]).append(" "); + newMLine.append(origMLineParts[origPartIndex++]).append(" "); + newMLine.append(origMLineParts[origPartIndex++]).append(" "); + newMLine.append(isac16kRtpMap).append(" "); + for (; origPartIndex < origMLineParts.length; ++origPartIndex) { + if (!origMLineParts[origPartIndex].equals(isac16kRtpMap)) { + newMLine.append(origMLineParts[origPartIndex]).append(" "); + } + } + lines[mLineIndex] = newMLine.toString(); + StringBuilder newSdpDescription = new StringBuilder(); + for (String line : lines) { + newSdpDescription.append(line).append("\n"); + } + return newSdpDescription.toString(); + } + // Implementation detail: observe ICE & stream changes and react accordingly. private class PCObserver implements PeerConnection.Observer { @Override public void onIceCandidate(final IceCandidate candidate){ @@ -360,10 +411,12 @@ public class AppRTCDemoActivity extends Activity // Implementation detail: handle offer creation/signaling and answer setting, // as well as adding remote ICE candidates once the answer SDP is set. private class SDPObserver implements SdpObserver { - @Override public void onCreateSuccess(final SessionDescription sdp) { + @Override public void onCreateSuccess(final SessionDescription origSdp) { runOnUiThread(new Runnable() { public void run() { - logAndToast("Sending " + sdp.type); + logAndToast("Sending " + origSdp.type); + SessionDescription sdp = new SessionDescription( + origSdp.type, preferISAC(origSdp.description)); JSONObject json = new JSONObject(); jsonPut(json, "type", sdp.type.canonicalForm()); jsonPut(json, "sdp", sdp.description); @@ -449,7 +502,7 @@ public class AppRTCDemoActivity extends Activity } else if (type.equals("answer") || type.equals("offer")) { SessionDescription sdp = new SessionDescription( SessionDescription.Type.fromCanonicalForm(type), - (String) json.get("sdp")); + preferISAC((String) json.get("sdp"))); pc.setRemoteDescription(sdpObserver, sdp); } else if (type.equals("bye")) { logAndToast("Remote end hung up; dropping PeerConnection");