mirror of https://github.com/Genymobile/scrcpy
Pass key frame flag from the device
MediaCodec indicates when a packet is a key frame. Transmit it to the client.
This commit is contained in:
parent
e3c2398aa2
commit
67068e4e3d
|
@ -15,8 +15,9 @@
|
||||||
#define HEADER_SIZE 12
|
#define HEADER_SIZE 12
|
||||||
|
|
||||||
#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_PTS_MASK (SC_PACKET_FLAG_CONFIG - 1)
|
#define SC_PACKET_PTS_MASK (SC_PACKET_FLAG_KEY_FRAME - 1)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
|
@ -35,10 +36,11 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
// The most significant bits of the PTS are used for packet flags:
|
// The most significant bits of the PTS are used for packet flags:
|
||||||
//
|
//
|
||||||
// byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
|
// byte 7 byte 6 byte 5 byte 4 byte 3 byte 2 byte 1 byte 0
|
||||||
// C....... ........ ........ ........ ........ ........ ........ ........
|
// CK...... ........ ........ ........ ........ ........ ........ ........
|
||||||
// ^<-------------------------------------------------------------------->
|
// ^^<------------------------------------------------------------------->
|
||||||
// | PTS
|
// || PTS
|
||||||
// `- config packet
|
// | `- config packet
|
||||||
|
// `-- key frame
|
||||||
|
|
||||||
uint8_t header[HEADER_SIZE];
|
uint8_t header[HEADER_SIZE];
|
||||||
ssize_t r = net_recv_all(demuxer->socket, header, HEADER_SIZE);
|
ssize_t r = net_recv_all(demuxer->socket, header, HEADER_SIZE);
|
||||||
|
@ -67,6 +69,10 @@ sc_demuxer_recv_packet(struct sc_demuxer *demuxer, AVPacket *packet) {
|
||||||
packet->pts = pts_flags & SC_PACKET_PTS_MASK;
|
packet->pts = pts_flags & SC_PACKET_PTS_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pts_flags & SC_PACKET_FLAG_KEY_FRAME) {
|
||||||
|
packet->flags |= AV_PKT_FLAG_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
||||||
private static final int[] MAX_SIZE_FALLBACK = {2560, 1920, 1600, 1280, 1024, 800};
|
private static final int[] MAX_SIZE_FALLBACK = {2560, 1920, 1600, 1280, 1024, 800};
|
||||||
|
|
||||||
private static final long PACKET_FLAG_CONFIG = 1L << 63;
|
private static final long PACKET_FLAG_CONFIG = 1L << 63;
|
||||||
|
private static final long PACKET_FLAG_KEY_FRAME = 1L << 62;
|
||||||
|
|
||||||
private final AtomicBoolean rotationChanged = new AtomicBoolean();
|
private final AtomicBoolean rotationChanged = new AtomicBoolean();
|
||||||
private final ByteBuffer headerBuffer = ByteBuffer.allocate(12);
|
private final ByteBuffer headerBuffer = ByteBuffer.allocate(12);
|
||||||
|
@ -189,6 +190,9 @@ public class ScreenEncoder implements Device.RotationListener {
|
||||||
ptsOrigin = bufferInfo.presentationTimeUs;
|
ptsOrigin = bufferInfo.presentationTimeUs;
|
||||||
}
|
}
|
||||||
pts = bufferInfo.presentationTimeUs - ptsOrigin;
|
pts = bufferInfo.presentationTimeUs - ptsOrigin;
|
||||||
|
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||||
|
pts |= PACKET_FLAG_KEY_FRAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
headerBuffer.putLong(pts);
|
headerBuffer.putLong(pts);
|
||||||
|
|
Loading…
Reference in New Issue