obs-outputs: Fix file splitting overshooting when b-frames are used

I discovered while testing that the first split would always be one GOP
too long (e.g. 1m2s instead of 1m) due to the fact that b-frames and
negative start DTSes were not accounted for.

This is now fixed by setting the start_time to the nonzero negative DTS
produced for the first packet. Additionally, a small tolerance of 1 ms
was also added to account for rounding issues present in the first GOP.
This commit is contained in:
derrod
2026-08-21 14:33:06 -04:00
committed by Ryan Foster
parent 575c77f19d
commit f89ad4bee5
+13 -2
View File
@@ -51,6 +51,7 @@ struct mp4_output {
struct serializer serializer;
bool enable_bpm;
bool received_first_keyframe;
volatile bool active;
volatile bool stopping;
@@ -348,8 +349,11 @@ static inline bool should_split(struct mp4_output *out, struct encoder_packet *p
return true;
/* reached maximum duration */
if (out->max_time > 0 && packet->dts_usec - out->start_time >= out->max_time)
return true;
if (out->max_time > 0) {
const int64_t current_runtime = packet->dts_usec - out->start_time;
/* Allow a small error in timestamps (up to 1 ms). */
return llabs(out->max_time - current_runtime) < 1000LL;
}
return false;
}
@@ -532,6 +536,13 @@ static void mp4_output_packet(void *data, struct encoder_packet *packet)
}
}
/* Correct start time for b-frames */
if (!out->received_first_keyframe && packet->type == OBS_ENCODER_VIDEO && packet->track_idx == 0 &&
packet->keyframe) {
out->start_time = packet->dts_usec;
out->received_first_keyframe = true;
}
if (out->split_file_enabled) {
if (out->split_buffer.num) {
int64_t pts_usec = packet_pts_usec(packet);