You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-05 17:15:09 +00:00
Merge pull request #106825 from berarma/video_timing
VideoStreamPlayer: Fix sync with the scene tree
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user