浏览代码

Perform timestamp smoothing in media-io as well

Doing timestamp smoothing in obs-source.c is good because timestamps can
typically operate on a different timebase, however, obs-source.c can
also change that time base dynamically (such as with async video and
unexpected timestamp jumps), so in order to ensure that audio is
seamless in the output as well, perform timestamp smoothing in
audio-io.c as well just as an extra precautionary measure.
jp9000 11 年之前
父节点
当前提交
5ac364ff9a
共有 1 个文件被更改,包括 22 次插入3 次删除
  1. 22 3
      libobs/media-io/audio-io.c

+ 22 - 3
libobs/media-io/audio-io.c

@@ -53,6 +53,8 @@ struct audio_line {
 	uint64_t                   base_timestamp;
 	uint64_t                   base_timestamp;
 	uint64_t                   last_timestamp;
 	uint64_t                   last_timestamp;
 
 
+	uint64_t                   next_ts_min;
+
 	/* states whether this line is still being used.  if not, then when the
 	/* states whether this line is still being used.  if not, then when the
 	 * buffer is depleted, it's destroyed */
 	 * buffer is depleted, it's destroyed */
 	bool                       alive;
 	bool                       alive;
@@ -659,16 +661,33 @@ static void audio_line_place_data_pos(struct audio_line *line,
 	}
 	}
 }
 }
 
 
+static inline uint64_t smooth_ts(struct audio_line *line, uint64_t timestamp)
+{
+	if (!line->next_ts_min)
+		return timestamp;
+
+	bool ts_under = (timestamp < line->next_ts_min);
+	uint64_t diff = ts_under ?
+		(line->next_ts_min - timestamp) :
+		(timestamp - line->next_ts_min);
+
+	return (diff < TS_SMOOTHING_THRESHOLD) ? line->next_ts_min : timestamp;
+}
+
 static void audio_line_place_data(struct audio_line *line,
 static void audio_line_place_data(struct audio_line *line,
 		const struct audio_data *data)
 		const struct audio_data *data)
 {
 {
-	size_t pos = ts_diff_bytes(line->audio, data->timestamp,
-			line->base_timestamp);
+	size_t pos;
+	uint64_t timestamp = smooth_ts(line, data->timestamp);
+
+	pos = ts_diff_bytes(line->audio, timestamp, line->base_timestamp);
+	line->next_ts_min =
+		timestamp + conv_frames_to_time(line->audio, data->frames);
 
 
 #ifdef DEBUG_AUDIO
 #ifdef DEBUG_AUDIO
 	blog(LOG_DEBUG, "data->timestamp: %llu, line->base_timestamp: %llu, "
 	blog(LOG_DEBUG, "data->timestamp: %llu, line->base_timestamp: %llu, "
 			"pos: %lu, bytes: %lu, buf size: %lu",
 			"pos: %lu, bytes: %lu, buf size: %lu",
-			data->timestamp, line->base_timestamp, pos,
+			timestamp, line->base_timestamp, pos,
 			data->frames * line->audio->block_size,
 			data->frames * line->audio->block_size,
 			line->buffers[0].size);
 			line->buffers[0].size);
 #endif
 #endif