Add option to set maximum video encoder bitrate to AppRTCDemo.

BUG=b/30951236

Review-Url: https://codereview.webrtc.org/2306433002
Cr-Commit-Position: refs/heads/master@{#14028}
This commit is contained in:
glaznev
2016-09-01 11:49:45 -07:00
committed by Commit bot
parent f9e1b922ef
commit a70856c0bf
6 changed files with 93 additions and 50 deletions

View File

@ -59,15 +59,15 @@
<string name="pref_capturequalityslider_dlg">Enable slider for changing capture quality.</string> <string name="pref_capturequalityslider_dlg">Enable slider for changing capture quality.</string>
<string name="pref_capturequalityslider_default">false</string> <string name="pref_capturequalityslider_default">false</string>
<string name="pref_startvideobitrate_key">startvideobitrate_preference</string> <string name="pref_maxvideobitrate_key">maxvideobitrate_preference</string>
<string name="pref_startvideobitrate_title">Start video bitrate setting.</string> <string name="pref_maxvideobitrate_title">Maximum video bitrate setting.</string>
<string name="pref_startvideobitrate_dlg">Start video bitrate setting.</string> <string name="pref_maxvideobitrate_dlg">Maximum video bitrate setting.</string>
<string name="pref_startvideobitrate_default">Default</string> <string name="pref_maxvideobitrate_default">Default</string>
<string name="pref_startvideobitratevalue_key">startvideobitratevalue_preference</string> <string name="pref_maxvideobitratevalue_key">maxvideobitratevalue_preference</string>
<string name="pref_startvideobitratevalue_title">Video encoder start bitrate.</string> <string name="pref_maxvideobitratevalue_title">Video encoder maximum bitrate.</string>
<string name="pref_startvideobitratevalue_dlg">Enter video encoder start bitrate in kbps.</string> <string name="pref_maxvideobitratevalue_dlg">Enter video encoder maximum bitrate in kbps.</string>
<string name="pref_startvideobitratevalue_default">1000</string> <string name="pref_maxvideobitratevalue_default">1700</string>
<string name="pref_videocodec_key">videocodec_preference</string> <string name="pref_videocodec_key">videocodec_preference</string>
<string name="pref_videocodec_title">Default video codec.</string> <string name="pref_videocodec_title">Default video codec.</string>

View File

@ -38,19 +38,19 @@
android:defaultValue="@string/pref_capturequalityslider_default" /> android:defaultValue="@string/pref_capturequalityslider_default" />
<ListPreference <ListPreference
android:key="@string/pref_startvideobitrate_key" android:key="@string/pref_maxvideobitrate_key"
android:title="@string/pref_startvideobitrate_title" android:title="@string/pref_maxvideobitrate_title"
android:defaultValue="@string/pref_startvideobitrate_default" android:defaultValue="@string/pref_maxvideobitrate_default"
android:dialogTitle="@string/pref_startvideobitrate_dlg" android:dialogTitle="@string/pref_maxvideobitrate_dlg"
android:entries="@array/startBitrate" android:entries="@array/startBitrate"
android:entryValues="@array/startBitrate" /> android:entryValues="@array/startBitrate" />
<EditTextPreference <EditTextPreference
android:key="@string/pref_startvideobitratevalue_key" android:key="@string/pref_maxvideobitratevalue_key"
android:title="@string/pref_startvideobitratevalue_title" android:title="@string/pref_maxvideobitratevalue_title"
android:inputType="number" android:inputType="number"
android:defaultValue="@string/pref_startvideobitratevalue_default" android:defaultValue="@string/pref_maxvideobitratevalue_default"
android:dialogTitle="@string/pref_startvideobitratevalue_dlg" /> android:dialogTitle="@string/pref_maxvideobitratevalue_dlg" />
<ListPreference <ListPreference
android:key="@string/pref_videocodec_key" android:key="@string/pref_videocodec_key"

View File

@ -658,6 +658,10 @@ public class CallActivity extends Activity
appRtcClient.sendAnswerSdp(sdp); appRtcClient.sendAnswerSdp(sdp);
} }
} }
if (peerConnectionParameters.videoMaxBitrate > 0) {
Log.d(TAG, "Set video maximum bitrate: " + peerConnectionParameters.videoMaxBitrate);
peerConnectionClient.setVideoMaxBitrate(peerConnectionParameters.videoMaxBitrate);
}
} }
}); });
} }

