Compare commits
2 Commits
refactor-e
...
refactor-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39b84af1cc | ||
|
|
5353dfb9a5 |
@@ -28,7 +28,6 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
|
|
||||||
// Keep the values in descending order
|
// Keep the values in descending order
|
||||||
private static final int[] MAX_SIZE_FALLBACK = {2560, 1920, 1600, 1280, 1024, 800};
|
private static final int[] MAX_SIZE_FALLBACK = {2560, 1920, 1600, 1280, 1024, 800};
|
||||||
private static final int MAX_CONSECUTIVE_ERRORS = 3; // on error, retry MAX_CONSECUTIVE_ERRORS times
|
|
||||||
|
|
||||||
private static final long PACKET_FLAG_CONFIG = 1L << 63;
|
private static final long PACKET_FLAG_CONFIG = 1L << 63;
|
||||||
private static final long PACKET_FLAG_KEY_FRAME = 1L << 62;
|
private static final long PACKET_FLAG_KEY_FRAME = 1L << 62;
|
||||||
@@ -45,7 +44,6 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
private long ptsOrigin;
|
private long ptsOrigin;
|
||||||
|
|
||||||
private boolean firstFrameSent;
|
private boolean firstFrameSent;
|
||||||
private int consecutiveErrors;
|
|
||||||
|
|
||||||
public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, List<CodecOption> codecOptions, String encoderName,
|
public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, List<CodecOption> codecOptions, String encoderName,
|
||||||
boolean downsizeOnError) {
|
boolean downsizeOnError) {
|
||||||
@@ -109,12 +107,22 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
alive = encode(codec, fd);
|
alive = encode(codec, fd);
|
||||||
// do not call stop() on exception, it would trigger an IllegalStateException
|
// do not call stop() on exception, it would trigger an IllegalStateException
|
||||||
codec.stop();
|
codec.stop();
|
||||||
|
} catch (MediaCodec.CodecException e) {
|
||||||
|
Ln.e("Codec error: " + e.getMessage());
|
||||||
|
// <https://developer.android.com/reference/android/media/MediaCodec#error-handling>
|
||||||
|
// For simplicity, handle isTransient() like isRecoverable()
|
||||||
|
if (e.isRecoverable() || e.isTransient()) {
|
||||||
|
// Avoid busy-loop if too many errors are generated
|
||||||
|
SystemClock.sleep(50);
|
||||||
|
} else if (!prepareDownsizeRetry(device, screenInfo)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
alive = true;
|
||||||
} catch (IllegalStateException | IllegalArgumentException e) {
|
} catch (IllegalStateException | IllegalArgumentException e) {
|
||||||
Ln.e("Encoding error: " + e.getClass().getName() + ": " + e.getMessage());
|
Ln.e("Encoding error: " + e.getClass().getName() + ": " + e.getMessage());
|
||||||
if (!prepareRetry(device, screenInfo)) {
|
if (!prepareDownsizeRetry(device, screenInfo)) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
Ln.i("Retrying...");
|
|
||||||
alive = true;
|
alive = true;
|
||||||
} finally {
|
} finally {
|
||||||
codec.reset();
|
codec.reset();
|
||||||
@@ -130,26 +138,12 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean prepareRetry(Device device, ScreenInfo screenInfo) {
|
private boolean prepareDownsizeRetry(Device device, ScreenInfo screenInfo) {
|
||||||
if (firstFrameSent) {
|
if (!downsizeOnError || firstFrameSent) {
|
||||||
++consecutiveErrors;
|
|
||||||
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
||||||
// Definitively fail
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a bit to increase the probability that retrying will fix the problem
|
|
||||||
SystemClock.sleep(50);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!downsizeOnError) {
|
|
||||||
// Must fail immediately
|
// Must fail immediately
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Downsizing on error is only enabled if an encoding failure occurs before the first frame (downsizing later could be surprising)
|
|
||||||
|
|
||||||
int newMaxSize = chooseMaxSizeFallback(screenInfo.getVideoSize());
|
int newMaxSize = chooseMaxSizeFallback(screenInfo.getVideoSize());
|
||||||
Ln.i("newMaxSize = " + newMaxSize);
|
Ln.i("newMaxSize = " + newMaxSize);
|
||||||
if (newMaxSize == 0) {
|
if (newMaxSize == 0) {
|
||||||
@@ -198,7 +192,6 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
|
||||||
// If this is not a config packet, then it contains a frame
|
// If this is not a config packet, then it contains a frame
|
||||||
firstFrameSent = true;
|
firstFrameSent = true;
|
||||||
consecutiveErrors = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user