Feature option to setPreviewFrameRate as exact as possible

pull/754/head
hualong-shen 6 years ago
parent 83bb45108a
commit d44b7ee01e
  1. 5
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/engine/MockCameraEngine.java
  2. 20
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  3. 25
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java
  4. 28
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java
  5. 1
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java
  6. 1
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraEngine.java
  7. 1
      cameraview/src/main/res/values/attrs.xml

@ -212,4 +212,9 @@ public class MockCameraEngine extends CameraBaseEngine {
@Override public void setPreviewFrameRate(float previewFrameRate) {
mPreviewFrameRate = previewFrameRate;
}
@Override
public void setPreviewFrameRateExact(boolean previewFrameRateExact) {
mPreviewFrameRateExact = previewFrameRateExact;
}
}

@ -206,6 +206,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
int videoBitRate = a.getInteger(R.styleable.CameraView_cameraVideoBitRate, 0);
int audioBitRate = a.getInteger(R.styleable.CameraView_cameraAudioBitRate, 0);
float videoFrameRate = a.getFloat(R.styleable.CameraView_cameraPreviewFrameRate, 0);
boolean videoFrameRateExact = a.getBoolean(R.styleable.CameraView_cameraPreviewFrameRateExact, false);
long autoFocusResetDelay = (long) a.getInteger(
R.styleable.CameraView_cameraAutoFocusResetDelay,
(int) DEFAULT_AUTOFOCUS_RESET_DELAY_MILLIS);
@ -277,6 +278,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
setVideoMaxDuration(videoMaxDuration);
setVideoBitRate(videoBitRate);
setAutoFocusResetDelay(autoFocusResetDelay);
setPreviewFrameRateExact(videoFrameRateExact);
setPreviewFrameRate(videoFrameRate);
setSnapshotMaxWidth(snapshotMaxWidth);
setSnapshotMaxHeight(snapshotMaxHeight);
@ -1543,6 +1545,24 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
return mCameraEngine.getVideoBitRate();
}
/**
* A flag to control the behavior when calling {@link #setPreviewFrameRate(float)}.
*
* If the value is set to true, {@link #setPreviewFrameRate(float)} will choose the preview
* frame range as close to the desired new frame rate as possible. Which mean it may choose a
* narrow range around the desired frame rate.
*
* If the value is set to false, {@link #setPreviewFrameRate(float)} will choose as broad range
* as it can.
*
* @param videoFrameRateExact whether want a more exact preview frame range
*
* @see #setPreviewFrameRate(float)
*/
private void setPreviewFrameRateExact(boolean videoFrameRateExact) {
mCameraEngine.setPreviewFrameRateExact(videoFrameRateExact);
}
/**
* Sets the preview frame rate in frames per second.
* This rate will be used, for example, by the frame processor and in video

@ -52,6 +52,7 @@ import com.otaliastudios.cameraview.video.SnapshotVideoRecorder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -696,6 +697,11 @@ public class Camera1Engine extends CameraBaseEngine implements
return false;
}
@Override
public void setPreviewFrameRateExact(boolean previewFrameRateExact) {
mPreviewFrameRateExact = previewFrameRateExact;
}
@Override
public void setPreviewFrameRate(float previewFrameRate) {
final float old = previewFrameRate;
@ -726,6 +732,7 @@ public class Camera1Engine extends CameraBaseEngine implements
}
}
} else {
sortRanges(fpsRanges);
// If out of boundaries, adjust it.
mPreviewFrameRate = Math.min(mPreviewFrameRate,
mCameraOptions.getPreviewFrameRateMaxValue());
@ -745,6 +752,24 @@ public class Camera1Engine extends CameraBaseEngine implements
return false;
}
private void sortRanges(List<int[]> fpsRanges) {
if (mPreviewFrameRateExact) { // sort by range width in ascending order
Collections.sort(fpsRanges, new Comparator<int[]>() {
@Override
public int compare(int[] range1, int[] range2) {
return (range1[1] - range1[0]) - (range2[1] - range2[0]);
}
});
} else { // sort by range width in descending order
Collections.sort(fpsRanges, new Comparator<int[]>() {
@Override
public int compare(int[] range1, int[] range2) {
return (range2[1] - range2[0]) - (range1[1] - range1[0]);
}
});
}
}
@Override
public void setPictureFormat(@NonNull PictureFormat pictureFormat) {
if (pictureFormat != PictureFormat.JPEG) {

@ -71,6 +71,8 @@ import com.otaliastudios.cameraview.video.Full2VideoRecorder;
import com.otaliastudios.cameraview.video.SnapshotVideoRecorder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
@ -1353,6 +1355,11 @@ public class Camera2Engine extends CameraBaseEngine implements
mPlaySoundsTask = Tasks.forResult(null);
}
@Override
public void setPreviewFrameRateExact(boolean previewFrameRateExact) {
mPreviewFrameRateExact = previewFrameRateExact;
}
@Override
public void setPreviewFrameRate(float previewFrameRate) {
final float oldPreviewFrameRate = mPreviewFrameRate;
@ -1387,6 +1394,7 @@ public class Camera2Engine extends CameraBaseEngine implements
}
}
} else {
sortRanges(fpsRanges);
// If out of boundaries, adjust it.
mPreviewFrameRate = Math.min(mPreviewFrameRate,
mCameraOptions.getPreviewFrameRateMaxValue());
@ -1403,6 +1411,26 @@ public class Camera2Engine extends CameraBaseEngine implements
return false;
}
private void sortRanges(Range<Integer>[] fpsRanges) {
if (mPreviewFrameRateExact) {
Arrays.sort(fpsRanges, new Comparator<Range<Integer>>() {
@Override
public int compare(Range<Integer> range1, Range<Integer> range2) {
return (range1.getUpper() - range1.getLower())
- (range2.getUpper() - range2.getLower());
}
});
} else {
Arrays.sort(fpsRanges, new Comparator<Range<Integer>>() {
@Override
public int compare(Range<Integer> range1, Range<Integer> range2) {
return (range2.getUpper() - range2.getLower())
- (range1.getUpper() - range1.getLower());
}
});
}
}
@Override
public void setPictureFormat(final @NonNull PictureFormat pictureFormat) {
if (pictureFormat != mPictureFormat) {

@ -70,6 +70,7 @@ public abstract class CameraBaseEngine extends CameraEngine {
@SuppressWarnings("WeakerAccess") protected boolean mPictureMetering;
@SuppressWarnings("WeakerAccess") protected boolean mPictureSnapshotMetering;
@SuppressWarnings("WeakerAccess") protected float mPreviewFrameRate;
@SuppressWarnings("WeakerAccess") protected boolean mPreviewFrameRateExact;
private FrameManager mFrameManager;
private final Angles mAngles = new Angles();

@ -690,6 +690,7 @@ public abstract class CameraEngine implements
public abstract void setPictureFormat(@NonNull PictureFormat pictureFormat);
@NonNull public abstract PictureFormat getPictureFormat();
public abstract void setPreviewFrameRateExact(boolean previewFrameRateExact);
public abstract void setPreviewFrameRate(float previewFrameRate);
public abstract float getPreviewFrameRate();

@ -34,6 +34,7 @@
<attr name="cameraVideoBitRate" format="integer|reference" />
<attr name="cameraAudioBitRate" format="integer|reference" />
<attr name="cameraPreviewFrameRate" format="integer|reference" />
<attr name="cameraPreviewFrameRateExact" format="boolean" />
<attr name="cameraGestureTap" format="enum">
<enum name="none" value="0" />

Loading…
Cancel
Save