From 2cd99e72051fd91c6616743add7126c1c799f0e6 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 9 Nov 2018 16:09:15 +0100 Subject: [PATCH] Only set valid PTS/DTS When the PTS is valid, set both PTS and DTS to avoid FFmpeg warnings. Since configuration packets have no PTS, do not record these packets. --- app/src/decoder.c | 23 +++++++++++++------ app/src/decoder.h | 3 ++- .../com/genymobile/scrcpy/ScreenEncoder.java | 18 ++++++++++++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/app/src/decoder.c b/app/src/decoder.c index 6543acb4..681a5609 100644 --- a/app/src/decoder.c +++ b/app/src/decoder.c @@ -15,6 +15,7 @@ #include "recorder.h" #define BUFSIZE 0x10000 +#define MEDIA_CODEC_FLAG_CONFIG 2 // MediaCodec.BUFFER_FLAG_CODEC_CONFIG static inline uint64_t from_be(uint8_t *b, int size) { @@ -45,6 +46,7 @@ static int read_packet(void *opaque, uint8_t *buf, int buf_size) { return ret; decoder->pts = from_be(header, 8); + decoder->buffer_info_flags = from_be(header + 8, 4); remaining = from_be(header + 12, 4); } @@ -141,13 +143,20 @@ static int run_decoder(void *data) { while (!av_read_frame(format_ctx, &packet)) { if (decoder->recorder) { - packet.pts = decoder->pts; - // no need to rescale with av_packet_rescale_ts(), the timestamps - // are in microseconds both in input and output - if (!recorder_write(decoder->recorder, &packet)) { - LOGE("Could not write frame to output file"); - av_packet_unref(&packet); - goto run_quit; + // do not record configuration packets + // (they contain no media data and have no PTS/DTS) + // FIXME do not use MediaCodec specific flags + if (!(decoder->buffer_info_flags & MEDIA_CODEC_FLAG_CONFIG)) { + packet.pts = decoder->pts; + packet.dts = decoder->pts; + + // no need to rescale with av_packet_rescale_ts(), the timestamps + // are in microseconds both in input and output + if (!recorder_write(decoder->recorder, &packet)) { + LOGE("Could not write frame to output file"); + av_packet_unref(&packet); + goto run_quit; + } } } diff --git a/app/src/decoder.h b/app/src/decoder.h index 9c673973..fa1200b4 100644 --- a/app/src/decoder.h +++ b/app/src/decoder.h @@ -10,12 +10,13 @@ struct frames; struct decoder { - uint64_t pts; struct frames *frames; socket_t video_socket; SDL_Thread *thread; SDL_mutex *mutex; struct recorder *recorder; + uint64_t pts; + uint32_t buffer_info_flags; int remaining; }; diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index c5cabfdb..325febbb 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -29,6 +29,7 @@ public class ScreenEncoder implements Device.RotationListener { private int bitRate; private int frameRate; private int iFrameInterval; + private long ptsOrigin; public ScreenEncoder(int bitRate, int frameRate, int iFrameInterval) { this.bitRate = bitRate; @@ -93,11 +94,22 @@ public class ScreenEncoder implements Device.RotationListener { } if (outputBufferId >= 0) { ByteBuffer codecBuffer = codec.getOutputBuffer(outputBufferId); - bBuffer.position(0); - bBuffer.putLong(bufferInfo.presentationTimeUs); + bBuffer.clear(); + + long pts; + if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { + pts = 0; // non-media data packet + } else { + if (ptsOrigin == 0) { + ptsOrigin = bufferInfo.presentationTimeUs; + } + pts = bufferInfo.presentationTimeUs - ptsOrigin; + } + + bBuffer.putLong(pts); bBuffer.putInt(bufferInfo.flags); bBuffer.putInt(codecBuffer.remaining()); - bBuffer.position(0); + bBuffer.flip(); IO.writeFully(fd, bBuffer); IO.writeFully(fd, codecBuffer); }