Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions plugins/obs-outputs/mp4-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2501,18 +2501,30 @@ static void process_packets(struct mp4_mux *mux, struct mp4_track *track, uint64
if (!count)
return;

/* Only iterate upt to penultimate packet so we can determine duration
* for all processed packets. */
for (size_t i = 0; i < count - 1; i++) {
/* Unless it is the final flush, only iterate up to penultimate packet so we can determine duration for all
* processed packets. */
const bool final_flush = mux->next_frag_pts == 0;
const size_t end_offset = final_flush ? 0 : 1;

for (size_t i = 0; i < count - end_offset; i++) {
struct encoder_packet *pkt = get_pkt_at(&track->packets, i);

if (mux->next_frag_pts && packet_pts_usec(pkt) >= mux->next_frag_pts)
if (!final_flush && packet_pts_usec(pkt) >= mux->next_frag_pts)
break;

struct encoder_packet *next = get_pkt_at(&track->packets, i + 1);
uint32_t duration;
if (i < count - 1) {
/* If a next packet is available: Duration is just distance between current and next DTS. */
struct encoder_packet *next = get_pkt_at(&track->packets, i + 1);
duration = (uint32_t)(next->dts - pkt->dts);
} else {
/* If this is the last packet, and we're doing a final flush: Reuse the previous duration */
if (!track->fragment_samples.num)
break; /* no previous sample */

duration = track->fragment_samples.array[track->fragment_samples.num - 1].duration;
}

/* Duration is just distance between current and next DTS. */
uint32_t duration = (uint32_t)(next->dts - pkt->dts);
uint32_t sample_count = 1;
uint32_t size = (uint32_t)pkt->size;
int32_t offset = (int32_t)(pkt->pts - pkt->dts);
Expand Down
15 changes: 13 additions & 2 deletions plugins/obs-outputs/mp4-output.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct mp4_output {
struct serializer serializer;

bool enable_bpm;
bool received_first_keyframe;

volatile bool active;
volatile bool stopping;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
Loading