package org.webrtc; import android.annotation.TargetApi; import android.content.Context; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CaptureRequest; import android.os.Handler; import android.util.Range; import android.view.Surface; import androidx.annotation.Nullable; import c.d.b.a.a; import h0.c.d; import h0.c.l0; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import org.webrtc.CameraEnumerationAndroid; import org.webrtc.CameraSession; @TargetApi(21) public class Camera2Session implements CameraSession { private static final String TAG = "Camera2Session"; private static final Histogram camera2ResolutionHistogram = Histogram.createEnumeration("WebRTC.Android.Camera2.Resolution", CameraEnumerationAndroid.COMMON_RESOLUTIONS.size()); private static final Histogram camera2StartTimeMsHistogram = Histogram.createCounts("WebRTC.Android.Camera2.StartTimeMs", 1, 10000, 50); private static final Histogram camera2StopTimeMsHistogram = Histogram.createCounts("WebRTC.Android.Camera2.StopTimeMs", 1, 10000, 50); private final Context applicationContext; private final CameraSession.CreateSessionCallback callback; private CameraCharacteristics cameraCharacteristics; @Nullable private CameraDevice cameraDevice; private final String cameraId; private final CameraManager cameraManager; private int cameraOrientation; private final Handler cameraThreadHandler; private CameraEnumerationAndroid.CaptureFormat captureFormat; @Nullable private CameraCaptureSession captureSession; private final long constructionTimeNs; private final CameraSession.Events events; private boolean firstFrameReported; private int fpsUnitFactor; private final int framerate; private final int height; private boolean isCameraFrontFacing; private SessionState state = SessionState.RUNNING; @Nullable private Surface surface; private final SurfaceTextureHelper surfaceTextureHelper; private final int width; public static class CameraCaptureCallback extends CameraCaptureSession.CaptureCallback { private CameraCaptureCallback() { } @Override // android.hardware.camera2.CameraCaptureSession.CaptureCallback public void onCaptureFailed(CameraCaptureSession cameraCaptureSession, CaptureRequest captureRequest, CaptureFailure captureFailure) { Logging.d("Camera2Session", "Capture failed: " + captureFailure); } } public class CameraStateCallback extends CameraDevice.StateCallback { private CameraStateCallback() { } private String getErrorDescription(int i) { return i != 1 ? i != 2 ? i != 3 ? i != 4 ? i != 5 ? a.j("Unknown camera error: ", i) : "Camera service has encountered a fatal error." : "Camera device has encountered a fatal error." : "Camera device could not be opened due to a device policy." : "Camera device could not be opened because there are too many other open camera devices." : "Camera device is in use already."; } @Override // android.hardware.camera2.CameraDevice.StateCallback public void onClosed(CameraDevice cameraDevice) { Camera2Session.access$000(Camera2Session.this); Logging.d("Camera2Session", "Camera device closed."); Camera2Session.access$500(Camera2Session.this).onCameraClosed(Camera2Session.this); } @Override // android.hardware.camera2.CameraDevice.StateCallback public void onDisconnected(CameraDevice cameraDevice) { Camera2Session.access$000(Camera2Session.this); boolean z2 = Camera2Session.access$100(Camera2Session.this) == null && Camera2Session.access$200(Camera2Session.this) != SessionState.STOPPED; Camera2Session.access$202(Camera2Session.this, SessionState.STOPPED); Camera2Session.access$300(Camera2Session.this); if (z2) { Camera2Session.access$400(Camera2Session.this).onFailure(CameraSession.FailureType.DISCONNECTED, "Camera disconnected / evicted."); } else { Camera2Session.access$500(Camera2Session.this).onCameraDisconnected(Camera2Session.this); } } @Override // android.hardware.camera2.CameraDevice.StateCallback public void onError(CameraDevice cameraDevice, int i) { Camera2Session.access$000(Camera2Session.this); Camera2Session.access$600(Camera2Session.this, getErrorDescription(i)); } @Override // android.hardware.camera2.CameraDevice.StateCallback public void onOpened(CameraDevice cameraDevice) { Camera2Session.access$000(Camera2Session.this); Logging.d("Camera2Session", "Camera opened."); Camera2Session.access$702(Camera2Session.this, cameraDevice); Camera2Session.access$900(Camera2Session.this).setTextureSize(Camera2Session.access$800(Camera2Session.this).width, Camera2Session.access$800(Camera2Session.this).height); Camera2Session.access$1002(Camera2Session.this, new Surface(Camera2Session.access$900(Camera2Session.this).getSurfaceTexture())); try { cameraDevice.createCaptureSession(Arrays.asList(Camera2Session.access$1000(Camera2Session.this)), new CaptureSessionCallback(), Camera2Session.access$1200(Camera2Session.this)); } catch (CameraAccessException e) { Camera2Session camera2Session = Camera2Session.this; Camera2Session.access$600(camera2Session, "Failed to create capture session. " + e); } } } public class CaptureSessionCallback extends CameraCaptureSession.StateCallback { private CaptureSessionCallback() { } private void chooseFocusMode(CaptureRequest.Builder builder) { for (int i : (int[]) Camera2Session.access$1500(Camera2Session.this).get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES)) { if (i == 3) { builder.set(CaptureRequest.CONTROL_AF_MODE, 3); Logging.d("Camera2Session", "Using continuous video auto-focus."); return; } } Logging.d("Camera2Session", "Auto-focus is not available."); } private void chooseStabilizationMode(CaptureRequest.Builder builder) { int[] iArr = (int[]) Camera2Session.access$1500(Camera2Session.this).get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION); if (iArr != null) { for (int i : iArr) { if (i == 1) { builder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, 1); builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, 0); Logging.d("Camera2Session", "Using optical stabilization."); return; } } } for (int i2 : (int[]) Camera2Session.access$1500(Camera2Session.this).get(CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES)) { if (i2 == 1) { builder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, 1); builder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, 0); Logging.d("Camera2Session", "Using video stabilization."); return; } } Logging.d("Camera2Session", "Stabilization not available."); } /* access modifiers changed from: private */ /* renamed from: lambda$onConfigured$0 */ public /* synthetic */ void a(VideoFrame videoFrame) { Camera2Session.access$000(Camera2Session.this); if (Camera2Session.access$200(Camera2Session.this) != SessionState.RUNNING) { Logging.d("Camera2Session", "Texture frame captured but camera is no longer running."); return; } if (!Camera2Session.access$1600(Camera2Session.this)) { Camera2Session.access$1602(Camera2Session.this, true); Camera2Session.access$1800().addSample((int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - Camera2Session.access$1700(Camera2Session.this))); } VideoFrame videoFrame2 = new VideoFrame(l0.a((TextureBufferImpl) videoFrame.getBuffer(), Camera2Session.access$1900(Camera2Session.this), -Camera2Session.access$2000(Camera2Session.this)), Camera2Session.access$2100(Camera2Session.this), videoFrame.getTimestampNs()); Camera2Session.access$500(Camera2Session.this).onFrameCaptured(Camera2Session.this, videoFrame2); videoFrame2.release(); } @Override // android.hardware.camera2.CameraCaptureSession.StateCallback public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { Camera2Session.access$000(Camera2Session.this); cameraCaptureSession.close(); Camera2Session.access$600(Camera2Session.this, "Failed to configure capture session."); } @Override // android.hardware.camera2.CameraCaptureSession.StateCallback public void onConfigured(CameraCaptureSession cameraCaptureSession) { Camera2Session.access$000(Camera2Session.this); Logging.d("Camera2Session", "Camera capture session configured."); Camera2Session.access$102(Camera2Session.this, cameraCaptureSession); try { CaptureRequest.Builder createCaptureRequest = Camera2Session.access$700(Camera2Session.this).createCaptureRequest(3); createCaptureRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range(Integer.valueOf(Camera2Session.access$800(Camera2Session.this).framerate.min / Camera2Session.access$1300(Camera2Session.this)), Integer.valueOf(Camera2Session.access$800(Camera2Session.this).framerate.max / Camera2Session.access$1300(Camera2Session.this)))); createCaptureRequest.set(CaptureRequest.CONTROL_AE_MODE, 1); createCaptureRequest.set(CaptureRequest.CONTROL_AE_LOCK, Boolean.FALSE); chooseStabilizationMode(createCaptureRequest); chooseFocusMode(createCaptureRequest); createCaptureRequest.addTarget(Camera2Session.access$1000(Camera2Session.this)); cameraCaptureSession.setRepeatingRequest(createCaptureRequest.build(), new CameraCaptureCallback(), Camera2Session.access$1200(Camera2Session.this)); Camera2Session.access$900(Camera2Session.this).startListening(new d(this)); Logging.d("Camera2Session", "Camera device successfully started."); Camera2Session.access$400(Camera2Session.this).onDone(Camera2Session.this); } catch (CameraAccessException e) { Camera2Session camera2Session = Camera2Session.this; Camera2Session.access$600(camera2Session, "Failed to start capture request. " + e); } } } public enum SessionState { RUNNING, STOPPED } private Camera2Session(CameraSession.CreateSessionCallback createSessionCallback, CameraSession.Events events, Context context, CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, String str, int i, int i2, int i3) { Logging.d("Camera2Session", "Create new camera2 session on camera " + str); this.constructionTimeNs = System.nanoTime(); this.cameraThreadHandler = new Handler(); this.callback = createSessionCallback; this.events = events; this.applicationContext = context; this.cameraManager = cameraManager; this.surfaceTextureHelper = surfaceTextureHelper; this.cameraId = str; this.width = i; this.height = i2; this.framerate = i3; start(); } public static /* synthetic */ void access$000(Camera2Session camera2Session) { camera2Session.checkIsOnCameraThread(); } public static /* synthetic */ CameraCaptureSession access$100(Camera2Session camera2Session) { return camera2Session.captureSession; } public static /* synthetic */ Surface access$1000(Camera2Session camera2Session) { return camera2Session.surface; } public static /* synthetic */ Surface access$1002(Camera2Session camera2Session, Surface surface) { camera2Session.surface = surface; return surface; } public static /* synthetic */ CameraCaptureSession access$102(Camera2Session camera2Session, CameraCaptureSession cameraCaptureSession) { camera2Session.captureSession = cameraCaptureSession; return cameraCaptureSession; } public static /* synthetic */ Handler access$1200(Camera2Session camera2Session) { return camera2Session.cameraThreadHandler; } public static /* synthetic */ int access$1300(Camera2Session camera2Session) { return camera2Session.fpsUnitFactor; } public static /* synthetic */ CameraCharacteristics access$1500(Camera2Session camera2Session) { return camera2Session.cameraCharacteristics; } public static /* synthetic */ boolean access$1600(Camera2Session camera2Session) { return camera2Session.firstFrameReported; } public static /* synthetic */ boolean access$1602(Camera2Session camera2Session, boolean z2) { camera2Session.firstFrameReported = z2; return z2; } public static /* synthetic */ long access$1700(Camera2Session camera2Session) { return camera2Session.constructionTimeNs; } public static /* synthetic */ Histogram access$1800() { return camera2StartTimeMsHistogram; } public static /* synthetic */ boolean access$1900(Camera2Session camera2Session) { return camera2Session.isCameraFrontFacing; } public static /* synthetic */ SessionState access$200(Camera2Session camera2Session) { return camera2Session.state; } public static /* synthetic */ int access$2000(Camera2Session camera2Session) { return camera2Session.cameraOrientation; } public static /* synthetic */ SessionState access$202(Camera2Session camera2Session, SessionState sessionState) { camera2Session.state = sessionState; return sessionState; } public static /* synthetic */ int access$2100(Camera2Session camera2Session) { return camera2Session.getFrameOrientation(); } public static /* synthetic */ void access$300(Camera2Session camera2Session) { camera2Session.stopInternal(); } public static /* synthetic */ CameraSession.CreateSessionCallback access$400(Camera2Session camera2Session) { return camera2Session.callback; } public static /* synthetic */ CameraSession.Events access$500(Camera2Session camera2Session) { return camera2Session.events; } public static /* synthetic */ void access$600(Camera2Session camera2Session, String str) { camera2Session.reportError(str); } public static /* synthetic */ CameraDevice access$700(Camera2Session camera2Session) { return camera2Session.cameraDevice; } public static /* synthetic */ CameraDevice access$702(Camera2Session camera2Session, CameraDevice cameraDevice) { camera2Session.cameraDevice = cameraDevice; return cameraDevice; } public static /* synthetic */ CameraEnumerationAndroid.CaptureFormat access$800(Camera2Session camera2Session) { return camera2Session.captureFormat; } public static /* synthetic */ SurfaceTextureHelper access$900(Camera2Session camera2Session) { return camera2Session.surfaceTextureHelper; } private void checkIsOnCameraThread() { if (Thread.currentThread() != this.cameraThreadHandler.getLooper().getThread()) { throw new IllegalStateException("Wrong thread"); } } public static void create(CameraSession.CreateSessionCallback createSessionCallback, CameraSession.Events events, Context context, CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, String str, int i, int i2, int i3) { new Camera2Session(createSessionCallback, events, context, cameraManager, surfaceTextureHelper, str, i, i2, i3); } private void findCaptureFormat() { checkIsOnCameraThread(); Range[] rangeArr = (Range[]) this.cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES); int fpsUnitFactor = Camera2Enumerator.getFpsUnitFactor(rangeArr); this.fpsUnitFactor = fpsUnitFactor; List convertFramerates = Camera2Enumerator.convertFramerates(rangeArr, fpsUnitFactor); List supportedSizes = Camera2Enumerator.getSupportedSizes(this.cameraCharacteristics); Logging.d("Camera2Session", "Available preview sizes: " + supportedSizes); Logging.d("Camera2Session", "Available fps ranges: " + convertFramerates); if (convertFramerates.isEmpty() || supportedSizes.isEmpty()) { reportError("No supported capture formats."); return; } CameraEnumerationAndroid.CaptureFormat.FramerateRange closestSupportedFramerateRange = CameraEnumerationAndroid.getClosestSupportedFramerateRange(convertFramerates, this.framerate); Size closestSupportedSize = CameraEnumerationAndroid.getClosestSupportedSize(supportedSizes, this.width, this.height); CameraEnumerationAndroid.reportCameraResolution(camera2ResolutionHistogram, closestSupportedSize); this.captureFormat = new CameraEnumerationAndroid.CaptureFormat(closestSupportedSize.width, closestSupportedSize.height, closestSupportedFramerateRange); StringBuilder K = a.K("Using capture format: "); K.append(this.captureFormat); Logging.d("Camera2Session", K.toString()); } private int getFrameOrientation() { int b = l0.b(this.applicationContext); if (!this.isCameraFrontFacing) { b = 360 - b; } return (this.cameraOrientation + b) % 360; } private void openCamera() { checkIsOnCameraThread(); StringBuilder K = a.K("Opening camera "); K.append(this.cameraId); Logging.d("Camera2Session", K.toString()); this.events.onCameraOpening(); try { this.cameraManager.openCamera(this.cameraId, new CameraStateCallback(), this.cameraThreadHandler); } catch (CameraAccessException e) { reportError("Failed to open camera: " + e); } } private void reportError(String str) { checkIsOnCameraThread(); Logging.e("Camera2Session", "Error: " + str); boolean z2 = this.captureSession == null && this.state != SessionState.STOPPED; this.state = SessionState.STOPPED; stopInternal(); if (z2) { this.callback.onFailure(CameraSession.FailureType.ERROR, str); } else { this.events.onCameraError(this, str); } } private void start() { checkIsOnCameraThread(); Logging.d("Camera2Session", "start"); try { CameraCharacteristics cameraCharacteristics = this.cameraManager.getCameraCharacteristics(this.cameraId); this.cameraCharacteristics = cameraCharacteristics; this.cameraOrientation = ((Integer) cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)).intValue(); this.isCameraFrontFacing = ((Integer) this.cameraCharacteristics.get(CameraCharacteristics.LENS_FACING)).intValue() == 0; findCaptureFormat(); openCamera(); } catch (CameraAccessException e) { StringBuilder K = a.K("getCameraCharacteristics(): "); K.append(e.getMessage()); reportError(K.toString()); } } private void stopInternal() { Logging.d("Camera2Session", "Stop internal"); checkIsOnCameraThread(); this.surfaceTextureHelper.stopListening(); CameraCaptureSession cameraCaptureSession = this.captureSession; if (cameraCaptureSession != null) { cameraCaptureSession.close(); this.captureSession = null; } Surface surface = this.surface; if (surface != null) { surface.release(); this.surface = null; } CameraDevice cameraDevice = this.cameraDevice; if (cameraDevice != null) { cameraDevice.close(); this.cameraDevice = null; } Logging.d("Camera2Session", "Stop done"); } @Override // org.webrtc.CameraSession public void stop() { StringBuilder K = a.K("Stop camera2 session on camera "); K.append(this.cameraId); Logging.d("Camera2Session", K.toString()); checkIsOnCameraThread(); SessionState sessionState = this.state; SessionState sessionState2 = SessionState.STOPPED; if (sessionState != sessionState2) { long nanoTime = System.nanoTime(); this.state = sessionState2; stopInternal(); camera2StopTimeMsHistogram.addSample((int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - nanoTime)); } } }