/* gets the point where audio and video are closest together */ static size_t get_interleaved_start_idx(struct obs_output *output) { int64_t closest_diff = 0x7FFFFFFFFFFFFFFFLL; struct encoder_packet *first_video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); size_t video_idx = DARRAY_INVALID; size_t idx = 0; for (size_t i = 0; i < output->interleaved_packets.num; i++) { struct encoder_packet *packet = &output->interleaved_packets.array[i]; int64_t diff; if (packet->type != OBS_ENCODER_AUDIO) { if (packet == first_video) video_idx = i; continue; } diff = llabs(packet->dts_usec - first_video->dts_usec); if (diff < closest_diff) { closest_diff = diff; idx = i; } } return video_idx < idx ? video_idx : idx; }
static bool initialize_interleaved_packets(struct obs_output *output) { struct encoder_packet *video; struct encoder_packet *audio[MAX_AUDIO_MIXES]; size_t audio_mixes = num_audio_mixes(output); video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); if (!video) output->received_video = false; for (size_t i = 0; i < audio_mixes; i++) { audio[i] = find_first_packet_type(output, OBS_ENCODER_AUDIO, i); if (!audio[i]) { output->received_audio = false; return false; } } if (!video) { return false; } /* get new offsets */ output->video_offset = video->dts; for (size_t i = 0; i < audio_mixes; i++) output->audio_offsets[i] = audio[i]->dts; /* subtract offsets from highest TS offset variables */ output->highest_audio_ts -= audio[0]->dts_usec; output->highest_video_ts -= video->dts_usec; /* apply new offsets to all existing packet DTS/PTS values */ for (size_t i = 0; i < output->interleaved_packets.num; i++) { struct encoder_packet *packet = &output->interleaved_packets.array[i]; apply_interleaved_packet_offset(output, packet); } return true; }
static bool get_audio_and_video_packets(struct obs_output *output, struct encoder_packet **video, struct encoder_packet **audio, size_t audio_mixes) { *video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0); if (!*video) output->received_video = false; for (size_t i = 0; i < audio_mixes; i++) { audio[i] = find_first_packet_type(output, OBS_ENCODER_AUDIO, i); if (!audio[i]) { output->received_audio = false; return false; } } if (!*video) { return false; } return true; }
static void initialize_interleaved_packets(struct obs_output *output) { struct encoder_packet *video; struct encoder_packet *audio; video = find_first_packet_type(output, OBS_ENCODER_VIDEO); audio = find_first_packet_type(output, OBS_ENCODER_AUDIO); /* get new offsets */ output->video_offset = video->dts; output->audio_offset = audio->dts; /* subtract offsets from highest TS offset variables */ output->highest_audio_ts -= audio->dts_usec; output->highest_video_ts -= video->dts_usec; /* apply new offsets to all existing packet DTS/PTS values */ for (size_t i = 0; i < output->interleaved_packets.num; i++) { struct encoder_packet *packet = &output->interleaved_packets.array[i]; apply_interleaved_packet_offset(output, packet); } }