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:
Romain Vimont 2022-02-11 19:33:35 +01:00
parent e3c2398aa2
commit 67068e4e3d
2 changed files with 15 additions and 5 deletions

View file

@ -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;
} }

View file

@ -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);