Fix PTS/DTS

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

View file

@ -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);
}
@ -142,13 +144,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;
}
}
}

View file

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

View file

@ -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; // 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(codecBuffer.remaining());
bBuffer.position(0);
bBuffer.flip();
IO.writeFully(fd, bBuffer);
IO.writeFully(fd, codecBuffer);
}