This commit is contained in:
gz0119 2025-03-10 20:57:45 +08:00
commit 11f7b2995b
4 changed files with 20 additions and 11 deletions

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ build/
/x/ /x/
local.properties local.properties
/scrcpy-server /scrcpy-server
.DS_Store

View file

@ -9,7 +9,7 @@
#include "util/binary.h" #include "util/binary.h"
#include "util/log.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_CONFIG (UINT64_C(1) << 63)
#define SC_PACKET_FLAG_KEY_FRAME (UINT64_C(1) << 62) #define SC_PACKET_FLAG_KEY_FRAME (UINT64_C(1) << 62)
@ -95,11 +95,11 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
// The video and audio streams contain a sequence of raw packets (as // The video and audio streams contain a sequence of raw packets (as
// provided by MediaCodec), each prefixed with a "meta" header. // provided by MediaCodec), each prefixed with a "meta" header.
// //
// The "meta" header length is 12 bytes: // The "meta" header length is 16 bytes:
// [. . . . . . . .|. . . .]. . . . . . . . . . . . . . . ... // [. . . . . . . .|. . . .][. . . .]. . . . . . . . . . . . . . . ...
// <-------------> <-----> <-----------------------------... // <-------------> <------> <------> <-----------------------------...
// PTS packet raw packet // PTS packet screen raw packet
// size // size orientation
// //
// It is followed by <packet_size> bytes containing the packet/frame. // It is followed by <packet_size> bytes containing the packet/frame.
// //
@ -149,6 +149,7 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
} }
packet->dts = packet->pts; packet->dts = packet->pts;
return true; return true;
} }

View file

@ -132,7 +132,7 @@ public final class Server {
audioCapture = new AudioPlaybackCapture(options.getAudioDup()); 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; AsyncProcessor audioRecorder;
if (audioCodec == AudioCodec.RAW) { if (audioCodec == AudioCodec.RAW) {
audioRecorder = new AudioRawRecorder(audioCapture, audioStreamer); audioRecorder = new AudioRawRecorder(audioCapture, audioStreamer);
@ -144,7 +144,7 @@ public final class Server {
if (video) { if (video) {
Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecMeta(), Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecMeta(),
options.getSendFrameMeta()); options.getSendFrameMeta(), options.getDisplayId());
SurfaceCapture surfaceCapture; SurfaceCapture surfaceCapture;
if (options.getVideoSource() == VideoSource.DISPLAY) { if (options.getVideoSource() == VideoSource.DISPLAY) {
NewDisplay newDisplay = options.getNewDisplay(); NewDisplay newDisplay = options.getNewDisplay();

View file

@ -21,15 +21,17 @@ public final class Streamer {
private final Codec codec; private final Codec codec;
private final boolean sendCodecMeta; private final boolean sendCodecMeta;
private final boolean sendFrameMeta; private final boolean sendFrameMeta;
private final int displayId;
private final int HEADER_PACKET_SIZE = 12; private final int HEADER_PACKET_SIZE = 12;
private final ByteBuffer headerBuffer = ByteBuffer.allocate(HEADER_PACKET_SIZE); private final ByteBuffer headerBuffer = ByteBuffer.allocate(HEADER_PACKET_SIZE);
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.fd = fd;
this.codec = codec; this.codec = codec;
this.sendCodecMeta = sendCodecMeta; this.sendCodecMeta = sendCodecMeta;
this.sendFrameMeta = sendFrameMeta; this.sendFrameMeta = sendFrameMeta;
this.displayId = displayId;
} }
public Codec getCodec() { public Codec getCodec() {
@ -77,11 +79,15 @@ public final class Streamer {
} }
if (sendFrameMeta) { if (sendFrameMeta) {
writeFrameMeta(fd, buffer.remaining(), pts, config, keyFrame); int screenOrientation = getScreenOrientation();
writeFrameMeta(fd, buffer.remaining(), pts, config, keyFrame, screenOrientation);
} }
IO.writeFully(fd, buffer); IO.writeFully(fd, buffer);
} }
private int getScreenOrientation() {
return Device.getCurrentRotation(this.displayId);
}
public void writePacket(ByteBuffer codecBuffer, MediaCodec.BufferInfo bufferInfo) throws IOException { public void writePacket(ByteBuffer codecBuffer, MediaCodec.BufferInfo bufferInfo) throws IOException {
long pts = bufferInfo.presentationTimeUs; long pts = bufferInfo.presentationTimeUs;
@ -90,7 +96,7 @@ public final class Streamer {
writePacket(codecBuffer, pts, config, keyFrame); 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(); headerBuffer.clear();
long ptsAndFlags; long ptsAndFlags;
@ -105,6 +111,7 @@ public final class Streamer {
headerBuffer.putLong(ptsAndFlags); headerBuffer.putLong(ptsAndFlags);
headerBuffer.putInt(packetSize); headerBuffer.putInt(packetSize);
headerBuffer.putInt(screenOrientation);
headerBuffer.flip(); headerBuffer.flip();
IO.writeFully(fd, headerBuffer); IO.writeFully(fd, headerBuffer);
} }