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
This commit is contained in:
fischman@webrtc.org 2013-09-03 19:02:11 +00:00
parent 8788167b9b
commit ccf8b56670

View File

@ -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=<media> <port> <proto> <fmt> ...
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");