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:
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user