From 7ac9ea75cc37ecf688441f05b6c36ef4ffeb7a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 6 Dec 2021 17:24:45 +0100 Subject: Rename `VideoPlayer` to `VideoStreamPlayer` for consistency It's a player for `VideoStream` resources, just like `AudioStreamPlayer` is a player for `AudioStream` resources. Closes https://github.com/godotengine/godot-proposals/issues/3624. --- SConstruct | 2 +- doc/classes/VideoPlayer.xml | 88 ------- doc/classes/VideoStream.xml | 2 +- doc/classes/VideoStreamPlayer.xml | 88 +++++++ scene/gui/video_player.cpp | 470 ----------------------------------- scene/gui/video_player.h | 126 ---------- scene/gui/video_stream_player.cpp | 470 +++++++++++++++++++++++++++++++++++ scene/gui/video_stream_player.h | 126 ++++++++++ scene/register_scene_types.cpp | 14 +- servers/audio/audio_rb_resampler.cpp | 2 +- 10 files changed, 694 insertions(+), 694 deletions(-) delete mode 100644 doc/classes/VideoPlayer.xml create mode 100644 doc/classes/VideoStreamPlayer.xml delete mode 100644 scene/gui/video_player.cpp delete mode 100644 scene/gui/video_player.h create mode 100644 scene/gui/video_stream_player.cpp create mode 100644 scene/gui/video_stream_player.h diff --git a/SConstruct b/SConstruct index 1922e904d0..9dcc6c554f 100644 --- a/SConstruct +++ b/SConstruct @@ -127,7 +127,7 @@ opts.Add(BoolVariable("production", "Set defaults to build Godot for use in prod opts.Add(BoolVariable("use_lto", "Use link-time optimization", False)) # Components -opts.Add(BoolVariable("deprecated", "Enable deprecated features", True)) +opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True)) opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True)) opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True)) diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml deleted file mode 100644 index c8590988f5..0000000000 --- a/doc/classes/VideoPlayer.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - Control for playing video streams. - - - Control node for playing video streams using [VideoStream] resources. - Supported video formats are [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]) and any format exposed via a GDNative plugin using [VideoStreamGDNative]. - [b]Note:[/b] Due to a bug, VideoPlayer does not support localization remapping yet. - [b]Warning:[/b] On HTML5, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations. - - - - - - - - Returns the video stream's name, or [code]"<No Stream>"[/code] if no video stream is assigned. - - - - - - Returns the current frame as a [Texture2D]. - - - - - - Returns [code]true[/code] if the video is playing. - [b]Note:[/b] The video is still considered playing if paused during playback. - - - - - - Starts the video playback from the beginning. If the video is paused, this will not unpause the video. - - - - - - Stops the video playback and sets the stream position to 0. - [b]Note:[/b] Although the stream position will be set to 0, the first frame of the video stream won't become the current frame. - - - - - - The embedded audio track to play. - - - If [code]true[/code], playback starts when the scene loads. - - - Amount of time in milliseconds to store in buffer while playing. - - - Audio bus to use for sound playback. - - - If [code]true[/code], the video scales to the control size. Otherwise, the control minimum size will be automatically adjusted to match the video stream's dimensions. - - - If [code]true[/code], the video is paused. - - - The assigned video stream. See description for supported formats. - - - The current position of the stream, in seconds. - [b]Note:[/b] Changing this value won't have any effect as seeking is not implemented yet, except in video formats implemented by a GDNative add-on. - - - Audio volume as a linear value. - - - Audio volume in dB. - - - - - - Emitted when playback is finished. - - - - diff --git a/doc/classes/VideoStream.xml b/doc/classes/VideoStream.xml index 39fefa8d95..5978e73ac5 100644 --- a/doc/classes/VideoStream.xml +++ b/doc/classes/VideoStream.xml @@ -4,7 +4,7 @@ Base resource for video streams. - Base resource type for all video streams. Classes that derive from [VideoStream] can all be used as resource types to play back videos in [VideoPlayer]. + Base resource type for all video streams. Classes that derive from [VideoStream] can all be used as resource types to play back videos in [VideoStreamPlayer]. diff --git a/doc/classes/VideoStreamPlayer.xml b/doc/classes/VideoStreamPlayer.xml new file mode 100644 index 0000000000..3aa9a8a295 --- /dev/null +++ b/doc/classes/VideoStreamPlayer.xml @@ -0,0 +1,88 @@ + + + + Control for playing video streams. + + + Control node for playing video streams using [VideoStream] resources. + Supported video formats are [url=https://www.theora.org/]Ogg Theora[/url] ([code].ogv[/code], [VideoStreamTheora]) and any format exposed via a GDNative plugin using [VideoStreamGDNative]. + [b]Note:[/b] Due to a bug, VideoStreamPlayer does not support localization remapping yet. + [b]Warning:[/b] On HTML5, video playback [i]will[/i] perform poorly due to missing architecture-specific assembly optimizations. + + + + + + + + Returns the video stream's name, or [code]"<No Stream>"[/code] if no video stream is assigned. + + + + + + Returns the current frame as a [Texture2D]. + + + + + + Returns [code]true[/code] if the video is playing. + [b]Note:[/b] The video is still considered playing if paused during playback. + + + + + + Starts the video playback from the beginning. If the video is paused, this will not unpause the video. + + + + + + Stops the video playback and sets the stream position to 0. + [b]Note:[/b] Although the stream position will be set to 0, the first frame of the video stream won't become the current frame. + + + + + + The embedded audio track to play. + + + If [code]true[/code], playback starts when the scene loads. + + + Amount of time in milliseconds to store in buffer while playing. + + + Audio bus to use for sound playback. + + + If [code]true[/code], the video scales to the control size. Otherwise, the control minimum size will be automatically adjusted to match the video stream's dimensions. + + + If [code]true[/code], the video is paused. + + + The assigned video stream. See description for supported formats. + + + The current position of the stream, in seconds. + [b]Note:[/b] Changing this value won't have any effect as seeking is not implemented yet, except in video formats implemented by a GDNative add-on. + + + Audio volume as a linear value. + + + Audio volume in dB. + + + + + + Emitted when playback is finished. + + + + diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp deleted file mode 100644 index 55b7f01fd5..0000000000 --- a/scene/gui/video_player.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/*************************************************************************/ -/* video_player.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "video_player.h" - -#include "core/os/os.h" -#include "scene/scene_string_names.h" -#include "servers/audio_server.h" - -int VideoPlayer::sp_get_channel_count() const { - if (playback.is_null()) { - return 0; - } - - return playback->get_channels(); -} - -bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) { - // Check the amount resampler can really handle. - // If it cannot, wait "wait_resampler_phase_limit" times. - // This mechanism contributes to smoother pause/unpause operation. - if (p_frames <= resampler.get_num_of_ready_frames() || - wait_resampler_limit <= wait_resampler) { - wait_resampler = 0; - return resampler.mix(p_buffer, p_frames); - } - wait_resampler++; - return false; -} - -// Called from main thread (e.g. VideoStreamPlaybackTheora::update). -int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { - ERR_FAIL_NULL_V(p_udata, 0); - ERR_FAIL_NULL_V(p_data, 0); - - VideoPlayer *vp = (VideoPlayer *)p_udata; - - int todo = MIN(vp->resampler.get_writer_space(), p_frames); - - float *wb = vp->resampler.get_write_buffer(); - int c = vp->resampler.get_channel_count(); - - for (int i = 0; i < todo * c; i++) { - wb[i] = p_data[i]; - } - vp->resampler.write(todo); - - return todo; -} - -void VideoPlayer::_mix_audios(void *p_self) { - ERR_FAIL_NULL(p_self); - reinterpret_cast(p_self)->_mix_audio(); -} - -// Called from audio thread -void VideoPlayer::_mix_audio() { - if (!stream.is_valid()) { - return; - } - if (!playback.is_valid() || !playback->is_playing() || playback->is_paused()) { - return; - } - - AudioFrame *buffer = mix_buffer.ptrw(); - int buffer_size = mix_buffer.size(); - - // Resample - if (!mix(buffer, buffer_size)) { - return; - } - - AudioFrame vol = AudioFrame(volume, volume); - - int cc = AudioServer::get_singleton()->get_channel_count(); - - if (cc == 1) { - AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); - ERR_FAIL_COND(!target); - - for (int j = 0; j < buffer_size; j++) { - target[j] += buffer[j] * vol; - } - - } else { - AudioFrame *targets[4]; - - for (int k = 0; k < cc; k++) { - targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, k); - ERR_FAIL_COND(!targets[k]); - } - - for (int j = 0; j < buffer_size; j++) { - AudioFrame frame = buffer[j] * vol; - for (int k = 0; k < cc; k++) { - targets[k][j] += frame; - } - } - } -} - -void VideoPlayer::_notification(int p_notification) { - switch (p_notification) { - case NOTIFICATION_ENTER_TREE: { - AudioServer::get_singleton()->add_mix_callback(_mix_audios, this); - - if (stream.is_valid() && autoplay && !Engine::get_singleton()->is_editor_hint()) { - play(); - } - - } break; - - case NOTIFICATION_EXIT_TREE: { - AudioServer::get_singleton()->remove_mix_callback(_mix_audios, this); - } break; - - case NOTIFICATION_INTERNAL_PROCESS: { - bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); - - if (stream.is_null() || paused || playback.is_null() || !playback->is_playing()) { - return; - } - - double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()); - - double delta = last_audio_time == 0 ? 0 : audio_time - last_audio_time; - last_audio_time = audio_time; - - if (delta == 0) { - return; - } - - playback->update(delta); // playback->is_playing() returns false in the last video frame - - if (!playback->is_playing()) { - emit_signal(SceneStringNames::get_singleton()->finished); - } - - } break; - - case NOTIFICATION_DRAW: { - if (texture.is_null()) { - return; - } - if (texture->get_width() == 0) { - return; - } - - Size2 s = expand ? get_size() : texture->get_size(); - draw_texture_rect(texture, Rect2(Point2(), s), false); - - } break; - }; -}; - -Size2 VideoPlayer::get_minimum_size() const { - if (!expand && !texture.is_null()) { - return texture->get_size(); - } else { - return Size2(); - } -} - -void VideoPlayer::set_expand(bool p_expand) { - expand = p_expand; - update(); - update_minimum_size(); -} - -bool VideoPlayer::has_expand() const { - return expand; -} - -void VideoPlayer::set_stream(const Ref &p_stream) { - stop(); - - AudioServer::get_singleton()->lock(); - mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); - stream = p_stream; - if (stream.is_valid()) { - stream->set_audio_track(audio_track); - playback = stream->instance_playback(); - } else { - playback = Ref(); - } - AudioServer::get_singleton()->unlock(); - - if (!playback.is_null()) { - playback->set_loop(loops); - playback->set_paused(paused); - texture = playback->get_texture(); - - const int channels = playback->get_channels(); - - AudioServer::get_singleton()->lock(); - if (channels > 0) { - resampler.setup(channels, playback->get_mix_rate(), AudioServer::get_singleton()->get_mix_rate(), buffering_ms, 0); - } else { - resampler.clear(); - } - AudioServer::get_singleton()->unlock(); - - if (channels > 0) { - playback->set_mix_callback(_audio_mix_callback, this); - } - - } else { - texture.unref(); - AudioServer::get_singleton()->lock(); - resampler.clear(); - AudioServer::get_singleton()->unlock(); - } - - update(); - - if (!expand) { - update_minimum_size(); - } -}; - -Ref VideoPlayer::get_stream() const { - return stream; -}; - -void VideoPlayer::play() { - ERR_FAIL_COND(!is_inside_tree()); - if (playback.is_null()) { - return; - } - playback->stop(); - playback->play(); - set_process_internal(true); - // AudioServer::get_singleton()->stream_set_active(stream_rid,true); - // AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume); - last_audio_time = 0; -}; - -void VideoPlayer::stop() { - if (!is_inside_tree()) { - return; - } - if (playback.is_null()) { - return; - } - - playback->stop(); - // AudioServer::get_singleton()->stream_set_active(stream_rid,false); - resampler.flush(); - set_process_internal(false); - last_audio_time = 0; -}; - -bool VideoPlayer::is_playing() const { - if (playback.is_null()) { - return false; - } - - return playback->is_playing(); -}; - -void VideoPlayer::set_paused(bool p_paused) { - paused = p_paused; - if (playback.is_valid()) { - playback->set_paused(p_paused); - set_process_internal(!p_paused); - }; - last_audio_time = 0; -}; - -bool VideoPlayer::is_paused() const { - return paused; -} - -void VideoPlayer::set_buffering_msec(int p_msec) { - buffering_ms = p_msec; -} - -int VideoPlayer::get_buffering_msec() const { - return buffering_ms; -} - -void VideoPlayer::set_audio_track(int p_track) { - audio_track = p_track; -} - -int VideoPlayer::get_audio_track() const { - return audio_track; -} - -void VideoPlayer::set_volume(float p_vol) { - volume = p_vol; -}; - -float VideoPlayer::get_volume() const { - return volume; -}; - -void VideoPlayer::set_volume_db(float p_db) { - if (p_db < -79) { - set_volume(0); - } else { - set_volume(Math::db2linear(p_db)); - } -}; - -float VideoPlayer::get_volume_db() const { - if (volume == 0) { - return -80; - } else { - return Math::linear2db(volume); - } -}; - -String VideoPlayer::get_stream_name() const { - if (stream.is_null()) { - return ""; - } - return stream->get_name(); -}; - -float VideoPlayer::get_stream_position() const { - if (playback.is_null()) { - return 0; - } - return playback->get_playback_position(); -}; - -void VideoPlayer::set_stream_position(float p_position) { - if (playback.is_valid()) { - playback->seek(p_position); - } -} - -Ref VideoPlayer::get_video_texture() const { - if (playback.is_valid()) { - return playback->get_texture(); - } - - return Ref(); -} - -void VideoPlayer::set_autoplay(bool p_enable) { - autoplay = p_enable; -}; - -bool VideoPlayer::has_autoplay() const { - return autoplay; -}; - -void VideoPlayer::set_bus(const StringName &p_bus) { - //if audio is active, must lock this - AudioServer::get_singleton()->lock(); - bus = p_bus; - AudioServer::get_singleton()->unlock(); -} - -StringName VideoPlayer::get_bus() const { - for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { - if (AudioServer::get_singleton()->get_bus_name(i) == bus) { - return bus; - } - } - return "Master"; -} - -void VideoPlayer::_validate_property(PropertyInfo &p_property) const { - if (p_property.name == "bus") { - String options; - for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { - if (i > 0) { - options += ","; - } - String name = AudioServer::get_singleton()->get_bus_name(i); - options += name; - } - - p_property.hint_string = options; - } -} - -void VideoPlayer::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream); - ClassDB::bind_method(D_METHOD("get_stream"), &VideoPlayer::get_stream); - - ClassDB::bind_method(D_METHOD("play"), &VideoPlayer::play); - ClassDB::bind_method(D_METHOD("stop"), &VideoPlayer::stop); - - ClassDB::bind_method(D_METHOD("is_playing"), &VideoPlayer::is_playing); - - ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoPlayer::set_paused); - ClassDB::bind_method(D_METHOD("is_paused"), &VideoPlayer::is_paused); - - ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoPlayer::set_volume); - ClassDB::bind_method(D_METHOD("get_volume"), &VideoPlayer::get_volume); - - ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoPlayer::set_volume_db); - ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoPlayer::get_volume_db); - - ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoPlayer::set_audio_track); - ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoPlayer::get_audio_track); - - ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoPlayer::get_stream_name); - - ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoPlayer::set_stream_position); - ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoPlayer::get_stream_position); - - ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoPlayer::set_autoplay); - ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoPlayer::has_autoplay); - - ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoPlayer::set_expand); - ClassDB::bind_method(D_METHOD("has_expand"), &VideoPlayer::has_expand); - - ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoPlayer::set_buffering_msec); - ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoPlayer::get_buffering_msec); - - ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoPlayer::set_bus); - ClassDB::bind_method(D_METHOD("get_bus"), &VideoPlayer::get_bus); - - ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoPlayer::get_video_texture); - - ADD_SIGNAL(MethodInfo("finished")); - - ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_track", PROPERTY_HINT_RANGE, "0,128,1"), "set_audio_track", "get_audio_track"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "VideoStream"), "set_stream", "get_stream"); - //ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), "set_loop", "has_loop") ; - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume", PROPERTY_HINT_RANGE, "0,15,0.01,exp", PROPERTY_USAGE_NONE), "set_volume", "get_volume"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "has_autoplay"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_paused", "is_paused"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "buffering_msec", PROPERTY_HINT_RANGE, "10,1000"), "set_buffering_msec", "get_buffering_msec"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stream_position", PROPERTY_HINT_RANGE, "0,1280000,0.1", PROPERTY_USAGE_NONE), "set_stream_position", "get_stream_position"); - - ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); -} - -VideoPlayer::VideoPlayer() {} - -VideoPlayer::~VideoPlayer() { - // if (stream_rid.is_valid()) - // AudioServer::get_singleton()->free(stream_rid); - resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes -}; diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h deleted file mode 100644 index 0edad296a1..0000000000 --- a/scene/gui/video_player.h +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************/ -/* video_player.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef VIDEO_PLAYER_H -#define VIDEO_PLAYER_H - -#include "scene/gui/control.h" -#include "scene/resources/video_stream.h" -#include "servers/audio/audio_rb_resampler.h" -#include "servers/audio_server.h" - -class VideoPlayer : public Control { - GDCLASS(VideoPlayer, Control); - - struct Output { - AudioFrame vol; - int bus_index = 0; - Viewport *viewport = nullptr; //pointer only used for reference to previous mix - }; - Ref playback; - Ref stream; - - int sp_get_channel_count() const; - bool mix(AudioFrame *p_buffer, int p_frames); - - RID stream_rid; - - Ref texture; - - AudioRBResampler resampler; - Vector mix_buffer; - int wait_resampler = 0; - int wait_resampler_limit = 2; - - bool paused = false; - bool autoplay = false; - float volume = 1.0; - double last_audio_time = 0.0; - bool expand = true; - bool loops = false; - int buffering_ms = 500; - int audio_track = 0; - int bus_index = 0; - - StringName bus; - - void _mix_audio(); - static int _audio_mix_callback(void *p_udata, const float *p_data, int p_frames); - static void _mix_audios(void *p_self); - -protected: - static void _bind_methods(); - void _notification(int p_notification); - void _validate_property(PropertyInfo &p_property) const override; - -public: - Size2 get_minimum_size() const override; - void set_expand(bool p_expand); - bool has_expand() const; - - Ref get_video_texture() const; - - void set_stream(const Ref &p_stream); - Ref get_stream() const; - - void play(); - void stop(); - bool is_playing() const; - - void set_paused(bool p_paused); - bool is_paused() const; - - void set_volume(float p_vol); - float get_volume() const; - - void set_volume_db(float p_db); - float get_volume_db() const; - - String get_stream_name() const; - float get_stream_position() const; - void set_stream_position(float p_position); - - void set_autoplay(bool p_enable); - bool has_autoplay() const; - - void set_audio_track(int p_track); - int get_audio_track() const; - - void set_buffering_msec(int p_msec); - int get_buffering_msec() const; - - void set_bus(const StringName &p_bus); - StringName get_bus() const; - - VideoPlayer(); - ~VideoPlayer(); -}; - -#endif // VIDEO_PLAYER_H diff --git a/scene/gui/video_stream_player.cpp b/scene/gui/video_stream_player.cpp new file mode 100644 index 0000000000..a11d56a2ed --- /dev/null +++ b/scene/gui/video_stream_player.cpp @@ -0,0 +1,470 @@ +/*************************************************************************/ +/* video_stream_player.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "video_stream_player.h" + +#include "core/os/os.h" +#include "scene/scene_string_names.h" +#include "servers/audio_server.h" + +int VideoStreamPlayer::sp_get_channel_count() const { + if (playback.is_null()) { + return 0; + } + + return playback->get_channels(); +} + +bool VideoStreamPlayer::mix(AudioFrame *p_buffer, int p_frames) { + // Check the amount resampler can really handle. + // If it cannot, wait "wait_resampler_phase_limit" times. + // This mechanism contributes to smoother pause/unpause operation. + if (p_frames <= resampler.get_num_of_ready_frames() || + wait_resampler_limit <= wait_resampler) { + wait_resampler = 0; + return resampler.mix(p_buffer, p_frames); + } + wait_resampler++; + return false; +} + +// Called from main thread (e.g. VideoStreamPlaybackTheora::update). +int VideoStreamPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) { + ERR_FAIL_NULL_V(p_udata, 0); + ERR_FAIL_NULL_V(p_data, 0); + + VideoStreamPlayer *vp = (VideoStreamPlayer *)p_udata; + + int todo = MIN(vp->resampler.get_writer_space(), p_frames); + + float *wb = vp->resampler.get_write_buffer(); + int c = vp->resampler.get_channel_count(); + + for (int i = 0; i < todo * c; i++) { + wb[i] = p_data[i]; + } + vp->resampler.write(todo); + + return todo; +} + +void VideoStreamPlayer::_mix_audios(void *p_self) { + ERR_FAIL_NULL(p_self); + reinterpret_cast(p_self)->_mix_audio(); +} + +// Called from audio thread +void VideoStreamPlayer::_mix_audio() { + if (!stream.is_valid()) { + return; + } + if (!playback.is_valid() || !playback->is_playing() || playback->is_paused()) { + return; + } + + AudioFrame *buffer = mix_buffer.ptrw(); + int buffer_size = mix_buffer.size(); + + // Resample + if (!mix(buffer, buffer_size)) { + return; + } + + AudioFrame vol = AudioFrame(volume, volume); + + int cc = AudioServer::get_singleton()->get_channel_count(); + + if (cc == 1) { + AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); + ERR_FAIL_COND(!target); + + for (int j = 0; j < buffer_size; j++) { + target[j] += buffer[j] * vol; + } + + } else { + AudioFrame *targets[4]; + + for (int k = 0; k < cc; k++) { + targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, k); + ERR_FAIL_COND(!targets[k]); + } + + for (int j = 0; j < buffer_size; j++) { + AudioFrame frame = buffer[j] * vol; + for (int k = 0; k < cc; k++) { + targets[k][j] += frame; + } + } + } +} + +void VideoStreamPlayer::_notification(int p_notification) { + switch (p_notification) { + case NOTIFICATION_ENTER_TREE: { + AudioServer::get_singleton()->add_mix_callback(_mix_audios, this); + + if (stream.is_valid() && autoplay && !Engine::get_singleton()->is_editor_hint()) { + play(); + } + + } break; + + case NOTIFICATION_EXIT_TREE: { + AudioServer::get_singleton()->remove_mix_callback(_mix_audios, this); + } break; + + case NOTIFICATION_INTERNAL_PROCESS: { + bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus); + + if (stream.is_null() || paused || playback.is_null() || !playback->is_playing()) { + return; + } + + double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()); + + double delta = last_audio_time == 0 ? 0 : audio_time - last_audio_time; + last_audio_time = audio_time; + + if (delta == 0) { + return; + } + + playback->update(delta); // playback->is_playing() returns false in the last video frame + + if (!playback->is_playing()) { + emit_signal(SceneStringNames::get_singleton()->finished); + } + + } break; + + case NOTIFICATION_DRAW: { + if (texture.is_null()) { + return; + } + if (texture->get_width() == 0) { + return; + } + + Size2 s = expand ? get_size() : texture->get_size(); + draw_texture_rect(texture, Rect2(Point2(), s), false); + + } break; + }; +}; + +Size2 VideoStreamPlayer::get_minimum_size() const { + if (!expand && !texture.is_null()) { + return texture->get_size(); + } else { + return Size2(); + } +} + +void VideoStreamPlayer::set_expand(bool p_expand) { + expand = p_expand; + update(); + update_minimum_size(); +} + +bool VideoStreamPlayer::has_expand() const { + return expand; +} + +void VideoStreamPlayer::set_stream(const Ref &p_stream) { + stop(); + + AudioServer::get_singleton()->lock(); + mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); + stream = p_stream; + if (stream.is_valid()) { + stream->set_audio_track(audio_track); + playback = stream->instance_playback(); + } else { + playback = Ref(); + } + AudioServer::get_singleton()->unlock(); + + if (!playback.is_null()) { + playback->set_loop(loops); + playback->set_paused(paused); + texture = playback->get_texture(); + + const int channels = playback->get_channels(); + + AudioServer::get_singleton()->lock(); + if (channels > 0) { + resampler.setup(channels, playback->get_mix_rate(), AudioServer::get_singleton()->get_mix_rate(), buffering_ms, 0); + } else { + resampler.clear(); + } + AudioServer::get_singleton()->unlock(); + + if (channels > 0) { + playback->set_mix_callback(_audio_mix_callback, this); + } + + } else { + texture.unref(); + AudioServer::get_singleton()->lock(); + resampler.clear(); + AudioServer::get_singleton()->unlock(); + } + + update(); + + if (!expand) { + update_minimum_size(); + } +}; + +Ref VideoStreamPlayer::get_stream() const { + return stream; +}; + +void VideoStreamPlayer::play() { + ERR_FAIL_COND(!is_inside_tree()); + if (playback.is_null()) { + return; + } + playback->stop(); + playback->play(); + set_process_internal(true); + // AudioServer::get_singleton()->stream_set_active(stream_rid,true); + // AudioServer::get_singleton()->stream_set_volume_scale(stream_rid,volume); + last_audio_time = 0; +}; + +void VideoStreamPlayer::stop() { + if (!is_inside_tree()) { + return; + } + if (playback.is_null()) { + return; + } + + playback->stop(); + // AudioServer::get_singleton()->stream_set_active(stream_rid,false); + resampler.flush(); + set_process_internal(false); + last_audio_time = 0; +}; + +bool VideoStreamPlayer::is_playing() const { + if (playback.is_null()) { + return false; + } + + return playback->is_playing(); +}; + +void VideoStreamPlayer::set_paused(bool p_paused) { + paused = p_paused; + if (playback.is_valid()) { + playback->set_paused(p_paused); + set_process_internal(!p_paused); + }; + last_audio_time = 0; +}; + +bool VideoStreamPlayer::is_paused() const { + return paused; +} + +void VideoStreamPlayer::set_buffering_msec(int p_msec) { + buffering_ms = p_msec; +} + +int VideoStreamPlayer::get_buffering_msec() const { + return buffering_ms; +} + +void VideoStreamPlayer::set_audio_track(int p_track) { + audio_track = p_track; +} + +int VideoStreamPlayer::get_audio_track() const { + return audio_track; +} + +void VideoStreamPlayer::set_volume(float p_vol) { + volume = p_vol; +}; + +float VideoStreamPlayer::get_volume() const { + return volume; +}; + +void VideoStreamPlayer::set_volume_db(float p_db) { + if (p_db < -79) { + set_volume(0); + } else { + set_volume(Math::db2linear(p_db)); + } +}; + +float VideoStreamPlayer::get_volume_db() const { + if (volume == 0) { + return -80; + } else { + return Math::linear2db(volume); + } +}; + +String VideoStreamPlayer::get_stream_name() const { + if (stream.is_null()) { + return ""; + } + return stream->get_name(); +}; + +float VideoStreamPlayer::get_stream_position() const { + if (playback.is_null()) { + return 0; + } + return playback->get_playback_position(); +}; + +void VideoStreamPlayer::set_stream_position(float p_position) { + if (playback.is_valid()) { + playback->seek(p_position); + } +} + +Ref VideoStreamPlayer::get_video_texture() const { + if (playback.is_valid()) { + return playback->get_texture(); + } + + return Ref(); +} + +void VideoStreamPlayer::set_autoplay(bool p_enable) { + autoplay = p_enable; +}; + +bool VideoStreamPlayer::has_autoplay() const { + return autoplay; +}; + +void VideoStreamPlayer::set_bus(const StringName &p_bus) { + //if audio is active, must lock this + AudioServer::get_singleton()->lock(); + bus = p_bus; + AudioServer::get_singleton()->unlock(); +} + +StringName VideoStreamPlayer::get_bus() const { + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (AudioServer::get_singleton()->get_bus_name(i) == bus) { + return bus; + } + } + return "Master"; +} + +void VideoStreamPlayer::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "bus") { + String options; + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (i > 0) { + options += ","; + } + String name = AudioServer::get_singleton()->get_bus_name(i); + options += name; + } + + p_property.hint_string = options; + } +} + +void VideoStreamPlayer::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoStreamPlayer::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &VideoStreamPlayer::get_stream); + + ClassDB::bind_method(D_METHOD("play"), &VideoStreamPlayer::play); + ClassDB::bind_method(D_METHOD("stop"), &VideoStreamPlayer::stop); + + ClassDB::bind_method(D_METHOD("is_playing"), &VideoStreamPlayer::is_playing); + + ClassDB::bind_method(D_METHOD("set_paused", "paused"), &VideoStreamPlayer::set_paused); + ClassDB::bind_method(D_METHOD("is_paused"), &VideoStreamPlayer::is_paused); + + ClassDB::bind_method(D_METHOD("set_volume", "volume"), &VideoStreamPlayer::set_volume); + ClassDB::bind_method(D_METHOD("get_volume"), &VideoStreamPlayer::get_volume); + + ClassDB::bind_method(D_METHOD("set_volume_db", "db"), &VideoStreamPlayer::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &VideoStreamPlayer::get_volume_db); + + ClassDB::bind_method(D_METHOD("set_audio_track", "track"), &VideoStreamPlayer::set_audio_track); + ClassDB::bind_method(D_METHOD("get_audio_track"), &VideoStreamPlayer::get_audio_track); + + ClassDB::bind_method(D_METHOD("get_stream_name"), &VideoStreamPlayer::get_stream_name); + + ClassDB::bind_method(D_METHOD("set_stream_position", "position"), &VideoStreamPlayer::set_stream_position); + ClassDB::bind_method(D_METHOD("get_stream_position"), &VideoStreamPlayer::get_stream_position); + + ClassDB::bind_method(D_METHOD("set_autoplay", "enabled"), &VideoStreamPlayer::set_autoplay); + ClassDB::bind_method(D_METHOD("has_autoplay"), &VideoStreamPlayer::has_autoplay); + + ClassDB::bind_method(D_METHOD("set_expand", "enable"), &VideoStreamPlayer::set_expand); + ClassDB::bind_method(D_METHOD("has_expand"), &VideoStreamPlayer::has_expand); + + ClassDB::bind_method(D_METHOD("set_buffering_msec", "msec"), &VideoStreamPlayer::set_buffering_msec); + ClassDB::bind_method(D_METHOD("get_buffering_msec"), &VideoStreamPlayer::get_buffering_msec); + + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &VideoStreamPlayer::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &VideoStreamPlayer::get_bus); + + ClassDB::bind_method(D_METHOD("get_video_texture"), &VideoStreamPlayer::get_video_texture); + + ADD_SIGNAL(MethodInfo("finished")); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "audio_track", PROPERTY_HINT_RANGE, "0,128,1"), "set_audio_track", "get_audio_track"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "VideoStream"), "set_stream", "get_stream"); + //ADD_PROPERTY( PropertyInfo(Variant::BOOL, "stream/loop"), "set_loop", "has_loop") ; + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume", PROPERTY_HINT_RANGE, "0,15,0.01,exp", PROPERTY_USAGE_NONE), "set_volume", "get_volume"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "has_autoplay"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "paused"), "set_paused", "is_paused"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "buffering_msec", PROPERTY_HINT_RANGE, "10,1000"), "set_buffering_msec", "get_buffering_msec"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "stream_position", PROPERTY_HINT_RANGE, "0,1280000,0.1", PROPERTY_USAGE_NONE), "set_stream_position", "get_stream_position"); + + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); +} + +VideoStreamPlayer::VideoStreamPlayer() {} + +VideoStreamPlayer::~VideoStreamPlayer() { + // if (stream_rid.is_valid()) + // AudioServer::get_singleton()->free(stream_rid); + resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes +}; diff --git a/scene/gui/video_stream_player.h b/scene/gui/video_stream_player.h new file mode 100644 index 0000000000..ad4a3dd9e9 --- /dev/null +++ b/scene/gui/video_stream_player.h @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* video_stream_player.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VIDEO_STREAM_PLAYER_H +#define VIDEO_STREAM_PLAYER_H + +#include "scene/gui/control.h" +#include "scene/resources/video_stream.h" +#include "servers/audio/audio_rb_resampler.h" +#include "servers/audio_server.h" + +class VideoStreamPlayer : public Control { + GDCLASS(VideoStreamPlayer, Control); + + struct Output { + AudioFrame vol; + int bus_index = 0; + Viewport *viewport = nullptr; //pointer only used for reference to previous mix + }; + Ref playback; + Ref stream; + + int sp_get_channel_count() const; + bool mix(AudioFrame *p_buffer, int p_frames); + + RID stream_rid; + + Ref texture; + + AudioRBResampler resampler; + Vector mix_buffer; + int wait_resampler = 0; + int wait_resampler_limit = 2; + + bool paused = false; + bool autoplay = false; + float volume = 1.0; + double last_audio_time = 0.0; + bool expand = true; + bool loops = false; + int buffering_ms = 500; + int audio_track = 0; + int bus_index = 0; + + StringName bus; + + void _mix_audio(); + static int _audio_mix_callback(void *p_udata, const float *p_data, int p_frames); + static void _mix_audios(void *p_self); + +protected: + static void _bind_methods(); + void _notification(int p_notification); + void _validate_property(PropertyInfo &p_property) const override; + +public: + Size2 get_minimum_size() const override; + void set_expand(bool p_expand); + bool has_expand() const; + + Ref get_video_texture() const; + + void set_stream(const Ref &p_stream); + Ref get_stream() const; + + void play(); + void stop(); + bool is_playing() const; + + void set_paused(bool p_paused); + bool is_paused() const; + + void set_volume(float p_vol); + float get_volume() const; + + void set_volume_db(float p_db); + float get_volume_db() const; + + String get_stream_name() const; + float get_stream_position() const; + void set_stream_position(float p_position); + + void set_autoplay(bool p_enable); + bool has_autoplay() const; + + void set_audio_track(int p_track); + int get_audio_track() const; + + void set_buffering_msec(int p_msec); + int get_buffering_msec() const; + + void set_bus(const StringName &p_bus); + StringName get_bus() const; + + VideoStreamPlayer(); + ~VideoStreamPlayer(); +}; + +#endif // VIDEO_STREAM_PLAYER_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 664a67931a..b8442e7f70 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -123,7 +123,7 @@ #include "scene/gui/texture_progress_bar.h" #include "scene/gui/texture_rect.h" #include "scene/gui/tree.h" -#include "scene/gui/video_player.h" +#include "scene/gui/video_stream_player.h" #include "scene/main/canvas_item.h" #include "scene/main/canvas_layer.h" #include "scene/main/http_request.h" @@ -360,7 +360,7 @@ void register_scene_types() { GDREGISTER_CLASS(ItemList); GDREGISTER_CLASS(LineEdit); - GDREGISTER_CLASS(VideoPlayer); + GDREGISTER_CLASS(VideoStreamPlayer); #ifndef ADVANCED_GUI_DISABLED GDREGISTER_CLASS(FileDialog); @@ -931,6 +931,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("KinematicBody2D", "CharacterBody2D"); ClassDB::add_compatibility_class("KinematicCollision", "KinematicCollision3D"); ClassDB::add_compatibility_class("Light", "Light3D"); + ClassDB::add_compatibility_class("Light2D", "PointLight2D"); ClassDB::add_compatibility_class("LineShape2D", "WorldBoundaryShape2D"); ClassDB::add_compatibility_class("Listener", "AudioListener3D"); ClassDB::add_compatibility_class("MeshInstance", "MeshInstance3D"); @@ -983,13 +984,17 @@ void register_scene_types() { ClassDB::add_compatibility_class("SpringArm", "SpringArm3D"); ClassDB::add_compatibility_class("Sprite", "Sprite2D"); ClassDB::add_compatibility_class("StaticBody", "StaticBody3D"); + ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); ClassDB::add_compatibility_class("TextureProgress", "TextureProgressBar"); ClassDB::add_compatibility_class("VehicleBody", "VehicleBody3D"); ClassDB::add_compatibility_class("VehicleWheel", "VehicleWheel3D"); + ClassDB::add_compatibility_class("VideoPlayer", "VideoStreamPlayer"); ClassDB::add_compatibility_class("ViewportContainer", "SubViewportContainer"); ClassDB::add_compatibility_class("Viewport", "SubViewport"); ClassDB::add_compatibility_class("VisibilityEnabler", "VisibleOnScreenEnabler3D"); ClassDB::add_compatibility_class("VisibilityNotifier", "VisibleOnScreenNotifier3D"); + ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); + ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); ClassDB::add_compatibility_class("VisualServer", "RenderingServer"); ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); @@ -1007,11 +1012,6 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch"); ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp"); ClassDB::add_compatibility_class("World", "World3D"); - ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D"); - ClassDB::add_compatibility_class("Light2D", "PointLight2D"); - ClassDB::add_compatibility_class("VisibilityNotifier2D", "VisibleOnScreenNotifier2D"); - ClassDB::add_compatibility_class("VisibilityNotifier3D", "VisibleOnScreenNotifier3D"); - #endif /* DISABLE_DEPRECATED */ OS::get_singleton()->yield(); // may take time to init diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index d9c442facf..b37965a988 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -43,7 +43,7 @@ int AudioRBResampler::get_channel_count() const { // Linear interpolation based sample rate conversion (low quality) // Note that AudioStreamPlaybackResampled::mix has better algorithm, -// but it wasn't obvious to integrate that with VideoPlayer +// but it wasn't obvious to integrate that with VideoStreamPlayer template uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) { uint32_t read = offset & MIX_FRAC_MASK; -- cgit v1.2.3