510 lines
16 KiB
Java
510 lines
16 KiB
Java
package com.google.android.gms.vision;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.ImageFormat;
|
|
import android.graphics.SurfaceTexture;
|
|
import android.hardware.Camera;
|
|
import android.os.SystemClock;
|
|
import android.view.SurfaceHolder;
|
|
import android.view.WindowManager;
|
|
import com.google.android.gms.common.images.Size;
|
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
|
|
import com.google.android.gms.vision.Frame;
|
|
import java.io.IOException;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import org.bouncycastle.crypto.tls.CipherSuite;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public class CameraSource {
|
|
public static final int CAMERA_FACING_BACK = 0;
|
|
public static final int CAMERA_FACING_FRONT = 1;
|
|
private int facing;
|
|
private int rotation;
|
|
private Context zze;
|
|
private final Object zzf;
|
|
private Camera zzg;
|
|
private Size zzh;
|
|
private float zzi;
|
|
private int zzj;
|
|
private int zzk;
|
|
private boolean zzl;
|
|
private SurfaceTexture zzm;
|
|
private boolean zzn;
|
|
private Thread zzo;
|
|
private zzb zzp;
|
|
private Map<byte[], ByteBuffer> zzq;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public interface PictureCallback {
|
|
void onPictureTaken(byte[] bArr);
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
public interface ShutterCallback {
|
|
void onShutter();
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes2.dex */
|
|
public final class zza implements Camera.PreviewCallback {
|
|
private final CameraSource zzt;
|
|
|
|
private zza(CameraSource cameraSource) {
|
|
this.zzt = cameraSource;
|
|
}
|
|
|
|
@Override // android.hardware.Camera.PreviewCallback
|
|
public final void onPreviewFrame(byte[] bArr, Camera camera) {
|
|
this.zzt.zzp.zza(bArr, camera);
|
|
}
|
|
}
|
|
|
|
public void release() {
|
|
synchronized (this.zzf) {
|
|
stop();
|
|
this.zzp.release();
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
final class zzc implements Camera.PictureCallback {
|
|
private final CameraSource zzt;
|
|
private PictureCallback zzz;
|
|
|
|
private zzc(CameraSource cameraSource) {
|
|
this.zzt = cameraSource;
|
|
}
|
|
|
|
@Override // android.hardware.Camera.PictureCallback
|
|
public final void onPictureTaken(byte[] bArr, Camera camera) {
|
|
PictureCallback pictureCallback = this.zzz;
|
|
if (pictureCallback != null) {
|
|
pictureCallback.onPictureTaken(bArr);
|
|
}
|
|
synchronized (this.zzt.zzf) {
|
|
if (this.zzt.zzg != null) {
|
|
this.zzt.zzg.startPreview();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
static final class zzd implements Camera.ShutterCallback {
|
|
private ShutterCallback zzaa;
|
|
|
|
private zzd() {
|
|
}
|
|
|
|
@Override // android.hardware.Camera.ShutterCallback
|
|
public final void onShutter() {
|
|
ShutterCallback shutterCallback = this.zzaa;
|
|
if (shutterCallback != null) {
|
|
shutterCallback.onShutter();
|
|
}
|
|
}
|
|
}
|
|
|
|
public CameraSource start() throws IOException {
|
|
synchronized (this.zzf) {
|
|
if (this.zzg != null) {
|
|
return this;
|
|
}
|
|
this.zzg = zza();
|
|
SurfaceTexture surfaceTexture = new SurfaceTexture(100);
|
|
this.zzm = surfaceTexture;
|
|
this.zzg.setPreviewTexture(surfaceTexture);
|
|
this.zzn = true;
|
|
this.zzg.startPreview();
|
|
Thread thread = new Thread(this.zzp);
|
|
this.zzo = thread;
|
|
thread.setName("gms.vision.CameraSource");
|
|
this.zzp.setActive(true);
|
|
this.zzo.start();
|
|
return this;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes2.dex */
|
|
public final class zzb implements Runnable {
|
|
private Detector<?> zzr;
|
|
private final CameraSource zzt;
|
|
private long zzw;
|
|
private ByteBuffer zzy;
|
|
private long zzu = SystemClock.elapsedRealtime();
|
|
private final Object lock = new Object();
|
|
private boolean zzv = true;
|
|
private int zzx = 0;
|
|
|
|
zzb(CameraSource cameraSource, Detector<?> detector) {
|
|
this.zzt = cameraSource;
|
|
this.zzr = detector;
|
|
}
|
|
|
|
final void release() {
|
|
this.zzr.release();
|
|
this.zzr = null;
|
|
}
|
|
|
|
final void setActive(boolean z) {
|
|
synchronized (this.lock) {
|
|
this.zzv = z;
|
|
this.lock.notifyAll();
|
|
}
|
|
}
|
|
|
|
final void zza(byte[] bArr, Camera camera) {
|
|
synchronized (this.lock) {
|
|
ByteBuffer byteBuffer = this.zzy;
|
|
if (byteBuffer != null) {
|
|
camera.addCallbackBuffer(byteBuffer.array());
|
|
this.zzy = null;
|
|
}
|
|
if (this.zzt.zzq.containsKey(bArr)) {
|
|
this.zzw = SystemClock.elapsedRealtime() - this.zzu;
|
|
this.zzx++;
|
|
this.zzy = (ByteBuffer) this.zzt.zzq.get(bArr);
|
|
this.lock.notifyAll();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
boolean z;
|
|
Frame build;
|
|
ByteBuffer byteBuffer;
|
|
while (true) {
|
|
synchronized (this.lock) {
|
|
while (true) {
|
|
z = this.zzv;
|
|
if (!z || this.zzy != null) {
|
|
break;
|
|
}
|
|
try {
|
|
this.lock.wait();
|
|
} catch (InterruptedException unused) {
|
|
return;
|
|
}
|
|
}
|
|
if (!z) {
|
|
return;
|
|
}
|
|
build = new Frame.Builder().setImageData(this.zzy, this.zzt.zzh.getWidth(), this.zzt.zzh.getHeight(), 17).setId(this.zzx).setTimestampMillis(this.zzw).setRotation(this.zzt.rotation).build();
|
|
byteBuffer = this.zzy;
|
|
this.zzy = null;
|
|
}
|
|
try {
|
|
this.zzr.receiveFrame(build);
|
|
} catch (Exception unused2) {
|
|
} finally {
|
|
this.zzt.zzg.addCallbackBuffer(byteBuffer.array());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes2.dex */
|
|
public static class Builder {
|
|
private final Detector<?> zzr;
|
|
private CameraSource zzs;
|
|
|
|
public Builder(Context context, Detector<?> detector) {
|
|
CameraSource cameraSource = new CameraSource();
|
|
this.zzs = cameraSource;
|
|
if (context == null) {
|
|
throw new IllegalArgumentException("No context supplied.");
|
|
}
|
|
if (detector == null) {
|
|
throw new IllegalArgumentException("No detector supplied.");
|
|
}
|
|
this.zzr = detector;
|
|
cameraSource.zze = context;
|
|
}
|
|
|
|
public Builder setRequestedFps(float f) {
|
|
if (f <= BitmapDescriptorFactory.HUE_RED) {
|
|
StringBuilder sb = new StringBuilder(28);
|
|
sb.append("Invalid fps: ");
|
|
sb.append(f);
|
|
throw new IllegalArgumentException(sb.toString());
|
|
}
|
|
this.zzs.zzi = f;
|
|
return this;
|
|
}
|
|
|
|
public Builder setRequestedPreviewSize(int i, int i2) {
|
|
if (i <= 0 || i > 1000000 || i2 <= 0 || i2 > 1000000) {
|
|
StringBuilder sb = new StringBuilder(45);
|
|
sb.append("Invalid preview size: ");
|
|
sb.append(i);
|
|
sb.append("x");
|
|
sb.append(i2);
|
|
throw new IllegalArgumentException(sb.toString());
|
|
}
|
|
this.zzs.zzj = i;
|
|
this.zzs.zzk = i2;
|
|
return this;
|
|
}
|
|
|
|
public Builder setFacing(int i) {
|
|
if (i != 0 && i != 1) {
|
|
StringBuilder sb = new StringBuilder(27);
|
|
sb.append("Invalid camera: ");
|
|
sb.append(i);
|
|
throw new IllegalArgumentException(sb.toString());
|
|
}
|
|
this.zzs.facing = i;
|
|
return this;
|
|
}
|
|
|
|
public Builder setAutoFocusEnabled(boolean z) {
|
|
this.zzs.zzl = z;
|
|
return this;
|
|
}
|
|
|
|
public CameraSource build() {
|
|
CameraSource cameraSource = this.zzs;
|
|
cameraSource.zzp = new zzb(cameraSource, this.zzr);
|
|
return this.zzs;
|
|
}
|
|
}
|
|
|
|
public CameraSource start(SurfaceHolder surfaceHolder) throws IOException {
|
|
synchronized (this.zzf) {
|
|
if (this.zzg != null) {
|
|
return this;
|
|
}
|
|
Camera zza2 = zza();
|
|
this.zzg = zza2;
|
|
zza2.setPreviewDisplay(surfaceHolder);
|
|
this.zzg.startPreview();
|
|
this.zzo = new Thread(this.zzp);
|
|
this.zzp.setActive(true);
|
|
this.zzo.start();
|
|
this.zzn = false;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public void stop() {
|
|
synchronized (this.zzf) {
|
|
this.zzp.setActive(false);
|
|
Thread thread = this.zzo;
|
|
if (thread != null) {
|
|
try {
|
|
thread.join();
|
|
} catch (InterruptedException unused) {
|
|
}
|
|
this.zzo = null;
|
|
}
|
|
Camera camera = this.zzg;
|
|
if (camera != null) {
|
|
camera.stopPreview();
|
|
this.zzg.setPreviewCallbackWithBuffer(null);
|
|
try {
|
|
if (this.zzn) {
|
|
this.zzg.setPreviewTexture(null);
|
|
} else {
|
|
this.zzg.setPreviewDisplay(null);
|
|
}
|
|
} catch (Exception unused2) {
|
|
}
|
|
this.zzg.release();
|
|
this.zzg = null;
|
|
}
|
|
this.zzq.clear();
|
|
}
|
|
}
|
|
|
|
public void takePicture(ShutterCallback shutterCallback, PictureCallback pictureCallback) {
|
|
synchronized (this.zzf) {
|
|
if (this.zzg != null) {
|
|
zzd zzdVar = new zzd();
|
|
zzdVar.zzaa = shutterCallback;
|
|
zzc zzcVar = new zzc();
|
|
zzcVar.zzz = pictureCallback;
|
|
this.zzg.takePicture(zzdVar, null, null, zzcVar);
|
|
}
|
|
}
|
|
}
|
|
|
|
private CameraSource() {
|
|
this.zzf = new Object();
|
|
this.facing = 0;
|
|
this.zzi = 30.0f;
|
|
this.zzj = 1024;
|
|
this.zzk = 768;
|
|
this.zzl = false;
|
|
this.zzq = new HashMap();
|
|
}
|
|
|
|
private final Camera zza() throws IOException {
|
|
int i;
|
|
int i2;
|
|
int i3 = this.facing;
|
|
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
|
int i4 = 0;
|
|
int i5 = 0;
|
|
while (true) {
|
|
if (i5 >= Camera.getNumberOfCameras()) {
|
|
i5 = -1;
|
|
break;
|
|
}
|
|
Camera.getCameraInfo(i5, cameraInfo);
|
|
if (cameraInfo.facing == i3) {
|
|
break;
|
|
}
|
|
i5++;
|
|
}
|
|
if (i5 == -1) {
|
|
throw new IOException("Could not find requested camera.");
|
|
}
|
|
Camera open = Camera.open(i5);
|
|
int i6 = this.zzj;
|
|
int i7 = this.zzk;
|
|
Camera.Parameters parameters = open.getParameters();
|
|
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
|
|
List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
|
|
ArrayList arrayList = new ArrayList();
|
|
for (Camera.Size size : supportedPreviewSizes) {
|
|
float f = size.width / size.height;
|
|
Iterator<Camera.Size> it = supportedPictureSizes.iterator();
|
|
while (true) {
|
|
if (it.hasNext()) {
|
|
Camera.Size next = it.next();
|
|
if (Math.abs(f - (next.width / next.height)) < 0.01f) {
|
|
arrayList.add(new zze(size, next));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (arrayList.size() == 0) {
|
|
Iterator<Camera.Size> it2 = supportedPreviewSizes.iterator();
|
|
while (it2.hasNext()) {
|
|
arrayList.add(new zze(it2.next(), null));
|
|
}
|
|
}
|
|
int size2 = arrayList.size();
|
|
int i8 = Integer.MAX_VALUE;
|
|
int i9 = 0;
|
|
int i10 = Integer.MAX_VALUE;
|
|
zze zzeVar = null;
|
|
while (i9 < size2) {
|
|
Object obj = arrayList.get(i9);
|
|
i9++;
|
|
zze zzeVar2 = (zze) obj;
|
|
Size zzb2 = zzeVar2.zzb();
|
|
int abs = Math.abs(zzb2.getWidth() - i6) + Math.abs(zzb2.getHeight() - i7);
|
|
if (abs < i10) {
|
|
zzeVar = zzeVar2;
|
|
i10 = abs;
|
|
}
|
|
}
|
|
if (zzeVar == null) {
|
|
throw new IOException("Could not find suitable preview size.");
|
|
}
|
|
Size zzc2 = zzeVar.zzc();
|
|
this.zzh = zzeVar.zzb();
|
|
int i11 = (int) (this.zzi * 1000.0f);
|
|
int[] iArr = null;
|
|
for (int[] iArr2 : open.getParameters().getSupportedPreviewFpsRange()) {
|
|
int i12 = iArr2[0];
|
|
int abs2 = Math.abs(i11 - iArr2[1]) + Math.abs(i11 - i12);
|
|
if (abs2 < i8) {
|
|
iArr = iArr2;
|
|
i8 = abs2;
|
|
}
|
|
}
|
|
if (iArr == null) {
|
|
throw new IOException("Could not find suitable preview frames per second range.");
|
|
}
|
|
Camera.Parameters parameters2 = open.getParameters();
|
|
if (zzc2 != null) {
|
|
parameters2.setPictureSize(zzc2.getWidth(), zzc2.getHeight());
|
|
}
|
|
parameters2.setPreviewSize(this.zzh.getWidth(), this.zzh.getHeight());
|
|
parameters2.setPreviewFpsRange(iArr[0], iArr[1]);
|
|
parameters2.setPreviewFormat(17);
|
|
int rotation = ((WindowManager) this.zze.getSystemService("window")).getDefaultDisplay().getRotation();
|
|
if (rotation != 0) {
|
|
if (rotation == 1) {
|
|
i4 = 90;
|
|
} else if (rotation == 2) {
|
|
i4 = CipherSuite.TLS_DHE_PSK_WITH_NULL_SHA256;
|
|
} else if (rotation == 3) {
|
|
i4 = 270;
|
|
}
|
|
}
|
|
Camera.CameraInfo cameraInfo2 = new Camera.CameraInfo();
|
|
Camera.getCameraInfo(i5, cameraInfo2);
|
|
if (cameraInfo2.facing == 1) {
|
|
i = (cameraInfo2.orientation + i4) % 360;
|
|
i2 = (360 - i) % 360;
|
|
} else {
|
|
i = ((cameraInfo2.orientation - i4) + 360) % 360;
|
|
i2 = i;
|
|
}
|
|
this.rotation = i / 90;
|
|
open.setDisplayOrientation(i2);
|
|
parameters2.setRotation(i);
|
|
if (this.zzl && parameters2.getSupportedFocusModes().contains("continuous-video")) {
|
|
parameters2.setFocusMode("continuous-video");
|
|
}
|
|
open.setParameters(parameters2);
|
|
open.setPreviewCallbackWithBuffer(new zza());
|
|
open.addCallbackBuffer(zza(this.zzh));
|
|
open.addCallbackBuffer(zza(this.zzh));
|
|
open.addCallbackBuffer(zza(this.zzh));
|
|
open.addCallbackBuffer(zza(this.zzh));
|
|
return open;
|
|
}
|
|
|
|
private final byte[] zza(Size size) {
|
|
byte[] bArr = new byte[((int) Math.ceil(((size.getHeight() * size.getWidth()) * ImageFormat.getBitsPerPixel(17)) / 8.0d)) + 1];
|
|
ByteBuffer wrap = ByteBuffer.wrap(bArr);
|
|
if (!wrap.hasArray() || wrap.array() != bArr) {
|
|
throw new IllegalStateException("Failed to create valid buffer for camera source.");
|
|
}
|
|
this.zzq.put(bArr, wrap);
|
|
return bArr;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes2.dex */
|
|
public static final class zze {
|
|
private Size zzab;
|
|
private Size zzac;
|
|
|
|
public zze(Camera.Size size, Camera.Size size2) {
|
|
this.zzab = new Size(size.width, size.height);
|
|
if (size2 != null) {
|
|
this.zzac = new Size(size2.width, size2.height);
|
|
}
|
|
}
|
|
|
|
public final Size zzc() {
|
|
return this.zzac;
|
|
}
|
|
|
|
public final Size zzb() {
|
|
return this.zzab;
|
|
}
|
|
}
|
|
|
|
public Size getPreviewSize() {
|
|
return this.zzh;
|
|
}
|
|
|
|
public int getCameraFacing() {
|
|
return this.facing;
|
|
}
|
|
}
|