소스 검색

VideoStreamPlayer: Fix sync with the scene tree

Bernat Arlandis 2 달 전
부모
커밋
1165021b0c
4개의 변경된 파일18개의 추가작업 그리고 18개의 파일을 삭제
  1. 5 16
      scene/gui/video_stream_player.cpp
  2. 1 1
      scene/gui/video_stream_player.h
  3. 9 1
      servers/audio/audio_rb_resampler.cpp
  4. 3 0
      servers/audio/audio_rb_resampler.h

+ 5 - 16
scene/gui/video_stream_player.cpp

@@ -154,14 +154,10 @@ void VideoStreamPlayer::_notification(int p_notification) {
 				return;
 			}
 
-			double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec());
+			double delta = first_frame ? 0 : get_process_delta_time();
+			first_frame = false;
 
-			double delta = last_audio_time == 0 ? 0 : audio_time - last_audio_time;
-			last_audio_time = audio_time;
-
-			if (delta == 0) {
-				return;
-			}
+			resampler.set_playback_speed(Engine::get_singleton()->get_time_scale());
 
 			playback->update(delta); // playback->is_playing() returns false in the last video frame
 
@@ -195,7 +191,6 @@ void VideoStreamPlayer::_notification(int p_notification) {
 					playback->set_paused(true);
 					set_process_internal(false);
 				}
-				last_audio_time = 0;
 			}
 		} break;
 
@@ -213,7 +208,6 @@ void VideoStreamPlayer::_notification(int p_notification) {
 					playback->set_paused(false);
 					set_process_internal(true);
 				}
-				last_audio_time = 0;
 			}
 		} break;
 	}
@@ -341,10 +335,7 @@ void VideoStreamPlayer::play() {
 	}
 	playback->play();
 	set_process_internal(true);
-	last_audio_time = 0;
-
-	// We update the playback to render the first frame immediately.
-	playback->update(0);
+	first_frame = true;
 
 	if (!can_process()) {
 		_notification(NOTIFICATION_PAUSED);
@@ -362,7 +353,6 @@ void VideoStreamPlayer::stop() {
 	playback->stop();
 	resampler.flush();
 	set_process_internal(false);
-	last_audio_time = 0;
 }
 
 bool VideoStreamPlayer::is_playing() const {
@@ -391,7 +381,6 @@ void VideoStreamPlayer::set_paused(bool p_paused) {
 		playback->set_paused(p_paused);
 		set_process_internal(!p_paused);
 	}
-	last_audio_time = 0;
 }
 
 bool VideoStreamPlayer::is_paused() const {
@@ -469,7 +458,7 @@ void VideoStreamPlayer::set_stream_position(double p_position) {
 	if (playback.is_valid()) {
 		resampler.flush();
 		playback->seek(p_position);
-		last_audio_time = 0;
+		first_frame = true;
 	}
 }
 

+ 1 - 1
scene/gui/video_stream_player.h

@@ -63,9 +63,9 @@ class VideoStreamPlayer : public Control {
 	bool paused_from_tree = false;
 	bool autoplay = false;
 	float volume = 1.0;
-	double last_audio_time = 0.0;
 	bool expand = false;
 	bool loop = false;
+	bool first_frame = false;
 	int buffering_ms = 500;
 	int audio_track = 0;
 	int bus_index = 0;

+ 9 - 1
servers/audio/audio_rb_resampler.cpp

@@ -120,7 +120,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
 		return false;
 	}
 
-	int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate;
+	int32_t increment = (src_mix_rate * MIX_FRAC_LEN * playback_speed) / target_mix_rate;
 	int read_space = get_reader_space();
 	int target_todo = MIN(get_num_of_ready_frames(), p_frames);
 
@@ -228,6 +228,14 @@ void AudioRBResampler::clear() {
 	read_buf = nullptr;
 }
 
+void AudioRBResampler::set_playback_speed(double p_playback_speed) {
+	playback_speed = p_playback_speed;
+}
+
+double AudioRBResampler::get_playback_speed() const {
+	return playback_speed;
+}
+
 AudioRBResampler::AudioRBResampler() {
 	rb = nullptr;
 	offset = 0;

+ 3 - 0
servers/audio/audio_rb_resampler.h

@@ -42,6 +42,7 @@ struct AudioRBResampler {
 	uint32_t channels;
 	uint32_t src_mix_rate;
 	uint32_t target_mix_rate;
+	double playback_speed = 1.0;
 
 	SafeNumeric<int> rb_read_pos;
 	SafeNumeric<int> rb_write_pos;
@@ -176,6 +177,8 @@ public:
 	void clear();
 	bool mix(AudioFrame *p_dest, int p_frames);
 	int get_num_of_ready_frames();
+	void set_playback_speed(double p_playback_speed);
+	double get_playback_speed() const;
 
 	AudioRBResampler();
 	~AudioRBResampler();