View File

@ -94,8 +94,8 @@ public class ConnectActivity extends Activity {
keyprefResolution = getString(R.string.pref_resolution_key); keyprefResolution = getString(R.string.pref_resolution_key);
keyprefFps = getString(R.string.pref_fps_key); keyprefFps = getString(R.string.pref_fps_key);
keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key); keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key);
keyprefVideoBitrateType = getString(R.string.pref_startvideobitrate_key); keyprefVideoBitrateType = getString(R.string.pref_maxvideobitrate_key);
keyprefVideoBitrateValue = getString(R.string.pref_startvideobitratevalue_key); keyprefVideoBitrateValue = getString(R.string.pref_maxvideobitratevalue_key);
keyprefVideoCodec = getString(R.string.pref_videocodec_key); keyprefVideoCodec = getString(R.string.pref_videocodec_key);
keyprefHwCodecAcceleration = getString(R.string.pref_hwcodec_key); keyprefHwCodecAcceleration = getString(R.string.pref_hwcodec_key);
keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key); keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key);
@ -357,12 +357,12 @@ public class ConnectActivity extends Activity {
// Get video and audio start bitrate. // Get video and audio start bitrate.
int videoStartBitrate = 0; int videoStartBitrate = 0;
String bitrateTypeDefault = getString( String bitrateTypeDefault = getString(
R.string.pref_startvideobitrate_default); R.string.pref_maxvideobitrate_default);
String bitrateType = sharedPref.getString( String bitrateType = sharedPref.getString(
keyprefVideoBitrateType, bitrateTypeDefault); keyprefVideoBitrateType, bitrateTypeDefault);
if (!bitrateType.equals(bitrateTypeDefault)) { if (!bitrateType.equals(bitrateTypeDefault)) {
String bitrateValue = sharedPref.getString(keyprefVideoBitrateValue, String bitrateValue = sharedPref.getString(keyprefVideoBitrateValue,
getString(R.string.pref_startvideobitratevalue_default)); getString(R.string.pref_maxvideobitratevalue_default));
videoStartBitrate = Integer.parseInt(bitrateValue); videoStartBitrate = Integer.parseInt(bitrateValue);
} }
int audioStartBitrate = 0; int audioStartBitrate = 0;

View File

@ -29,11 +29,12 @@ import org.webrtc.EglBase;
import org.webrtc.IceCandidate; import org.webrtc.IceCandidate;
import org.webrtc.Logging; import org.webrtc.Logging;
import org.webrtc.MediaConstraints; import org.webrtc.MediaConstraints;
import org.webrtc.MediaConstraints.KeyValuePair;
import org.webrtc.MediaStream; import org.webrtc.MediaStream;
import org.webrtc.PeerConnection; import org.webrtc.PeerConnection;
import org.webrtc.PeerConnection.IceConnectionState; import org.webrtc.PeerConnection.IceConnectionState;
import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory;
import org.webrtc.RtpParameters;
import org.webrtc.RtpSender;
import org.webrtc.SdpObserver; import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription; import org.webrtc.SessionDescription;
import org.webrtc.StatsObserver; import org.webrtc.StatsObserver;
@ -66,6 +67,7 @@ import java.util.regex.Pattern;
public class PeerConnectionClient { public class PeerConnectionClient {
public static final String VIDEO_TRACK_ID = "ARDAMSv0"; public static final String VIDEO_TRACK_ID = "ARDAMSv0";
public static final String AUDIO_TRACK_ID = "ARDAMSa0"; 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 TAG = "PCRTCClient";
private static final String VIDEO_CODEC_VP8 = "VP8"; private static final String VIDEO_CODEC_VP8 = "VP8";
private static final String VIDEO_CODEC_VP9 = "VP9"; 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_HIGH_PASS_FILTER_CONSTRAINT = "googHighpassFilter";
private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSuppression"; private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSuppression";
private static final String AUDIO_LEVEL_CONTROL_CONSTRAINT = "levelControl"; 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 String DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT = "DtlsSrtpKeyAgreement";
private static final int HD_VIDEO_WIDTH = 1280; private static final int HD_VIDEO_WIDTH = 1280;
private static final int HD_VIDEO_HEIGHT = 720; private static final int HD_VIDEO_HEIGHT = 720;
private static final int MAX_VIDEO_WIDTH = 1280; private static final int MAX_VIDEO_WIDTH = 1280;
private static final int MAX_VIDEO_HEIGHT = 1280; private static final int MAX_VIDEO_HEIGHT = 1280;
private static final int MAX_VIDEO_FPS = 30; private static final int MAX_VIDEO_FPS = 30;
private static final int BPS_IN_KBPS = 1000;
private static final PeerConnectionClient instance = new PeerConnectionClient(); private static final PeerConnectionClient instance = new PeerConnectionClient();
private final PCObserver pcObserver = new PCObserver(); private final PCObserver pcObserver = new PCObserver();
@ -135,6 +132,7 @@ public class PeerConnectionClient {
private boolean renderVideo; private boolean renderVideo;
private VideoTrack localVideoTrack; private VideoTrack localVideoTrack;
private VideoTrack remoteVideoTrack; private VideoTrack remoteVideoTrack;
private RtpSender localVideoSender;
// enableAudio is set to true if audio should be sent. // enableAudio is set to true if audio should be sent.
private boolean enableAudio; private boolean enableAudio;
private AudioTrack localAudioTrack; private AudioTrack localAudioTrack;
@ -150,7 +148,7 @@ public class PeerConnectionClient {
public final int videoWidth; public final int videoWidth;
public final int videoHeight; public final int videoHeight;
public final int videoFps; public final int videoFps;
public final int videoStartBitrate; public final int videoMaxBitrate;
public final String videoCodec; public final String videoCodec;
public final boolean videoCodecHwAcceleration; public final boolean videoCodecHwAcceleration;
public final boolean captureToTexture; public final boolean captureToTexture;
@ -167,7 +165,7 @@ public class PeerConnectionClient {
public PeerConnectionParameters( public PeerConnectionParameters(
boolean videoCallEnabled, boolean loopback, boolean tracing, boolean useCamera2, boolean videoCallEnabled, boolean loopback, boolean tracing, boolean useCamera2,
int videoWidth, int videoHeight, int videoFps, 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 captureToTexture, int audioStartBitrate, String audioCodec,
boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES,
boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBuiltInNS,
@ -179,7 +177,7 @@ public class PeerConnectionClient {
this.videoWidth = videoWidth; this.videoWidth = videoWidth;
this.videoHeight = videoHeight; this.videoHeight = videoHeight;
this.videoFps = videoFps; this.videoFps = videoFps;
this.videoStartBitrate = videoStartBitrate; this.videoMaxBitrate = videoMaxBitrate;
this.videoCodec = videoCodec; this.videoCodec = videoCodec;
this.videoCodecHwAcceleration = videoCodecHwAcceleration; this.videoCodecHwAcceleration = videoCodecHwAcceleration;
this.captureToTexture = captureToTexture; this.captureToTexture = captureToTexture;
@ -278,6 +276,7 @@ public class PeerConnectionClient {
renderVideo = true; renderVideo = true;
localVideoTrack = null; localVideoTrack = null;
remoteVideoTrack = null; remoteVideoTrack = null;
localVideoSender = null;
enableAudio = true; enableAudio = true;
localAudioTrack = null; localAudioTrack = null;
statsTimer = new Timer(); statsTimer = new Timer();
@ -567,6 +566,9 @@ public class PeerConnectionClient {
mediaStream.addTrack(createAudioTrack()); mediaStream.addTrack(createAudioTrack());
peerConnection.addStream(mediaStream); peerConnection.addStream(mediaStream);
if (videoCallEnabled) {
findVideoSender();
}
if (peerConnectionParameters.aecDump) { if (peerConnectionParameters.aecDump) {
try { try {
@ -770,14 +772,6 @@ public class PeerConnectionClient {
if (videoCallEnabled) { if (videoCallEnabled) {
sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, false); 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) { if (peerConnectionParameters.audioStartBitrate > 0) {
sdpDescription = setStartBitrate(AUDIO_CODEC_OPUS, false, sdpDescription = setStartBitrate(AUDIO_CODEC_OPUS, false,
sdpDescription, peerConnectionParameters.audioStartBitrate); 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) { private void reportError(final String errorMessage) {
Log.e(TAG, "Peerconnection error: " + errorMessage); Log.e(TAG, "Peerconnection error: " + errorMessage);
executor.execute(new Runnable() { executor.execute(new Runnable() {
@ -848,6 +875,18 @@ public class PeerConnectionClient {
return localVideoTrack; 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, private static String setStartBitrate(String codec, boolean isVideoCodec,
String sdpDescription, int bitrateKbps) { String sdpDescription, int bitrateKbps) {
String[] lines = sdpDescription.split("\r\n"); String[] lines = sdpDescription.split("\r\n");

View File

@ -31,8 +31,8 @@ public class SettingsActivity extends Activity
private String keyprefResolution; private String keyprefResolution;
private String keyprefFps; private String keyprefFps;
private String keyprefCaptureQualitySlider; private String keyprefCaptureQualitySlider;
private String keyprefStartVideoBitrateType; private String keyprefMaxVideoBitrateType;
private String keyprefStartVideoBitrateValue; private String keyprefMaxVideoBitrateValue;
private String keyPrefVideoCodec; private String keyPrefVideoCodec;
private String keyprefHwCodec; private String keyprefHwCodec;
private String keyprefCaptureToTexture; private String keyprefCaptureToTexture;
@ -61,8 +61,8 @@ public class SettingsActivity extends Activity
keyprefResolution = getString(R.string.pref_resolution_key); keyprefResolution = getString(R.string.pref_resolution_key);
keyprefFps = getString(R.string.pref_fps_key); keyprefFps = getString(R.string.pref_fps_key);
keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key); keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key);
keyprefStartVideoBitrateType = getString(R.string.pref_startvideobitrate_key); keyprefMaxVideoBitrateType = getString(R.string.pref_maxvideobitrate_key);
keyprefStartVideoBitrateValue = getString(R.string.pref_startvideobitratevalue_key); keyprefMaxVideoBitrateValue = getString(R.string.pref_maxvideobitratevalue_key);
keyPrefVideoCodec = getString(R.string.pref_videocodec_key); keyPrefVideoCodec = getString(R.string.pref_videocodec_key);
keyprefHwCodec = getString(R.string.pref_hwcodec_key); keyprefHwCodec = getString(R.string.pref_hwcodec_key);
keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key); keyprefCaptureToTexture = getString(R.string.pref_capturetotexture_key);
@ -102,8 +102,8 @@ public class SettingsActivity extends Activity
updateSummary(sharedPreferences, keyprefResolution); updateSummary(sharedPreferences, keyprefResolution);
updateSummary(sharedPreferences, keyprefFps); updateSummary(sharedPreferences, keyprefFps);
updateSummaryB(sharedPreferences, keyprefCaptureQualitySlider); updateSummaryB(sharedPreferences, keyprefCaptureQualitySlider);
updateSummary(sharedPreferences, keyprefStartVideoBitrateType); updateSummary(sharedPreferences, keyprefMaxVideoBitrateType);
updateSummaryBitrate(sharedPreferences, keyprefStartVideoBitrateValue); updateSummaryBitrate(sharedPreferences, keyprefMaxVideoBitrateValue);
setVideoBitrateEnable(sharedPreferences); setVideoBitrateEnable(sharedPreferences);
updateSummary(sharedPreferences, keyPrefVideoCodec); updateSummary(sharedPreferences, keyPrefVideoCodec);
updateSummaryB(sharedPreferences, keyprefHwCodec); updateSummaryB(sharedPreferences, keyprefHwCodec);
@ -177,13 +177,13 @@ public class SettingsActivity extends Activity
String key) { String key) {
if (key.equals(keyprefResolution) if (key.equals(keyprefResolution)
|| key.equals(keyprefFps) || key.equals(keyprefFps)
|| key.equals(keyprefStartVideoBitrateType) || key.equals(keyprefMaxVideoBitrateType)
|| key.equals(keyPrefVideoCodec) || key.equals(keyPrefVideoCodec)
|| key.equals(keyprefStartAudioBitrateType) || key.equals(keyprefStartAudioBitrateType)
|| key.equals(keyPrefAudioCodec) || key.equals(keyPrefAudioCodec)
|| key.equals(keyPrefRoomServerUrl)) { || key.equals(keyPrefRoomServerUrl)) {
updateSummary(sharedPreferences, key); updateSummary(sharedPreferences, key);
} else if (key.equals(keyprefStartVideoBitrateValue) } else if (key.equals(keyprefMaxVideoBitrateValue)
|| key.equals(keyprefStartAudioBitrateValue)) { || key.equals(keyprefStartAudioBitrateValue)) {
updateSummaryBitrate(sharedPreferences, key); updateSummaryBitrate(sharedPreferences, key);
} else if (key.equals(keyprefVideoCall) } else if (key.equals(keyprefVideoCall)
@ -204,7 +204,7 @@ public class SettingsActivity extends Activity
} else if (key.equals(keyprefSpeakerphone)) { } else if (key.equals(keyprefSpeakerphone)) {
updateSummaryList(sharedPreferences, key); updateSummaryList(sharedPreferences, key);
} }
if (key.equals(keyprefStartVideoBitrateType)) { if (key.equals(keyprefMaxVideoBitrateType)) {
setVideoBitrateEnable(sharedPreferences); setVideoBitrateEnable(sharedPreferences);
} }
if (key.equals(keyprefStartAudioBitrateType)) { if (key.equals(keyprefStartAudioBitrateType)) {
@ -238,10 +238,10 @@ public class SettingsActivity extends Activity
private void setVideoBitrateEnable(SharedPreferences sharedPreferences) { private void setVideoBitrateEnable(SharedPreferences sharedPreferences) {
Preference bitratePreferenceValue = Preference bitratePreferenceValue =
settingsFragment.findPreference(keyprefStartVideoBitrateValue); settingsFragment.findPreference(keyprefMaxVideoBitrateValue);
String bitrateTypeDefault = getString(R.string.pref_startvideobitrate_default); String bitrateTypeDefault = getString(R.string.pref_maxvideobitrate_default);
String bitrateType = sharedPreferences.getString( String bitrateType = sharedPreferences.getString(
keyprefStartVideoBitrateType, bitrateTypeDefault); keyprefMaxVideoBitrateType, bitrateTypeDefault);
if (bitrateType.equals(bitrateTypeDefault)) { if (bitrateType.equals(bitrateTypeDefault)) {
bitratePreferenceValue.setEnabled(false); bitratePreferenceValue.setEnabled(false);
} else { } else {