Compare commits
2 Commits
window.15
...
refactor-e
Author | SHA1 | Date | |
---|---|---|---|
b0a4e6df25 | |||
545a8a8f32 |
@ -9,6 +9,7 @@ import android.media.MediaCodecList;
|
|||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@ -106,22 +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 (!downsizeOnError || firstFrameSent) {
|
if (!prepareDownsizeRetry(device, screenInfo)) {
|
||||||
// Fail immediately
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
alive = true;
|
||||||
} finally {
|
} finally {
|
||||||
codec.reset();
|
codec.reset();
|
||||||
@ -137,6 +138,26 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean prepareDownsizeRetry(Device device, ScreenInfo screenInfo) {
|
||||||
|
if (!downsizeOnError || firstFrameSent) {
|
||||||
|
Ln.i("#1 " + downsizeOnError + " " + firstFrameSent);
|
||||||
|
// Must fail immediately
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newMaxSize = chooseMaxSizeFallback(screenInfo.getVideoSize());
|
||||||
|
Ln.i("newMaxSize = " + newMaxSize);
|
||||||
|
if (newMaxSize == 0) {
|
||||||
|
// Must definitively fail
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry with a smaller device size
|
||||||
|
Ln.i("Retrying with -m" + newMaxSize + "...");
|
||||||
|
device.setMaxSize(newMaxSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static int chooseMaxSizeFallback(Size failedSize) {
|
private static int chooseMaxSizeFallback(Size failedSize) {
|
||||||
int currentMaxSize = Math.max(failedSize.getWidth(), failedSize.getHeight());
|
int currentMaxSize = Math.max(failedSize.getWidth(), failedSize.getHeight());
|
||||||
for (int value : MAX_SIZE_FALLBACK) {
|
for (int value : MAX_SIZE_FALLBACK) {
|
||||||
|
Reference in New Issue
Block a user