|
|
|
@ -19,6 +19,8 @@ import android.location.Location; |
|
|
|
|
import android.media.Image; |
|
|
|
|
import android.media.ImageReader; |
|
|
|
|
import android.os.Build; |
|
|
|
|
import android.os.Handler; |
|
|
|
|
import android.os.Looper; |
|
|
|
|
import android.util.Pair; |
|
|
|
|
import android.util.Range; |
|
|
|
|
import android.util.Rational; |
|
|
|
@ -61,6 +63,7 @@ import com.otaliastudios.cameraview.frame.FrameManager; |
|
|
|
|
import com.otaliastudios.cameraview.frame.ImageFrameManager; |
|
|
|
|
import com.otaliastudios.cameraview.gesture.Gesture; |
|
|
|
|
import com.otaliastudios.cameraview.internal.CropHelper; |
|
|
|
|
import com.otaliastudios.cameraview.internal.FpsRangeValidator; |
|
|
|
|
import com.otaliastudios.cameraview.metering.MeteringRegions; |
|
|
|
|
import com.otaliastudios.cameraview.picture.Full2PictureRecorder; |
|
|
|
|
import com.otaliastudios.cameraview.picture.Snapshot2PictureRecorder; |
|
|
|
@ -76,6 +79,7 @@ import java.util.Comparator; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.concurrent.Callable; |
|
|
|
|
import java.util.concurrent.CopyOnWriteArrayList; |
|
|
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
|
import java.util.concurrent.ExecutionException; |
|
|
|
|
|
|
|
|
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) |
|
|
|
@ -498,6 +502,7 @@ public class Camera2Engine extends CameraBaseEngine implements |
|
|
|
|
if (outputClass == SurfaceHolder.class) { |
|
|
|
|
try { |
|
|
|
|
// This must be called from the UI thread...
|
|
|
|
|
LOG.i("onStartBind:", "Waiting on UI thread..."); |
|
|
|
|
Tasks.await(Tasks.call(new Callable<Void>() { |
|
|
|
|
@Override |
|
|
|
|
public Void call() { |
|
|
|
@ -1374,14 +1379,13 @@ public class Camera2Engine extends CameraBaseEngine implements |
|
|
|
|
protected boolean applyPreviewFrameRate(@NonNull CaptureRequest.Builder builder, |
|
|
|
|
float oldPreviewFrameRate) { |
|
|
|
|
//noinspection unchecked
|
|
|
|
|
Range<Integer>[] fallback = new Range[]{}; |
|
|
|
|
Range<Integer>[] fpsRanges = readCharacteristic( |
|
|
|
|
CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, |
|
|
|
|
fallback); |
|
|
|
|
new Range[]{}); |
|
|
|
|
sortRanges(fpsRanges); |
|
|
|
|
if (mPreviewFrameRate == 0F) { |
|
|
|
|
// 0F is a special value. Fallback to a reasonable default.
|
|
|
|
|
for (Range<Integer> fpsRange : fpsRanges) { |
|
|
|
|
for (Range<Integer> fpsRange : filterRanges(fpsRanges)) { |
|
|
|
|
if (fpsRange.contains(30) || fpsRange.contains(24)) { |
|
|
|
|
builder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange); |
|
|
|
|
return true; |
|
|
|
@ -1393,7 +1397,7 @@ public class Camera2Engine extends CameraBaseEngine implements |
|
|
|
|
mCameraOptions.getPreviewFrameRateMaxValue()); |
|
|
|
|
mPreviewFrameRate = Math.max(mPreviewFrameRate, |
|
|
|
|
mCameraOptions.getPreviewFrameRateMinValue()); |
|
|
|
|
for (Range<Integer> fpsRange : fpsRanges) { |
|
|
|
|
for (Range<Integer> fpsRange : filterRanges(fpsRanges)) { |
|
|
|
|
if (fpsRange.contains(Math.round(mPreviewFrameRate))) { |
|
|
|
|
builder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange); |
|
|
|
|
return true; |
|
|
|
@ -1405,23 +1409,32 @@ public class Camera2Engine extends CameraBaseEngine implements |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void sortRanges(Range<Integer>[] fpsRanges) { |
|
|
|
|
if (getPreviewFrameRateExact() && mPreviewFrameRate != 0) { // sort by range width in ascending order
|
|
|
|
|
final boolean ascending = getPreviewFrameRateExact() && mPreviewFrameRate != 0; |
|
|
|
|
Arrays.sort(fpsRanges, new Comparator<Range<Integer>>() { |
|
|
|
|
@Override |
|
|
|
|
public int compare(Range<Integer> range1, Range<Integer> range2) { |
|
|
|
|
if (ascending) { |
|
|
|
|
return (range1.getUpper() - range1.getLower()) |
|
|
|
|
- (range2.getUpper() - range2.getLower()); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} else { // sort by range width in descending order
|
|
|
|
|
Arrays.sort(fpsRanges, new Comparator<Range<Integer>>() { |
|
|
|
|
@Override |
|
|
|
|
public int compare(Range<Integer> range1, Range<Integer> range2) { |
|
|
|
|
} else { |
|
|
|
|
return (range2.getUpper() - range2.getLower()) |
|
|
|
|
- (range1.getUpper() - range1.getLower()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private List<Range<Integer>> filterRanges(Range<Integer>[] fpsRanges) { |
|
|
|
|
List<Range<Integer>> results = new ArrayList<>(); |
|
|
|
|
int min = Math.round(mCameraOptions.getPreviewFrameRateMinValue()); |
|
|
|
|
int max = Math.round(mCameraOptions.getPreviewFrameRateMaxValue()); |
|
|
|
|
for (Range<Integer> fpsRange : fpsRanges) { |
|
|
|
|
if (!fpsRange.contains(min)) continue; |
|
|
|
|
if (!fpsRange.contains(max)) continue; |
|
|
|
|
if (!FpsRangeValidator.validate(fpsRange)) continue; |
|
|
|
|
results.add(fpsRange); |
|
|
|
|
} |
|
|
|
|
return results; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|