Skip to content

Commit

Permalink
Retry on error in MediaCodec configure or start
Browse files Browse the repository at this point in the history
The new retry mechanism with a lower definition only worked if the error
occurred during encode(). For example:

    java.lang.IllegalStateException
        at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
        at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:3452)
        at com.genymobile.scrcpy.ScreenEncoder.encode(ScreenEncoder.java:114)
        at com.genymobile.scrcpy.ScreenEncoder.internalStreamScreen(ScreenEncoder.java:95)
        at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:61)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:80)
        at com.genymobile.scrcpy.Server.main(Server.java:255)

However, MediaCodec may also fail before encoding, during configure() or
start(). For example:

    android.media.MediaCodec$CodecException: Error 0xfffffc0e
        at android.media.MediaCodec.native_configure(Native Method)
        at android.media.MediaCodec.configure(MediaCodec.java:1956)
        at android.media.MediaCodec.configure(MediaCodec.java:1885)
        at com.genymobile.scrcpy.ScreenEncoder.configure(ScreenEncoder.java:158)
        at com.genymobile.scrcpy.ScreenEncoder.streamScreen(ScreenEncoder.java:68)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:28)
        at com.genymobile.scrcpy.Server.main(Server.java:110)

Also downscale and retry in these cases.

Refs #2947 <#2947>
Refs #2988 <#2988>
  • Loading branch information
rom1v committed Jan 30, 2022
1 parent f4c7044 commit b223e23
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,15 @@ private void internalStreamScreen(Device device, FileDescriptor fd) throws IOExc
Rect unlockedVideoRect = screenInfo.getUnlockedVideoSize().toRect();
int videoRotation = screenInfo.getVideoRotation();
int layerStack = device.getLayerStack();

setSize(format, videoRect.width(), videoRect.height());
configure(codec, format);
Surface surface = codec.createInputSurface();
setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack);
codec.start();

Surface surface = null;
try {
configure(codec, format);
surface = codec.createInputSurface();
setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack);
codec.start();

alive = encode(codec, fd);
// do not call stop() on exception, it would trigger an IllegalStateException
codec.stop();
Expand All @@ -119,7 +121,9 @@ private void internalStreamScreen(Device device, FileDescriptor fd) throws IOExc
} finally {
destroyDisplay(display);
codec.release();
surface.release();
if (surface != null) {
surface.release();
}
}
} while (alive);
} finally {
Expand Down

0 comments on commit b223e23

Please sign in to comment.