Camera2 in AppRTC Android Demo.

Add an option to use Camera2 implemantion of CameraVideoCapturer in
AppRTC Android Demo. It is enabled by default.

BUG=webrtc:5519

Review-Url: https://codereview.webrtc.org/2077663003
Cr-Commit-Position: refs/heads/master@{#13391}
This commit is contained in:
sakal
2016-07-06 00:58:29 -07:00
committed by Commit bot
parent 9c0b551425
commit b224d80166
7 changed files with 124 additions and 39 deletions

View File

@ -10,6 +10,11 @@
package org.appspot.apprtc;
import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
import org.appspot.apprtc.AppRTCClient.SignalingParameters;
import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
import org.appspot.apprtc.util.LooperExecutor;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
@ -25,10 +30,7 @@ import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.Toast;
import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
import org.appspot.apprtc.AppRTCClient.SignalingParameters;
import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
import org.appspot.apprtc.util.LooperExecutor;
import org.webrtc.Camera2Enumerator;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.PeerConnectionFactory;
@ -52,6 +54,8 @@ public class CallActivity extends Activity
"org.appspot.apprtc.LOOPBACK";
public static final String EXTRA_VIDEO_CALL =
"org.appspot.apprtc.VIDEO_CALL";
public static final String EXTRA_CAMERA2 =
"org.appspot.apprtc.CAMERA2";
public static final String EXTRA_VIDEO_WIDTH =
"org.appspot.apprtc.VIDEO_WIDTH";
public static final String EXTRA_VIDEO_HEIGHT =
@ -219,12 +223,18 @@ public class CallActivity extends Activity
finish();
return;
}
boolean loopback = intent.getBooleanExtra(EXTRA_LOOPBACK, false);
boolean tracing = intent.getBooleanExtra(EXTRA_TRACING, false);
boolean useCamera2 = Camera2Enumerator.isSupported()
&& intent.getBooleanExtra(EXTRA_CAMERA2, true);
peerConnectionParameters = new PeerConnectionParameters(
intent.getBooleanExtra(EXTRA_VIDEO_CALL, true),
loopback,
tracing,
useCamera2,
intent.getIntExtra(EXTRA_VIDEO_WIDTH, 0),
intent.getIntExtra(EXTRA_VIDEO_HEIGHT, 0),
intent.getIntExtra(EXTRA_VIDEO_FPS, 0),

View File

@ -55,6 +55,7 @@ public class ConnectActivity extends Activity {
private ListView roomListView;
private SharedPreferences sharedPref;
private String keyprefVideoCallEnabled;
private String keyprefCamera2;
private String keyprefResolution;
private String keyprefFps;
private String keyprefCaptureQualitySlider;
@ -86,6 +87,7 @@ public class ConnectActivity extends Activity {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
keyprefVideoCallEnabled = getString(R.string.pref_videocall_key);
keyprefCamera2 = getString(R.string.pref_camera2_key);
keyprefResolution = getString(R.string.pref_resolution_key);
keyprefFps = getString(R.string.pref_fps_key);
keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key);
@ -259,6 +261,10 @@ public class ConnectActivity extends Activity {
boolean videoCallEnabled = sharedPref.getBoolean(keyprefVideoCallEnabled,
Boolean.valueOf(getString(R.string.pref_videocall_default)));
// Use Camera2 option.
boolean useCamera2 = sharedPref.getBoolean(keyprefCamera2,
Boolean.valueOf(getString(R.string.pref_camera2_default)));
// Get default codecs.
String videoCodec = sharedPref.getString(keyprefVideoCodec,
getString(R.string.pref_videocodec_default));
@ -364,6 +370,7 @@ public class ConnectActivity extends Activity {
intent.putExtra(CallActivity.EXTRA_ROOMID, roomId);
intent.putExtra(CallActivity.EXTRA_LOOPBACK, loopback);
intent.putExtra(CallActivity.EXTRA_VIDEO_CALL, videoCallEnabled);
intent.putExtra(CallActivity.EXTRA_CAMERA2, useCamera2);
intent.putExtra(CallActivity.EXTRA_VIDEO_WIDTH, videoWidth);
intent.putExtra(CallActivity.EXTRA_VIDEO_HEIGHT, videoHeight);
intent.putExtra(CallActivity.EXTRA_VIDEO_FPS, cameraFps);

View File

@ -19,7 +19,11 @@ import android.util.Log;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerationAndroid;
import org.webrtc.CameraEnumerator;
import org.webrtc.CameraVideoCapturer;
import org.webrtc.DataChannel;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
@ -35,7 +39,7 @@ import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.StatsObserver;
import org.webrtc.StatsReport;
import org.webrtc.VideoCapturerAndroid;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
@ -48,7 +52,6 @@ import java.util.EnumSet;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.regex.Matcher;
@ -95,6 +98,7 @@ public class PeerConnectionClient {
private final SDPObserver sdpObserver = new SDPObserver();
private final ScheduledExecutorService executor;
private Context context;
private PeerConnectionFactory factory;
private PeerConnection peerConnection;
PeerConnectionFactory.Options options = null;
@ -124,7 +128,7 @@ public class PeerConnectionClient {
private SessionDescription localSdp; // either offer or answer SDP
private MediaStream mediaStream;
private int numberOfCameras;
private VideoCapturerAndroid videoCapturer;
private CameraVideoCapturer videoCapturer;
// enableVideo is set to true if video should be rendered and sent.
private boolean renderVideo;
private VideoTrack localVideoTrack;
@ -140,6 +144,7 @@ public class PeerConnectionClient {
public final boolean videoCallEnabled;
public final boolean loopback;
public final boolean tracing;
public final boolean useCamera2;
public final int videoWidth;
public final int videoHeight;
public final int videoFps;
@ -155,13 +160,14 @@ public class PeerConnectionClient {
public final boolean disableBuiltInAEC;
public PeerConnectionParameters(
boolean videoCallEnabled, boolean loopback, boolean tracing,
int videoWidth, int videoHeight, int videoFps, int videoStartBitrate,
String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTexture,
int audioStartBitrate, String audioCodec,
boolean videoCallEnabled, boolean loopback, boolean tracing, boolean useCamera2,
int videoWidth, int videoHeight, int videoFps,
int videoStartBitrate, String videoCodec, boolean videoCodecHwAcceleration,
boolean captureToTexture, int audioStartBitrate, String audioCodec,
boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES,
boolean disableBuiltInAEC) {
this.videoCallEnabled = videoCallEnabled;
this.useCamera2 = useCamera2;
this.loopback = loopback;
this.tracing = tracing;
this.videoWidth = videoWidth;
@ -250,6 +256,7 @@ public class PeerConnectionClient {
this.events = events;
videoCallEnabled = peerConnectionParameters.videoCallEnabled;
// Reset variables to initial states.
this.context = null;
factory = null;
peerConnection = null;
preferIsac = false;
@ -367,6 +374,7 @@ public class PeerConnectionClient {
if (options != null) {
Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMask);
}
this.context = context;
factory = new PeerConnectionFactory(options);
Log.d(TAG, "Peer connection factory created.");
}
@ -456,6 +464,36 @@ public class PeerConnectionClient {
}
}
private void createCapturer(CameraEnumerator enumerator) {
final String[] deviceNames = enumerator.getDeviceNames();
// First, try to find front facing camera
Logging.d(TAG, "Looking for front facing cameras.");
for (String deviceName : deviceNames) {
if (enumerator.isFrontFacing(deviceName)) {
Logging.d(TAG, "Creating front facing camera capturer.");
videoCapturer = enumerator.createCapturer(deviceName, null);
if (videoCapturer != null) {
return;
}
}
}
// Front facing camera not found, try something else
Logging.d(TAG, "Looking for other cameras.");
for (String deviceName : deviceNames) {
if (!enumerator.isFrontFacing(deviceName)) {
Logging.d(TAG, "Creating other camera capturer.");
videoCapturer = enumerator.createCapturer(deviceName, null);
if (videoCapturer != null) {
return;
}
}
}
}
private void createPeerConnectionInternal(EglBase.Context renderEGLContext) {
if (factory == null || isError) {
Log.e(TAG, "Peerconnection factory is not created");
@ -498,15 +536,19 @@ public class PeerConnectionClient {
mediaStream = factory.createLocalMediaStream("ARDAMS");
if (videoCallEnabled) {
String cameraDeviceName = CameraEnumerationAndroid.getDeviceName(0);
String frontCameraDeviceName =
CameraEnumerationAndroid.getNameOfFrontFacingDevice();
if (numberOfCameras > 1 && frontCameraDeviceName != null) {
cameraDeviceName = frontCameraDeviceName;
if (peerConnectionParameters.useCamera2) {
if (!peerConnectionParameters.captureToTexture) {
reportError(context.getString(R.string.camera2_texture_only_error));
return;
}
Logging.d(TAG, "Creating capturer using camera2 API.");
createCapturer(new Camera2Enumerator(context));
} else {
Logging.d(TAG, "Creating capturer using camera1 API.");
createCapturer(new Camera1Enumerator(peerConnectionParameters.captureToTexture));
}
Log.d(TAG, "Opening camera: " + cameraDeviceName);
videoCapturer = VideoCapturerAndroid.create(cameraDeviceName, null,
peerConnectionParameters.captureToTexture);
if (videoCapturer == null) {
reportError("Failed to open camera");
return;
@ -791,7 +833,7 @@ public class PeerConnectionClient {
return localAudioTrack;
}
private VideoTrack createVideoTrack(VideoCapturerAndroid capturer) {
private VideoTrack createVideoTrack(VideoCapturer capturer) {
videoSource = factory.createVideoSource(capturer, videoConstraints);
localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource);

View File

@ -14,8 +14,10 @@ import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import org.webrtc.Camera2Enumerator;
import org.webrtc.voiceengine.WebRtcAudioUtils;
/**
@ -25,6 +27,7 @@ public class SettingsActivity extends Activity
implements OnSharedPreferenceChangeListener{
private SettingsFragment settingsFragment;
private String keyprefVideoCall;
private String keyprefCamera2;
private String keyprefResolution;
private String keyprefFps;
private String keyprefCaptureQualitySlider;
@ -50,6 +53,7 @@ public class SettingsActivity extends Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
keyprefVideoCall = getString(R.string.pref_videocall_key);
keyprefCamera2 = getString(R.string.pref_camera2_key);
keyprefResolution = getString(R.string.pref_resolution_key);
keyprefFps = getString(R.string.pref_fps_key);
keyprefCaptureQualitySlider = getString(R.string.pref_capturequalityslider_key);
@ -86,6 +90,7 @@ public class SettingsActivity extends Activity
settingsFragment.getPreferenceScreen().getSharedPreferences();
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
updateSummaryB(sharedPreferences, keyprefVideoCall);
updateSummaryB(sharedPreferences, keyprefCamera2);
updateSummary(sharedPreferences, keyprefResolution);
updateSummary(sharedPreferences, keyprefFps);
updateSummaryB(sharedPreferences, keyprefCaptureQualitySlider);
@ -109,6 +114,14 @@ public class SettingsActivity extends Activity
updateSummaryB(sharedPreferences, keyPrefDisplayHud);
updateSummaryB(sharedPreferences, keyPrefTracing);
if (!Camera2Enumerator.isSupported()) {
Preference camera2Preference =
settingsFragment.findPreference(keyprefCamera2);
camera2Preference.setSummary(getString(R.string.pref_camera2_not_supported));
camera2Preference.setEnabled(false);
}
// Disable forcing WebRTC based AEC so it won't affect our value.
// Otherwise, if it was enabled, isAcousticEchoCancelerSupported would always return false.
WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(false);
@ -116,7 +129,6 @@ public class SettingsActivity extends Activity
Preference disableBuiltInAECPreference =
settingsFragment.findPreference(keyprefDisableBuiltInAEC);
disableBuiltInAECPreference.setSummary(getString(R.string.pref_built_in_aec_not_available));
disableBuiltInAECPreference.setEnabled(false);
}
@ -145,6 +157,7 @@ public class SettingsActivity extends Activity
|| key.equals(keyprefStartAudioBitrateValue)) {
updateSummaryBitrate(sharedPreferences, key);
} else if (key.equals(keyprefVideoCall)
|| key.equals(keyprefCamera2)
|| key.equals(keyPrefTracing)
|| key.equals(keyprefCaptureQualitySlider)
|| key.equals(keyprefHwCodec)