Fix PTS/DTS

This commit is contained in:
Romain Vimont 2018-11-09 16:09:15 +01:00
commit 1f5221897a
3 changed files with 33 additions and 11 deletions

View file

@ -15,6 +15,7 @@
#include "recorder.h" #include "recorder.h"
#define BUFSIZE 0x10000 #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) 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; return ret;
decoder->pts = from_be(header, 8); decoder->pts = from_be(header, 8);
decoder->buffer_info_flags = from_be(header + 8, 4);
remaining = from_be(header + 12, 4); remaining = from_be(header + 12, 4);
} }
@ -142,13 +144,20 @@ static int run_decoder(void *data) {
while (!av_read_frame(format_ctx, &packet)) { while (!av_read_frame(format_ctx, &packet)) {
if (decoder->recorder) { if (decoder->recorder) {
packet.pts = decoder->pts; // do not record configuration packets
// no need to rescale with av_packet_rescale_ts(), the timestamps // (they contain no media data and have no PTS/DTS)
// are in microseconds both in input and output // FIXME do not use MediaCodec specific flags
if (!recorder_write(decoder->recorder, &packet)) { if (!(decoder->buffer_info_flags & MEDIA_CODEC_FLAG_CONFIG)) {
LOGE("Could not write frame to output file"); packet.pts = decoder->pts;
av_packet_unref(&packet); packet.dts = decoder->pts;
goto run_quit;
// 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;
}
} }
} }

View file

@ -10,12 +10,13 @@
struct frames; struct frames;
struct decoder { struct decoder {
uint64_t pts;
struct frames *frames; struct frames *frames;
socket_t video_socket; socket_t video_socket;
SDL_Thread *thread; SDL_Thread *thread;
SDL_mutex *mutex; SDL_mutex *mutex;
struct recorder *recorder; struct recorder *recorder;
uint64_t pts;
uint32_t buffer_info_flags;
int remaining; int remaining;
}; };

View file

@ -29,6 +29,7 @@ public class ScreenEncoder implements Device.RotationListener {
private int bitRate; private int bitRate;
private int frameRate; private int frameRate;
private int iFrameInterval; private int iFrameInterval;
private long ptsOrigin;
public ScreenEncoder(int bitRate, int frameRate, int iFrameInterval) { public ScreenEncoder(int bitRate, int frameRate, int iFrameInterval) {
this.bitRate = bitRate; this.bitRate = bitRate;
@ -93,11 +94,22 @@ public class ScreenEncoder implements Device.RotationListener {
} }
if (outputBufferId >= 0) { if (outputBufferId >= 0) {
ByteBuffer codecBuffer = codec.getOutputBuffer(outputBufferId); ByteBuffer codecBuffer = codec.getOutputBuffer(outputBufferId);
bBuffer.position(0); bBuffer.clear();
bBuffer.putLong(bufferInfo.presentationTimeUs);
long pts;
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
pts = 0; // no pts for non-media packets
} else {
if (ptsOrigin == 0) {
ptsOrigin = bufferInfo.presentationTimeUs;
}
pts = bufferInfo.presentationTimeUs - ptsOrigin;
}
bBuffer.putLong(pts);
bBuffer.putInt(bufferInfo.flags); bBuffer.putInt(bufferInfo.flags);
bBuffer.putInt(codecBuffer.remaining()); bBuffer.putInt(codecBuffer.remaining());
bBuffer.position(0); bBuffer.flip();
IO.writeFully(fd, bBuffer); IO.writeFully(fd, bBuffer);
IO.writeFully(fd, codecBuffer); IO.writeFully(fd, codecBuffer);
} }