Adding codecProfile and setCodecProfile to the ScreenEncoder

(cherry picked from commit db14945a119655c7775f480839983b615effbf2d)
This commit is contained in:
Tzah Mazuz 2020-03-12 16:56:27 +02:00
commit 89aa7b649a
2 changed files with 23 additions and 4 deletions

View file

@ -28,18 +28,20 @@ public class ScreenEncoder implements Device.RotationListener {
private int bitRate; private int bitRate;
private int maxFps; private int maxFps;
private int iFrameInterval; private int iFrameInterval;
private int codecProfile;
private boolean sendFrameMeta; private boolean sendFrameMeta;
private long ptsOrigin; private long ptsOrigin;
public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int iFrameInterval) { public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int codecProfile, int iFrameInterval) {
this.sendFrameMeta = sendFrameMeta; this.sendFrameMeta = sendFrameMeta;
this.bitRate = bitRate; this.bitRate = bitRate;
this.maxFps = maxFps; this.maxFps = maxFps;
this.codecProfile = codecProfile;
this.iFrameInterval = iFrameInterval; this.iFrameInterval = iFrameInterval;
} }
public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps) { public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int codecProfile) {
this(sendFrameMeta, bitRate, maxFps, DEFAULT_I_FRAME_INTERVAL); this(sendFrameMeta, bitRate, maxFps, codecProfile, DEFAULT_I_FRAME_INTERVAL);
} }
@Override @Override
@ -61,6 +63,7 @@ public class ScreenEncoder implements Device.RotationListener {
try { try {
do { do {
MediaCodec codec = createCodec(); MediaCodec codec = createCodec();
setCodecProfile(codec, format);
IBinder display = createDisplay(); IBinder display = createDisplay();
Rect contentRect = device.getScreenInfo().getContentRect(); Rect contentRect = device.getScreenInfo().getContentRect();
Rect videoRect = device.getScreenInfo().getVideoSize().toRect(); Rect videoRect = device.getScreenInfo().getVideoSize().toRect();
@ -134,6 +137,22 @@ public class ScreenEncoder implements Device.RotationListener {
IO.writeFully(fd, headerBuffer); IO.writeFully(fd, headerBuffer);
} }
private void setCodecProfile(MediaCodec codec, MediaFormat format) throws IOException {
if(codecProfile == 0) return;
int level = 0;
for (MediaCodecInfo.CodecProfileLevel profileLevel : codec.getCodecInfo().getCapabilitiesForType("video/avc").profileLevels) {
if(profileLevel.profile == codecProfile) {
level = Math.max(level, profileLevel.level);
}
}
if(level == 0) throw new IOException("Device doesn't support the requested codec profile.");
// Profile (SDK Level 21) and Level (SDK Level 23).
format.setInteger(MediaFormat.KEY_PROFILE, codecProfile);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
format.setInteger(MediaFormat.KEY_LEVEL, level);
}
}
private static MediaCodec createCodec() throws IOException { private static MediaCodec createCodec() throws IOException {
return MediaCodec.createEncoderByType("video/avc"); return MediaCodec.createEncoderByType("video/avc");
} }

View file

@ -19,7 +19,7 @@ public final class Server {
final Device device = new Device(options); final Device device = new Device(options);
boolean tunnelForward = options.isTunnelForward(); boolean tunnelForward = options.isTunnelForward();
try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) {
ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps()); ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), options.getCodecProfile());
if (options.getControl()) { if (options.getControl()) {
Controller controller = new Controller(device, connection); Controller controller = new Controller(device, connection);