libobs: Fix multi. video encoder sync issues
When using multiple video encoders together with a single audio encoder, the audio wouldn't be in sync. The reason why this occurred is because the dts_usec variable of the encoder packet (which is based on system time) would always be reset to a value based upon the dts (which is not guaranteed to be based on system time) in the apply_interleaved_packet_offset function. This would then in turn cause it to miscalculate the starting audio/video offsets, which are required to calculate sync. So instead of calling that function unnecessarily, separate the check for whether audio/video has been received in to a new function, and only start applying the interleaved offsets after audio and video have actually started up and the starting offsets have been calculated.
This commit is contained in:
parent
c2832b8b1c
commit
ffc7b3c666
@ -671,7 +671,7 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
|
||||
size_t size = data->frames * encoder->blocksize;
|
||||
size_t offset_size = 0;
|
||||
|
||||
if (encoder->paired_encoder && !encoder->start_ts) {
|
||||
if (!encoder->start_ts && encoder->paired_encoder) {
|
||||
uint64_t end_ts = data->timestamp;
|
||||
uint64_t v_start_ts = encoder->paired_encoder->start_ts;
|
||||
|
||||
@ -693,6 +693,9 @@ static bool buffer_audio(struct obs_encoder *encoder, struct audio_data *data)
|
||||
}
|
||||
|
||||
encoder->start_ts = v_start_ts;
|
||||
|
||||
} else if (!encoder->start_ts && !encoder->paired_encoder) {
|
||||
encoder->start_ts = data->timestamp;
|
||||
}
|
||||
|
||||
size -= offset_size;
|
||||
|
@ -677,7 +677,19 @@ static size_t get_track_index(const struct obs_output *output,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apply_interleaved_packet_offset(struct obs_output *output,
|
||||
static inline void check_received(struct obs_output *output,
|
||||
struct encoder_packet *out)
|
||||
{
|
||||
if (out->type == OBS_ENCODER_VIDEO) {
|
||||
if (!output->received_video)
|
||||
output->received_video = true;
|
||||
} else {
|
||||
if (!output->received_audio)
|
||||
output->received_audio = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void apply_interleaved_packet_offset(struct obs_output *output,
|
||||
struct encoder_packet *out)
|
||||
{
|
||||
int64_t offset;
|
||||
@ -686,17 +698,8 @@ static void apply_interleaved_packet_offset(struct obs_output *output,
|
||||
* may not currently be at 0 when we get data. so, we store the
|
||||
* current dts as offset and subtract that value from the dts/pts
|
||||
* of the output packet. */
|
||||
if (out->type == OBS_ENCODER_VIDEO) {
|
||||
if (!output->received_video)
|
||||
output->received_video = true;
|
||||
|
||||
offset = output->video_offset;
|
||||
} else {
|
||||
if (!output->received_audio)
|
||||
output->received_audio = true;
|
||||
|
||||
offset = output->audio_offsets[out->track_idx];
|
||||
}
|
||||
offset = (out->type == OBS_ENCODER_VIDEO) ?
|
||||
output->video_offset : output->audio_offsets[out->track_idx];
|
||||
|
||||
out->dts -= offset;
|
||||
out->pts -= offset;
|
||||
@ -896,7 +899,12 @@ static void interleave_packets(void *data, struct encoder_packet *packet)
|
||||
was_started = output->received_audio && output->received_video;
|
||||
|
||||
obs_duplicate_encoder_packet(&out, packet);
|
||||
apply_interleaved_packet_offset(output, &out);
|
||||
|
||||
if (was_started)
|
||||
apply_interleaved_packet_offset(output, &out);
|
||||
else
|
||||
check_received(output, packet);
|
||||
|
||||
insert_interleaved_packet(output, &out);
|
||||
set_higher_ts(output, &out);
|
||||
|
||||
@ -1078,7 +1086,9 @@ static inline bool pair_encoders(obs_output_t *output, size_t num_mixes)
|
||||
{
|
||||
if (num_mixes == 1 &&
|
||||
!output->audio_encoders[0]->active &&
|
||||
!output->video_encoder->active) {
|
||||
!output->video_encoder->active &&
|
||||
!output->video_encoder->paired_encoder &&
|
||||
!output->audio_encoders[0]->paired_encoder) {
|
||||
|
||||
output->audio_encoders[0]->wait_for_video = true;
|
||||
output->audio_encoders[0]->paired_encoder =
|
||||
|
Loading…
x
Reference in New Issue
Block a user