diff --git a/webrtc/examples/androidapp/res/values/strings.xml b/webrtc/examples/androidapp/res/values/strings.xml index 1d2148ad08..12bb88b464 100644 --- a/webrtc/examples/androidapp/res/values/strings.xml +++ b/webrtc/examples/androidapp/res/values/strings.xml @@ -59,15 +59,15 @@ Enable slider for changing capture quality. false - startvideobitrate_preference - Start video bitrate setting. - Start video bitrate setting. - Default + maxvideobitrate_preference + Maximum video bitrate setting. + Maximum video bitrate setting. + Default - startvideobitratevalue_preference - Video encoder start bitrate. - Enter video encoder start bitrate in kbps. - 1000 + maxvideobitratevalue_preference + Video encoder maximum bitrate. + Enter video encoder maximum bitrate in kbps. + 1700 videocodec_preference Default video codec. diff --git a/webrtc/examples/androidapp/res/xml/preferences.xml b/webrtc/examples/androidapp/res/xml/preferences.xml index 35a392dc8c..146ff5e62f 100644 --- a/webrtc/examples/androidapp/res/xml/preferences.xml +++ b/webrtc/examples/androidapp/res/xml/preferences.xml @@ -38,19 +38,19 @@ android:defaultValue="@string/pref_capturequalityslider_default" /> + android:defaultValue="@string/pref_maxvideobitratevalue_default" + android:dialogTitle="@string/pref_maxvideobitratevalue_dlg" /> 0) { + Log.d(TAG, "Set video maximum bitrate: " + peerConnectionParameters.videoMaxBitrate); + peerConnectionClient.setVideoMaxBitrate(peerConnectionParameters.videoMaxBitrate); + } } }); } diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/ConnectActivity.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/ConnectActivity.java index b1ff2e8de2..56d915f00a 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/ConnectActivity.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/ConnectActivity.java @@ -94,8 +94,8 @@ public class ConnectActivity extends Activity { keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key); - keyprefVideoBitrateType = getString(R.string.pref_startvideobitrate_key); - keyprefVideoBitrateValue = getString(R.string.pref_startvideobitratevalue_key); + keyprefVideoBitrateType = getString(R.string.pref_maxvideobitrate_key); + keyprefVideoBitrateValue = getString(R.string.pref_maxvideobitratevalue_key); keyprefVideoCodec = getString(R.string.pref_videocodec_key); keyprefHwCodecAcceleration = getString(R.string.pref_hwcodec_key); keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key); @@ -357,12 +357,12 @@ public class ConnectActivity extends Activity { // Get video and audio start bitrate. int videoStartBitrate = 0; String bitrateTypeDefault = getString( - R.string.pref_startvideobitrate_default); + R.string.pref_maxvideobitrate_default); String bitrateType = sharedPref.getString( keyprefVideoBitrateType, bitrateTypeDefault); if (!bitrateType.equals(bitrateTypeDefault)) { String bitrateValue = sharedPref.getString(keyprefVideoBitrateValue, - getString(R.string.pref_startvideobitratevalue_default)); + getString(R.string.pref_maxvideobitratevalue_default)); videoStartBitrate = Integer.parseInt(bitrateValue); } int audioStartBitrate = 0; diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java index 238d123dea..1d049f91d4 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java @@ -29,11 +29,12 @@ import org.webrtc.EglBase; import org.webrtc.IceCandidate; import org.webrtc.Logging; import org.webrtc.MediaConstraints; -import org.webrtc.MediaConstraints.KeyValuePair; import org.webrtc.MediaStream; import org.webrtc.PeerConnection; import org.webrtc.PeerConnection.IceConnectionState; import org.webrtc.PeerConnectionFactory; +import org.webrtc.RtpParameters; +import org.webrtc.RtpSender; import org.webrtc.SdpObserver; import org.webrtc.SessionDescription; import org.webrtc.StatsObserver; @@ -66,6 +67,7 @@ import java.util.regex.Pattern; public class PeerConnectionClient { public static final String VIDEO_TRACK_ID = "ARDAMSv0"; public static final String AUDIO_TRACK_ID = "ARDAMSa0"; + public static final String VIDEO_TRACK_TYPE = "video"; private static final String TAG = "PCRTCClient"; private static final String VIDEO_CODEC_VP8 = "VP8"; private static final String VIDEO_CODEC_VP9 = "VP9"; @@ -80,18 +82,13 @@ public class PeerConnectionClient { private static final String AUDIO_HIGH_PASS_FILTER_CONSTRAINT = "googHighpassFilter"; private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSuppression"; private static final String AUDIO_LEVEL_CONTROL_CONSTRAINT = "levelControl"; - private static final String MAX_VIDEO_WIDTH_CONSTRAINT = "maxWidth"; - private static final String MIN_VIDEO_WIDTH_CONSTRAINT = "minWidth"; - private static final String MAX_VIDEO_HEIGHT_CONSTRAINT = "maxHeight"; - private static final String MIN_VIDEO_HEIGHT_CONSTRAINT = "minHeight"; - private static final String MAX_VIDEO_FPS_CONSTRAINT = "maxFrameRate"; - private static final String MIN_VIDEO_FPS_CONSTRAINT = "minFrameRate"; private static final String DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT = "DtlsSrtpKeyAgreement"; private static final int HD_VIDEO_WIDTH = 1280; private static final int HD_VIDEO_HEIGHT = 720; private static final int MAX_VIDEO_WIDTH = 1280; private static final int MAX_VIDEO_HEIGHT = 1280; private static final int MAX_VIDEO_FPS = 30; + private static final int BPS_IN_KBPS = 1000; private static final PeerConnectionClient instance = new PeerConnectionClient(); private final PCObserver pcObserver = new PCObserver(); @@ -135,6 +132,7 @@ public class PeerConnectionClient { private boolean renderVideo; private VideoTrack localVideoTrack; private VideoTrack remoteVideoTrack; + private RtpSender localVideoSender; // enableAudio is set to true if audio should be sent. private boolean enableAudio; private AudioTrack localAudioTrack; @@ -150,7 +148,7 @@ public class PeerConnectionClient { public final int videoWidth; public final int videoHeight; public final int videoFps; - public final int videoStartBitrate; + public final int videoMaxBitrate; public final String videoCodec; public final boolean videoCodecHwAcceleration; public final boolean captureToTexture; @@ -167,7 +165,7 @@ public class PeerConnectionClient { public PeerConnectionParameters( boolean videoCallEnabled, boolean loopback, boolean tracing, boolean useCamera2, int videoWidth, int videoHeight, int videoFps, - int videoStartBitrate, String videoCodec, boolean videoCodecHwAcceleration, + int videoMaxBitrate, String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTexture, int audioStartBitrate, String audioCodec, boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBuiltInNS, @@ -179,7 +177,7 @@ public class PeerConnectionClient { this.videoWidth = videoWidth; this.videoHeight = videoHeight; this.videoFps = videoFps; - this.videoStartBitrate = videoStartBitrate; + this.videoMaxBitrate = videoMaxBitrate; this.videoCodec = videoCodec; this.videoCodecHwAcceleration = videoCodecHwAcceleration; this.captureToTexture = captureToTexture; @@ -278,6 +276,7 @@ public class PeerConnectionClient { renderVideo = true; localVideoTrack = null; remoteVideoTrack = null; + localVideoSender = null; enableAudio = true; localAudioTrack = null; statsTimer = new Timer(); @@ -567,6 +566,9 @@ public class PeerConnectionClient { mediaStream.addTrack(createAudioTrack()); peerConnection.addStream(mediaStream); + if (videoCallEnabled) { + findVideoSender(); + } if (peerConnectionParameters.aecDump) { try { @@ -770,14 +772,6 @@ public class PeerConnectionClient { if (videoCallEnabled) { sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, false); } - if (videoCallEnabled && peerConnectionParameters.videoStartBitrate > 0) { - sdpDescription = setStartBitrate(VIDEO_CODEC_VP8, true, - sdpDescription, peerConnectionParameters.videoStartBitrate); - sdpDescription = setStartBitrate(VIDEO_CODEC_VP9, true, - sdpDescription, peerConnectionParameters.videoStartBitrate); - sdpDescription = setStartBitrate(VIDEO_CODEC_H264, true, - sdpDescription, peerConnectionParameters.videoStartBitrate); - } if (peerConnectionParameters.audioStartBitrate > 0) { sdpDescription = setStartBitrate(AUDIO_CODEC_OPUS, false, sdpDescription, peerConnectionParameters.audioStartBitrate); @@ -818,6 +812,39 @@ public class PeerConnectionClient { }); } + public void setVideoMaxBitrate(final Integer maxBitrateKbps) { + executor.execute(new Runnable() { + @Override + public void run() { + if (peerConnection == null || localVideoSender == null || isError) { + return; + } + Log.d(TAG, "Requested max video bitrate: " + maxBitrateKbps); + if (localVideoSender == null) { + Log.w(TAG, "Sender is not ready."); + return; + } + + RtpParameters parameters = localVideoSender.getParameters(); + if (parameters.encodings.size() == 0) { + Log.w(TAG, "RtpParameters are not ready."); + return; + } + + for (RtpParameters.Encoding encoding : parameters.encodings) { + // Null value means no limit. + encoding.maxBitrateBps = maxBitrateKbps == null + ? null + : maxBitrateKbps * BPS_IN_KBPS; + } + if (!localVideoSender.setParameters(parameters)) { + Log.e(TAG, "RtpSender.setParameters failed."); + } + Log.d(TAG, "Configured max video bitrate to: " + maxBitrateKbps); + } + }); + } + private void reportError(final String errorMessage) { Log.e(TAG, "Peerconnection error: " + errorMessage); executor.execute(new Runnable() { @@ -848,6 +875,18 @@ public class PeerConnectionClient { return localVideoTrack; } + private void findVideoSender() { + for (RtpSender sender : peerConnection.getSenders()) { + if (sender.track() != null) { + String trackType = sender.track().kind(); + if (trackType.equals(VIDEO_TRACK_TYPE)) { + Log.d(TAG, "Found video sender."); + localVideoSender = sender; + } + } + } + } + private static String setStartBitrate(String codec, boolean isVideoCodec, String sdpDescription, int bitrateKbps) { String[] lines = sdpDescription.split("\r\n"); diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/SettingsActivity.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/SettingsActivity.java index e358465ff1..4114828f09 100644 --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/SettingsActivity.java +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/SettingsActivity.java @@ -31,8 +31,8 @@ public class SettingsActivity extends Activity private String keyprefResolution; private String keyprefFps; private String keyprefCaptureQualitySlider; - private String keyprefStartVideoBitrateType; - private String keyprefStartVideoBitrateValue; + private String keyprefMaxVideoBitrateType; + private String keyprefMaxVideoBitrateValue; private String keyPrefVideoCodec; private String keyprefHwCodec; private String keyprefCaptureToTexture; @@ -61,8 +61,8 @@ public class SettingsActivity extends Activity keyprefResolution = getString(R.string.pref_resolution_key); keyprefFps = getString(R.string.pref_fps_key); keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key); - keyprefStartVideoBitrateType = getString(R.string.pref_startvideobitrate_key); - keyprefStartVideoBitrateValue = getString(R.string.pref_startvideobitratevalue_key); + keyprefMaxVideoBitrateType = getString(R.string.pref_maxvideobitrate_key); + keyprefMaxVideoBitrateValue = getString(R.string.pref_maxvideobitratevalue_key); keyPrefVideoCodec = getString(R.string.pref_videocodec_key); keyprefHwCodec = getString(R.string.pref_hwcodec_key); keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key); @@ -102,8 +102,8 @@ public class SettingsActivity extends Activity updateSummary(sharedPreferences, keyprefResolution); updateSummary(sharedPreferences, keyprefFps); updateSummaryB(sharedPreferences, keyprefCaptureQualitySlider); - updateSummary(sharedPreferences, keyprefStartVideoBitrateType); - updateSummaryBitrate(sharedPreferences, keyprefStartVideoBitrateValue); + updateSummary(sharedPreferences, keyprefMaxVideoBitrateType); + updateSummaryBitrate(sharedPreferences, keyprefMaxVideoBitrateValue); setVideoBitrateEnable(sharedPreferences); updateSummary(sharedPreferences, keyPrefVideoCodec); updateSummaryB(sharedPreferences, keyprefHwCodec); @@ -177,13 +177,13 @@ public class SettingsActivity extends Activity String key) { if (key.equals(keyprefResolution) || key.equals(keyprefFps) - || key.equals(keyprefStartVideoBitrateType) + || key.equals(keyprefMaxVideoBitrateType) || key.equals(keyPrefVideoCodec) || key.equals(keyprefStartAudioBitrateType) || key.equals(keyPrefAudioCodec) || key.equals(keyPrefRoomServerUrl)) { updateSummary(sharedPreferences, key); - } else if (key.equals(keyprefStartVideoBitrateValue) + } else if (key.equals(keyprefMaxVideoBitrateValue) || key.equals(keyprefStartAudioBitrateValue)) { updateSummaryBitrate(sharedPreferences, key); } else if (key.equals(keyprefVideoCall) @@ -204,7 +204,7 @@ public class SettingsActivity extends Activity } else if (key.equals(keyprefSpeakerphone)) { updateSummaryList(sharedPreferences, key); } - if (key.equals(keyprefStartVideoBitrateType)) { + if (key.equals(keyprefMaxVideoBitrateType)) { setVideoBitrateEnable(sharedPreferences); } if (key.equals(keyprefStartAudioBitrateType)) { @@ -238,10 +238,10 @@ public class SettingsActivity extends Activity private void setVideoBitrateEnable(SharedPreferences sharedPreferences) { Preference bitratePreferenceValue = - settingsFragment.findPreference(keyprefStartVideoBitrateValue); - String bitrateTypeDefault = getString(R.string.pref_startvideobitrate_default); + settingsFragment.findPreference(keyprefMaxVideoBitrateValue); + String bitrateTypeDefault = getString(R.string.pref_maxvideobitrate_default); String bitrateType = sharedPreferences.getString( - keyprefStartVideoBitrateType, bitrateTypeDefault); + keyprefMaxVideoBitrateType, bitrateTypeDefault); if (bitrateType.equals(bitrateTypeDefault)) { bitratePreferenceValue.setEnabled(false); } else {