-
-
Notifications
You must be signed in to change notification settings - Fork 11k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract SurfaceCapture from ScreenEncoder
Extract an interface SurfaceCapture from ScreenEncoder, representing a video source which can be rendered to a Surface for encoding. Split ScreenEncoder into: - ScreenCapture, implementing SurfaceCapture to capture the device screen, - SurfaceEncoder, to encode any SurfaceCapture. This separation prepares the introduction of another SurfaceCapture implementation to capture the camera instead of the device screen. PR #4213 <#4213> Co-authored-by: Romain Vimont <[email protected]> Signed-off-by: Romain Vimont <[email protected]>
- Loading branch information
Showing
4 changed files
with
166 additions
and
71 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
server/src/main/java/com/genymobile/scrcpy/ScreenCapture.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package com.genymobile.scrcpy; | ||
|
||
import com.genymobile.scrcpy.wrappers.SurfaceControl; | ||
|
||
import android.graphics.Rect; | ||
import android.os.Build; | ||
import android.os.IBinder; | ||
import android.view.Surface; | ||
|
||
public class ScreenCapture extends SurfaceCapture implements Device.RotationListener, Device.FoldListener { | ||
|
||
private final Device device; | ||
private IBinder display; | ||
|
||
public ScreenCapture(Device device) { | ||
this.device = device; | ||
} | ||
|
||
@Override | ||
public void init() { | ||
display = createDisplay(); | ||
device.setRotationListener(this); | ||
device.setFoldListener(this); | ||
} | ||
|
||
@Override | ||
public void start(Surface surface) { | ||
ScreenInfo screenInfo = device.getScreenInfo(); | ||
Rect contentRect = screenInfo.getContentRect(); | ||
|
||
// does not include the locked video orientation | ||
Rect unlockedVideoRect = screenInfo.getUnlockedVideoSize().toRect(); | ||
int videoRotation = screenInfo.getVideoRotation(); | ||
int layerStack = device.getLayerStack(); | ||
setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack); | ||
} | ||
|
||
@Override | ||
public void release() { | ||
device.setRotationListener(null); | ||
device.setFoldListener(null); | ||
SurfaceControl.destroyDisplay(display); | ||
} | ||
|
||
@Override | ||
public Size getSize() { | ||
return device.getScreenInfo().getVideoSize(); | ||
} | ||
|
||
@Override | ||
public void setMaxSize(int maxSize) { | ||
device.setMaxSize(maxSize); | ||
} | ||
|
||
@Override | ||
public void onFoldChanged(int displayId, boolean folded) { | ||
requestReset(); | ||
} | ||
|
||
@Override | ||
public void onRotationChanged(int rotation) { | ||
requestReset(); | ||
} | ||
|
||
private static IBinder createDisplay() { | ||
// Since Android 12 (preview), secure displays could not be created with shell permissions anymore. | ||
// On Android 12 preview, SDK_INT is still R (not S), but CODENAME is "S". | ||
boolean secure = Build.VERSION.SDK_INT < Build.VERSION_CODES.R || (Build.VERSION.SDK_INT == Build.VERSION_CODES.R && !"S".equals( | ||
Build.VERSION.CODENAME)); | ||
return SurfaceControl.createDisplay("scrcpy", secure); | ||
} | ||
|
||
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect, int layerStack) { | ||
SurfaceControl.openTransaction(); | ||
try { | ||
SurfaceControl.setDisplaySurface(display, surface); | ||
SurfaceControl.setDisplayProjection(display, orientation, deviceRect, displayRect); | ||
SurfaceControl.setDisplayLayerStack(display, layerStack); | ||
} finally { | ||
SurfaceControl.closeTransaction(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
server/src/main/java/com/genymobile/scrcpy/SurfaceCapture.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.genymobile.scrcpy; | ||
|
||
import android.view.Surface; | ||
|
||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
/** | ||
* A video source which can be rendered on a Surface for encoding. | ||
*/ | ||
public abstract class SurfaceCapture { | ||
|
||
private final AtomicBoolean resetCapture = new AtomicBoolean(); | ||
|
||
/** | ||
* Request the encoding session to be restarted, for example if the capture implementation detects that the video source size has changed (on | ||
* device rotation for example). | ||
*/ | ||
protected void requestReset() { | ||
resetCapture.set(true); | ||
} | ||
|
||
/** | ||
* Consume the reset request (intended to be called by the encoder). | ||
* | ||
* @return {@code true} if a reset request was pending, {@code false} otherwise. | ||
*/ | ||
public boolean consumeReset() { | ||
return resetCapture.getAndSet(false); | ||
} | ||
|
||
/** | ||
* Called once before the capture starts. | ||
*/ | ||
public abstract void init(); | ||
|
||
/** | ||
* Called after the capture ends (if and only if {@link #init()} has been called). | ||
*/ | ||
public abstract void release(); | ||
|
||
/** | ||
* Start the capture to the target surface. | ||
* | ||
* @param surface the surface which will be encoded | ||
*/ | ||
public abstract void start(Surface surface); | ||
|
||
/** | ||
* Return the video size | ||
* | ||
* @return the video size | ||
*/ | ||
public abstract Size getSize(); | ||
|
||
/** | ||
* Set the maximum capture size (set by the encoder if it does not support the current size). | ||
* | ||
* @param maxSize Maximum size | ||
*/ | ||
public abstract void setMaxSize(int maxSize); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters