diff --git a/include/encoder/encoder.h b/include/encoder/encoder.h index 7a808cc..b46deb5 100644 --- a/include/encoder/encoder.h +++ b/include/encoder/encoder.h @@ -19,6 +19,7 @@ typedef struct { AVFormatContext *format_context; AVStream *stream; int64_t start_pts; + int64_t first_pts; bool has_received_keyframe; char *first_frame_ts_filepath; bool first_frame_ts_written; @@ -26,6 +27,7 @@ typedef struct { typedef struct { gsr_replay_buffer *replay_buffer; + int64_t first_pts; pthread_mutex_t file_write_mutex; bool file_write_mutex_created; diff --git a/src/encoder/encoder.c b/src/encoder/encoder.c index 09d17ac..59d4c1d 100644 --- a/src/encoder/encoder.c +++ b/src/encoder/encoder.c @@ -38,6 +38,7 @@ bool gsr_encoder_init(gsr_encoder *self, gsr_replay_storage replay_storage, size memset(self, 0, sizeof(*self)); self->num_recording_destinations = 0; self->recording_destination_id_counter = 0; + self->first_pts = -1; if(pthread_mutex_init(&self->file_write_mutex, NULL) != 0) { fprintf(stderr, "gsr error: gsr_encoder_init: failed to create mutex\n"); @@ -95,6 +96,7 @@ void gsr_encoder_deinit(gsr_encoder *self) { self->num_recording_destinations = 0; self->recording_destination_id_counter = 0; + self->first_pts = -1; } void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_context, int64_t pts, int stream_index) { @@ -107,9 +109,12 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex av_packet->size = 0; int res = avcodec_receive_packet(codec_context, av_packet); if(res == 0) { // we have a packet, send the packet to the muxer + if(self->first_pts == -1) + self->first_pts = pts; + av_packet->stream_index = stream_index; - av_packet->pts = pts; - av_packet->dts = pts; + av_packet->pts = pts - self->first_pts; + av_packet->dts = av_packet->pts; if(self->replay_buffer) { pthread_mutex_lock(&self->replay_mutex); @@ -136,8 +141,11 @@ void gsr_encoder_receive_packets(gsr_encoder *self, AVCodecContext *codec_contex recording_destination->first_frame_ts_written = true; } - av_packet->pts = pts - recording_destination->start_pts; - av_packet->dts = pts - recording_destination->start_pts; + if(recording_destination->first_pts == -1) + recording_destination->first_pts = pts; + + av_packet->pts = (pts - recording_destination->first_pts) - recording_destination->start_pts; + av_packet->dts = av_packet->pts; av_packet_rescale_ts(av_packet, codec_context->time_base, recording_destination->stream->time_base); // TODO: Is av_interleaved_write_frame needed?. Answer: might be needed for mkv but dont use it! it causes frames to be inconsistent, skipping frames and duplicating frames. @@ -189,6 +197,7 @@ size_t gsr_encoder_add_recording_destination(gsr_encoder *self, AVCodecContext * recording_destination->format_context = format_context; recording_destination->stream = stream; recording_destination->start_pts = start_pts; + recording_destination->first_pts = -1; recording_destination->has_received_keyframe = false; recording_destination->first_frame_ts_filepath = NULL; recording_destination->first_frame_ts_written = false; diff --git a/src/main.cpp b/src/main.cpp index 3aa50b8..94a3a98 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -898,6 +898,7 @@ static AVStream* create_stream(AVFormatContext *av_format_context, AVCodecContex stream->id = av_format_context->nb_streams - 1; stream->time_base = codec_context->time_base; stream->avg_frame_rate = codec_context->framerate; + //stream->r_frame_rate = codec_context->framerate; return stream; } @@ -1084,6 +1085,9 @@ static RecordingStartResult start_recording_create_streams(const char *filename, AVFormatContext *av_format_context; avformat_alloc_output_context2(&av_format_context, nullptr, arg_parser.container_format, filename); + av_opt_set(av_format_context->priv_data, "use_editlist", "1", 0); + //av_opt_set(av_format_context->priv_data, "movflags", "+frag_keyframe+empty_moov+delay_moov", 0); + AVStream *video_stream = create_stream(av_format_context, video_codec_context); avcodec_parameters_from_context(video_stream->codecpar, video_codec_context); @@ -3785,6 +3789,9 @@ int main(int argc, char **argv) { _exit(1); } + av_opt_set(av_format_context->priv_data, "use_editlist", "1", 0); + //av_opt_set(av_format_context->priv_data, "movflags", "+frag_keyframe+empty_moov+delay_moov", 0); + const AVOutputFormat *output_format = av_format_context->oformat; std::string file_extension = output_format->extensions ? output_format->extensions : "";