diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..2b0d21d7 Binary files /dev/null and b/.DS_Store differ diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 00000000..b65ed92e Binary files /dev/null and b/app/.DS_Store differ diff --git a/app/src/demuxer.c b/app/src/demuxer.c index 885cd6ee..0eb1a171 100644 --- a/app/src/demuxer.c +++ b/app/src/demuxer.c @@ -9,7 +9,7 @@ #include "util/binary.h" #include "util/log.h" -#define SC_PACKET_HEADER_SIZE 12 +#define SC_PACKET_HEADER_SIZE 16 #define SC_PACKET_FLAG_CONFIG (UINT64_C(1) << 63) #define SC_PACKET_FLAG_KEY_FRAME (UINT64_C(1) << 62) @@ -82,11 +82,11 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) { // The video and audio streams contain a sequence of raw packets (as // provided by MediaCodec), each prefixed with a "meta" header. // - // The "meta" header length is 12 bytes: - // [. . . . . . . .|. . . .]. . . . . . . . . . . . . . . ... - // <-------------> <-----> <-----------------------------... - // PTS packet raw packet - // size + // The "meta" header length is 16 bytes: + // [. . . . . . . .|. . . .][. . . .]. . . . . . . . . . . . . . . ... + // <-------------> <------> <------> <-----------------------------... + // PTS packet screen raw packet + // size orientation // // It is followed by bytes containing the packet/frame. // @@ -107,6 +107,8 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) { uint64_t pts_flags = sc_read64be(header); uint32_t len = sc_read32be(&header[8]); + uint32_t screen_orientation = sc_read32be(&header[12]); + LOGD("Screen Orientation: %u", screen_orientation); assert(len); if (av_new_packet(packet, len)) { @@ -131,6 +133,7 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) { } packet->dts = packet->pts; + return true; } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 09cfd6cf..b40632f0 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -132,7 +132,7 @@ public final class Server { audioCapture = new AudioPlaybackCapture(options.getAudioDup()); } - Streamer audioStreamer = new Streamer(connection.getAudioFd(), audioCodec, options.getSendCodecMeta(), options.getSendFrameMeta()); + Streamer audioStreamer = new Streamer(connection.getAudioFd(), audioCodec, options.getSendCodecMeta(), options.getSendFrameMeta(), options.getDisplayId()); AsyncProcessor audioRecorder; if (audioCodec == AudioCodec.RAW) { audioRecorder = new AudioRawRecorder(audioCapture, audioStreamer); @@ -144,7 +144,7 @@ public final class Server { if (video) { Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecMeta(), - options.getSendFrameMeta()); + options.getSendFrameMeta(), options.getDisplayId()); SurfaceCapture surfaceCapture; if (options.getVideoSource() == VideoSource.DISPLAY) { NewDisplay newDisplay = options.getNewDisplay(); diff --git a/server/src/main/java/com/genymobile/scrcpy/device/Device.java b/server/src/main/java/com/genymobile/scrcpy/device/Device.java index 3553dc27..687ec4a4 100644 --- a/server/src/main/java/com/genymobile/scrcpy/device/Device.java +++ b/server/src/main/java/com/genymobile/scrcpy/device/Device.java @@ -210,7 +210,7 @@ public final class Device { } } - private static int getCurrentRotation(int displayId) { + public static int getCurrentRotation(int displayId) { assert displayId != DISPLAY_ID_NONE; if (displayId == 0) { diff --git a/server/src/main/java/com/genymobile/scrcpy/device/Streamer.java b/server/src/main/java/com/genymobile/scrcpy/device/Streamer.java index f54d0567..99cc343c 100644 --- a/server/src/main/java/com/genymobile/scrcpy/device/Streamer.java +++ b/server/src/main/java/com/genymobile/scrcpy/device/Streamer.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; +import com.genymobile.scrcpy.util.Ln; public final class Streamer { @@ -21,14 +22,16 @@ public final class Streamer { private final Codec codec; private final boolean sendCodecMeta; private final boolean sendFrameMeta; + private final int displayId; - private final ByteBuffer headerBuffer = ByteBuffer.allocate(12); + private final ByteBuffer headerBuffer = ByteBuffer.allocate(16); - public Streamer(FileDescriptor fd, Codec codec, boolean sendCodecMeta, boolean sendFrameMeta) { + public Streamer(FileDescriptor fd, Codec codec, boolean sendCodecMeta, boolean sendFrameMeta, int displayId) { this.fd = fd; this.codec = codec; this.sendCodecMeta = sendCodecMeta; this.sendFrameMeta = sendFrameMeta; + this.displayId = displayId; } public Codec getCodec() { @@ -76,11 +79,15 @@ public final class Streamer { } if (sendFrameMeta) { - writeFrameMeta(fd, buffer.remaining(), pts, config, keyFrame); + int screenOrientation = getScreenOrientation(); + writeFrameMeta(fd, buffer.remaining(), pts, config, keyFrame, screenOrientation); } IO.writeFully(fd, buffer); } + private int getScreenOrientation() { + return Device.getCurrentRotation(this.displayId); + } public void writePacket(ByteBuffer codecBuffer, MediaCodec.BufferInfo bufferInfo) throws IOException { long pts = bufferInfo.presentationTimeUs; @@ -89,7 +96,7 @@ public final class Streamer { writePacket(codecBuffer, pts, config, keyFrame); } - private void writeFrameMeta(FileDescriptor fd, int packetSize, long pts, boolean config, boolean keyFrame) throws IOException { + private void writeFrameMeta(FileDescriptor fd, int packetSize, long pts, boolean config, boolean keyFrame, int screenOrientation) throws IOException { headerBuffer.clear(); long ptsAndFlags; @@ -104,6 +111,7 @@ public final class Streamer { headerBuffer.putLong(ptsAndFlags); headerBuffer.putInt(packetSize); + headerBuffer.putInt(screenOrientation); headerBuffer.flip(); IO.writeFully(fd, headerBuffer); }