浏览代码

libobs: Always prune excessive starting audio packets

On outputs that use already-active video/audio encoder, the audio
pruning to sync up audio packets with video packets doesn't always get
called (for example if the video pruning function was called).  Always
prune excess starting audio packets.
jp9000 9 年之前
父节点
当前提交
82a7d795db
共有 1 个文件被更改,包括 33 次插入12 次删除
  1. 33 12
      libobs/obs-output.c

+ 33 - 12
libobs/obs-output.c

@@ -1076,15 +1076,12 @@ static inline struct encoder_packet *find_last_packet_type(
 	return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL;
 	return (idx != -1) ? &output->interleaved_packets.array[idx] : NULL;
 }
 }
 
 
-static bool initialize_interleaved_packets(struct obs_output *output)
+static bool get_audio_and_video_packets(struct obs_output *output,
+		struct encoder_packet **video,
+		struct encoder_packet **audio, size_t audio_mixes)
 {
 {
-	struct encoder_packet *video;
-	struct encoder_packet *audio[MAX_AUDIO_MIXES];
-	struct encoder_packet *last_audio[MAX_AUDIO_MIXES];
-	size_t audio_mixes = num_audio_mixes(output);
-
-	video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0);
-	if (!video)
+	*video = find_first_packet_type(output, OBS_ENCODER_VIDEO, 0);
+	if (!*video)
 		output->received_video = false;
 		output->received_video = false;
 
 
 	for (size_t i = 0; i < audio_mixes; i++) {
 	for (size_t i = 0; i < audio_mixes; i++) {
@@ -1093,15 +1090,30 @@ static bool initialize_interleaved_packets(struct obs_output *output)
 			output->received_audio = false;
 			output->received_audio = false;
 			return false;
 			return false;
 		}
 		}
-
-		last_audio[i] = find_last_packet_type(output, OBS_ENCODER_AUDIO,
-				i);
 	}
 	}
 
 
-	if (!video) {
+	if (!*video) {
 		return false;
 		return false;
 	}
 	}
 
 
+	return true;
+}
+
+static bool initialize_interleaved_packets(struct obs_output *output)
+{
+	struct encoder_packet *video;
+	struct encoder_packet *audio[MAX_AUDIO_MIXES];
+	struct encoder_packet *last_audio[MAX_AUDIO_MIXES];
+	size_t audio_mixes = num_audio_mixes(output);
+	size_t start_idx;
+
+	if (!get_audio_and_video_packets(output, &video, audio, audio_mixes))
+		return false;
+
+	for (size_t i = 0; i < audio_mixes; i++)
+		last_audio[i] = find_last_packet_type(output, OBS_ENCODER_AUDIO,
+				i);
+
 	/* ensure that there is audio past the first video packet */
 	/* ensure that there is audio past the first video packet */
 	for (size_t i = 0; i < audio_mixes; i++) {
 	for (size_t i = 0; i < audio_mixes; i++) {
 		if (last_audio[i]->dts_usec < video->dts_usec) {
 		if (last_audio[i]->dts_usec < video->dts_usec) {
@@ -1110,6 +1122,15 @@ static bool initialize_interleaved_packets(struct obs_output *output)
 		}
 		}
 	}
 	}
 
 
+	/* clear out excess starting audio if it hasn't been already */
+	start_idx = get_interleaved_start_idx(output);
+	if (start_idx) {
+		discard_to_idx(output, start_idx);
+		if (!get_audio_and_video_packets(output, &video, audio,
+					audio_mixes))
+			return false;
+	}
+
 	/* get new offsets */
 	/* get new offsets */
 	output->video_offset = video->dts;
 	output->video_offset = video->dts;
 	for (size_t i = 0; i < audio_mixes; i++)
 	for (size_t i = 0; i < audio_mixes; i++)