1 /*************************************************************************/ 2 /* video_stream_gdnative.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 31 #ifndef VIDEO_STREAM_GDNATIVE_H 32 #define VIDEO_STREAM_GDNATIVE_H 33 34 #include "../gdnative.h" 35 #include "core/os/file_access.h" 36 #include "scene/resources/texture.h" 37 #include "scene/resources/video_stream.h" 38 39 struct VideoDecoderGDNative { 40 const godot_videodecoder_interface_gdnative *interface; 41 String plugin_name; 42 Vector<String> supported_extensions; 43 VideoDecoderGDNativeVideoDecoderGDNative44 VideoDecoderGDNative() : 45 interface(NULL), 46 plugin_name("none") {} 47 VideoDecoderGDNativeVideoDecoderGDNative48 VideoDecoderGDNative(const godot_videodecoder_interface_gdnative *p_interface) : 49 interface(p_interface), 50 plugin_name(p_interface->get_plugin_name()) { 51 _get_supported_extensions(); 52 } 53 54 private: _get_supported_extensionsVideoDecoderGDNative55 void _get_supported_extensions() { 56 supported_extensions.clear(); 57 int num_ext; 58 const char **supported_ext = interface->get_supported_extensions(&num_ext); 59 for (int i = 0; i < num_ext; i++) { 60 supported_extensions.push_back(supported_ext[i]); 61 } 62 } 63 }; 64 65 class VideoDecoderServer { 66 private: 67 Vector<VideoDecoderGDNative *> decoders; 68 Map<String, int> extensions; 69 70 static VideoDecoderServer *instance; 71 72 public: get_instance()73 static VideoDecoderServer *get_instance() { 74 return instance; 75 } 76 get_extensions()77 const Map<String, int> &get_extensions() { 78 return extensions; 79 } 80 register_decoder_interface(const godot_videodecoder_interface_gdnative * p_interface)81 void register_decoder_interface(const godot_videodecoder_interface_gdnative *p_interface) { 82 VideoDecoderGDNative *decoder = memnew(VideoDecoderGDNative(p_interface)); 83 int index = decoders.size(); 84 for (int i = 0; i < decoder->supported_extensions.size(); i++) { 85 extensions[decoder->supported_extensions[i]] = index; 86 } 87 decoders.push_back(decoder); 88 } 89 get_decoder(const String & extension)90 VideoDecoderGDNative *get_decoder(const String &extension) { 91 if (extensions.size() == 0 || !extensions.has(extension)) 92 return NULL; 93 return decoders[extensions[extension]]; 94 } 95 VideoDecoderServer()96 VideoDecoderServer() { 97 instance = this; 98 } 99 ~VideoDecoderServer()100 ~VideoDecoderServer() { 101 for (int i = 0; i < decoders.size(); i++) { 102 memdelete(decoders[i]); 103 } 104 decoders.clear(); 105 instance = NULL; 106 } 107 }; 108 109 class VideoStreamPlaybackGDNative : public VideoStreamPlayback { 110 111 GDCLASS(VideoStreamPlaybackGDNative, VideoStreamPlayback); 112 113 Ref<ImageTexture> texture; 114 bool playing; 115 bool paused; 116 117 Vector2 texture_size; 118 119 void *mix_udata; 120 AudioMixCallback mix_callback; 121 122 int num_channels; 123 float time; 124 bool seek_backward; 125 int mix_rate; 126 double delay_compensation; 127 128 float *pcm; 129 int pcm_write_idx; 130 int samples_decoded; 131 132 void cleanup(); 133 void update_texture(); 134 135 protected: 136 String file_name; 137 138 FileAccess *file; 139 140 const godot_videodecoder_interface_gdnative *interface; 141 void *data_struct; 142 143 public: 144 VideoStreamPlaybackGDNative(); 145 ~VideoStreamPlaybackGDNative(); 146 147 void set_interface(const godot_videodecoder_interface_gdnative *p_interface); 148 149 bool open_file(const String &p_file); 150 151 virtual void stop(); 152 virtual void play(); 153 154 virtual bool is_playing() const; 155 156 virtual void set_paused(bool p_paused); 157 virtual bool is_paused() const; 158 159 virtual void set_loop(bool p_enable); 160 virtual bool has_loop() const; 161 162 virtual float get_length() const; 163 164 virtual float get_playback_position() const; 165 virtual void seek(float p_time); 166 167 virtual void set_audio_track(int p_idx); 168 169 //virtual int mix(int16_t* p_buffer,int p_frames)=0; 170 171 virtual Ref<Texture> get_texture() const; 172 virtual void update(float p_delta); 173 174 virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); 175 virtual int get_channels() const; 176 virtual int get_mix_rate() const; 177 }; 178 179 class VideoStreamGDNative : public VideoStream { 180 181 GDCLASS(VideoStreamGDNative, VideoStream); 182 183 String file; 184 int audio_track; 185 186 protected: 187 static void 188 _bind_methods(); 189 190 public: 191 void set_file(const String &p_file); 192 String get_file(); 193 194 virtual void set_audio_track(int p_track); 195 virtual Ref<VideoStreamPlayback> instance_playback(); 196 VideoStreamGDNative()197 VideoStreamGDNative() {} 198 }; 199 200 class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader { 201 public: 202 virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); 203 virtual void get_recognized_extensions(List<String> *p_extensions) const; 204 virtual bool handles_type(const String &p_type) const; 205 virtual String get_resource_type(const String &p_path) const; 206 }; 207 208 #endif 209