|
|
@@ -309,6 +309,35 @@ static void set_file_not_readable_error(struct ffmpeg_muxer *stream,
|
|
|
obs_data_release(settings);
|
|
|
}
|
|
|
|
|
|
+inline static void ts_offset_clear(struct ffmpeg_muxer *stream)
|
|
|
+{
|
|
|
+ stream->found_video = false;
|
|
|
+ stream->video_pts_offset = 0;
|
|
|
+
|
|
|
+ for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) {
|
|
|
+ stream->found_audio[i] = false;
|
|
|
+ stream->audio_dts_offsets[i] = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+inline static void ts_offset_update(struct ffmpeg_muxer *stream,
|
|
|
+ struct encoder_packet *packet)
|
|
|
+{
|
|
|
+ if (packet->type == OBS_ENCODER_VIDEO) {
|
|
|
+ if (!stream->found_video) {
|
|
|
+ stream->video_pts_offset = packet->pts;
|
|
|
+ stream->found_video = true;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (stream->found_audio[packet->track_idx])
|
|
|
+ return;
|
|
|
+
|
|
|
+ stream->audio_dts_offsets[packet->track_idx] = packet->dts;
|
|
|
+ stream->found_audio[packet->track_idx] = true;
|
|
|
+}
|
|
|
+
|
|
|
static bool ffmpeg_mux_start(void *data)
|
|
|
{
|
|
|
struct ffmpeg_muxer *stream = data;
|
|
|
@@ -328,6 +357,7 @@ static bool ffmpeg_mux_start(void *data)
|
|
|
return false;
|
|
|
path = obs_service_get_url(service);
|
|
|
stream->split_file = false;
|
|
|
+ stream->reset_timestamps = false;
|
|
|
} else {
|
|
|
path = obs_data_get_string(settings, "path");
|
|
|
|
|
|
@@ -337,12 +367,16 @@ static bool ffmpeg_mux_start(void *data)
|
|
|
(1024 * 1024);
|
|
|
stream->split_file = stream->max_time > 0 ||
|
|
|
stream->max_size > 0;
|
|
|
+ stream->reset_timestamps =
|
|
|
+ obs_data_get_bool(settings, "reset_timestamps");
|
|
|
stream->allow_overwrite =
|
|
|
obs_data_get_bool(settings, "allow_overwrite");
|
|
|
stream->cur_size = 0;
|
|
|
stream->sent_headers = false;
|
|
|
}
|
|
|
|
|
|
+ ts_offset_clear(stream);
|
|
|
+
|
|
|
if (!stream->is_network) {
|
|
|
/* ensure output path is writable to avoid generic error
|
|
|
* message.
|
|
|
@@ -545,6 +579,16 @@ bool write_packet(struct ffmpeg_muxer *stream, struct encoder_packet *packet)
|
|
|
: FFM_PACKET_AUDIO,
|
|
|
.keyframe = packet->keyframe};
|
|
|
|
|
|
+ if (stream->split_file && stream->reset_timestamps) {
|
|
|
+ if (is_video) {
|
|
|
+ info.dts -= stream->video_pts_offset;
|
|
|
+ info.pts -= stream->video_pts_offset;
|
|
|
+ } else {
|
|
|
+ info.dts -= stream->audio_dts_offsets[info.index];
|
|
|
+ info.pts -= stream->audio_dts_offsets[info.index];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
ret = os_process_pipe_write(stream->pipe, (const uint8_t *)&info,
|
|
|
sizeof(info));
|
|
|
if (ret != sizeof(info)) {
|
|
|
@@ -682,6 +726,7 @@ static bool prepare_split_file(struct ffmpeg_muxer *stream,
|
|
|
|
|
|
stream->cur_size = 0;
|
|
|
stream->cur_time = packet->dts_usec;
|
|
|
+ ts_offset_clear(stream);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -721,6 +766,9 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (stream->split_file && stream->reset_timestamps)
|
|
|
+ ts_offset_update(stream, packet);
|
|
|
+
|
|
|
write_packet(stream, packet);
|
|
|
}
|
|
|
|