Downsize on error
Some devices are not able to encode at the device screen definition. Instead of just failing, try with a lower definition on any MediaCodec error. PR #2947 <https://github.com/Genymobile/scrcpy/pull/2947>
This commit is contained in:
parent
723faa5dee
commit
26b4104844
2 changed files with 33 additions and 1 deletions
|
@ -44,7 +44,7 @@ public final class Device {
|
|||
|
||||
private final Size deviceSize;
|
||||
private final Rect crop;
|
||||
private final int maxSize;
|
||||
private int maxSize;
|
||||
private final int lockVideoOrientation;
|
||||
|
||||
private ScreenInfo screenInfo;
|
||||
|
@ -133,6 +133,11 @@ public final class Device {
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized void setMaxSize(int newMaxSize) {
|
||||
maxSize = newMaxSize;
|
||||
screenInfo = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation);
|
||||
}
|
||||
|
||||
public synchronized ScreenInfo getScreenInfo() {
|
||||
return screenInfo;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
private static final int REPEAT_FRAME_DELAY_US = 100_000; // repeat after 100ms
|
||||
private static final String KEY_MAX_FPS_TO_ENCODER = "max-fps-to-encoder";
|
||||
|
||||
// Keep the values in descending order
|
||||
private static final int[] MAX_SIZE_FALLBACK = {2560, 1920, 1600, 1280, 1024, 800};
|
||||
|
||||
private static final int NO_PTS = -1;
|
||||
|
||||
private final AtomicBoolean rotationChanged = new AtomicBoolean();
|
||||
|
@ -91,6 +94,18 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
alive = encode(codec, fd);
|
||||
// do not call stop() on exception, it would trigger an IllegalStateException
|
||||
codec.stop();
|
||||
} catch (Exception e) {
|
||||
Ln.e("Encoding error: " + e.getClass().getName() + ": " + e.getMessage());
|
||||
int newMaxSize = chooseMaxSizeFallback(screenInfo.getVideoSize());
|
||||
if (newMaxSize == 0) {
|
||||
// Definitively fail
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Retry with a smaller device size
|
||||
Ln.i("Retrying with -m" + newMaxSize + "...");
|
||||
device.setMaxSize(newMaxSize);
|
||||
alive = true;
|
||||
} finally {
|
||||
destroyDisplay(display);
|
||||
codec.release();
|
||||
|
@ -102,6 +117,18 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
}
|
||||
}
|
||||
|
||||
private static int chooseMaxSizeFallback(Size failedSize) {
|
||||
int currentMaxSize = Math.max(failedSize.getWidth(), failedSize.getHeight());
|
||||
for (int value : MAX_SIZE_FALLBACK) {
|
||||
if (value < currentMaxSize) {
|
||||
// We found a smaller value to reduce the video size
|
||||
return value;
|
||||
}
|
||||
}
|
||||
// No fallback, fail definitively
|
||||
return 0;
|
||||
}
|
||||
|
||||
private boolean encode(MediaCodec codec, FileDescriptor fd) throws IOException {
|
||||
boolean eof = false;
|
||||
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
||||
|
|
Loading…
Reference in a new issue