VideoStreamPlayer: Fix sync with the scene tree

This commit is contained in:
Bernat Arlandis
2025-05-26 13:55:32 +02:00
parent 6c9765d87e
commit 1165021b0c
4 changed files with 18 additions and 18 deletions

View File

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

View File

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

View File

@ -120,7 +120,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
return false; 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 read_space = get_reader_space();
int target_todo = MIN(get_num_of_ready_frames(), p_frames); int target_todo = MIN(get_num_of_ready_frames(), p_frames);
@ -228,6 +228,14 @@ void AudioRBResampler::clear() {
read_buf = nullptr; 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() { AudioRBResampler::AudioRBResampler() {
rb = nullptr; rb = nullptr;
offset = 0; offset = 0;

View File

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