Add --camera-fps

Add a new option for specifying the camera frame rate.

By default, Android's default frame rate (30 fps) is used.

PR #4213 <https://github.com/Genymobile/scrcpy/pull/4213>

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
Andrew Gunnerson
2023-10-27 20:20:19 -04:00
committed by Romain Vimont
parent 928f8b8eb3
commit 4722bff423
13 changed files with 72 additions and 3 deletions

View File

@@ -19,6 +19,7 @@ import android.media.MediaCodec;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Range;
import android.view.Surface;
import java.io.IOException;
@@ -38,6 +39,7 @@ public class CameraCapture extends SurfaceCapture {
private final Size explicitSize;
private int maxSize;
private final CameraAspectRatio aspectRatio;
private final int fps;
private String cameraId;
private Size size;
@@ -49,12 +51,13 @@ public class CameraCapture extends SurfaceCapture {
private final AtomicBoolean disconnected = new AtomicBoolean();
public CameraCapture(String explicitCameraId, CameraFacing cameraFacing, Size explicitSize, int maxSize, CameraAspectRatio aspectRatio) {
public CameraCapture(String explicitCameraId, CameraFacing cameraFacing, Size explicitSize, int maxSize, CameraAspectRatio aspectRatio, int fps) {
this.explicitCameraId = explicitCameraId;
this.cameraFacing = cameraFacing;
this.explicitSize = explicitSize;
this.maxSize = maxSize;
this.aspectRatio = aspectRatio;
this.fps = fps;
}
@Override
@@ -304,6 +307,11 @@ public class CameraCapture extends SurfaceCapture {
private CaptureRequest createCaptureRequest(Surface surface) throws CameraAccessException {
CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
requestBuilder.addTarget(surface);
if (fps > 0) {
requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range<>(fps, fps));
}
return requestBuilder.build();
}

View File

@@ -9,8 +9,10 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.MediaCodec;
import android.util.Range;
import java.util.List;
import java.util.TreeSet;
public final class LogUtils {
@@ -97,7 +99,15 @@ public final class LogUtils {
builder.append(" (").append(getCameraFacingName(facing)).append(", ");
Rect activeSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
builder.append(activeSize.width()).append("x").append(activeSize.height()).append(')');
builder.append(activeSize.width()).append("x").append(activeSize.height()).append(", ");
// Capture frame rates for low-FPS mode are the same for every resolution
Range<Integer>[] lowFpsRanges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
TreeSet<Integer> uniqueLowFps = new TreeSet<>();
for (Range<Integer> range : lowFpsRanges) {
uniqueLowFps.add(range.getUpper());
}
builder.append("fps=").append(uniqueLowFps).append(')');
if (includeSizes) {
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

View File

@@ -28,6 +28,7 @@ public class Options {
private Size cameraSize;
private CameraFacing cameraFacing;
private CameraAspectRatio cameraAspectRatio;
private int cameraFps;
private boolean showTouches;
private boolean stayAwake;
private List<CodecOption> videoCodecOptions;
@@ -136,6 +137,10 @@ public class Options {
return cameraAspectRatio;
}
public int getCameraFps() {
return cameraFps;
}
public boolean getShowTouches() {
return showTouches;
}
@@ -384,6 +389,9 @@ public class Options {
options.cameraAspectRatio = parseCameraAspectRatio(value);
}
break;
case "camera_fps":
options.cameraFps = Integer.parseInt(value);
break;
case "send_device_meta":
options.sendDeviceMeta = Boolean.parseBoolean(value);
break;

View File

@@ -144,7 +144,7 @@ public final class Server {
surfaceCapture = new ScreenCapture(device);
} else {
surfaceCapture = new CameraCapture(options.getCameraId(), options.getCameraFacing(), options.getCameraSize(),
options.getMaxSize(), options.getCameraAspectRatio());
options.getMaxSize(), options.getCameraAspectRatio(), options.getCameraFps());
}
SurfaceEncoder surfaceEncoder = new SurfaceEncoder(surfaceCapture, videoStreamer, options.getVideoBitRate(), options.getMaxFps(),
options.getVideoCodecOptions(), options.getVideoEncoder(), options.getDownsizeOnError());