1 /*************************************************************************/ 2 /* video_stream_theora.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_THEORA_H 32 #define VIDEO_STREAM_THEORA_H 33 34 #include "core/io/resource_loader.h" 35 #include "core/os/file_access.h" 36 #include "core/os/semaphore.h" 37 #include "core/os/thread.h" 38 #include "core/ring_buffer.h" 39 #include "scene/resources/video_stream.h" 40 #include "servers/audio_server.h" 41 42 #include <theora/theoradec.h> 43 #include <vorbis/codec.h> 44 45 //#define THEORA_USE_THREAD_STREAMING 46 47 class VideoStreamPlaybackTheora : public VideoStreamPlayback { 48 49 GDCLASS(VideoStreamPlaybackTheora, VideoStreamPlayback); 50 51 enum { 52 MAX_FRAMES = 4, 53 }; 54 55 //Image frames[MAX_FRAMES]; 56 Image::Format format; 57 PoolVector<uint8_t> frame_data; 58 int frames_pending; 59 FileAccess *file; 60 String file_name; 61 int audio_frames_wrote; 62 Point2i size; 63 64 int buffer_data(); 65 int queue_page(ogg_page *page); 66 void video_write(void); 67 float get_time() const; 68 69 bool theora_eos; 70 bool vorbis_eos; 71 72 ogg_sync_state oy; 73 ogg_page og; 74 ogg_stream_state vo; 75 ogg_stream_state to; 76 th_info ti; 77 th_comment tc; 78 th_dec_ctx *td; 79 vorbis_info vi; 80 vorbis_dsp_state vd; 81 vorbis_block vb; 82 vorbis_comment vc; 83 th_pixel_fmt px_fmt; 84 double videobuf_time; 85 int pp_inc; 86 87 int theora_p; 88 int vorbis_p; 89 int pp_level_max; 90 int pp_level; 91 int videobuf_ready; 92 93 bool playing; 94 bool buffering; 95 96 double last_update_time; 97 double time; 98 double delay_compensation; 99 100 Ref<ImageTexture> texture; 101 102 AudioMixCallback mix_callback; 103 void *mix_udata; 104 bool paused; 105 106 #ifdef THEORA_USE_THREAD_STREAMING 107 108 enum { 109 RB_SIZE_KB = 1024 110 }; 111 112 RingBuffer<uint8_t> ring_buffer; 113 Vector<uint8_t> read_buffer; 114 bool thread_eof; 115 Semaphore *thread_sem; 116 Thread *thread; 117 volatile bool thread_exit; 118 119 static void _streaming_thread(void *ud); 120 121 #endif 122 123 int audio_track; 124 125 protected: 126 void clear(); 127 128 public: 129 virtual void play(); 130 virtual void stop(); 131 virtual bool is_playing() const; 132 133 virtual void set_paused(bool p_paused); 134 virtual bool is_paused() const; 135 136 virtual void set_loop(bool p_enable); 137 virtual bool has_loop() const; 138 139 virtual float get_length() const; 140 141 virtual String get_stream_name() const; 142 143 virtual int get_loop_count() const; 144 145 virtual float get_playback_position() const; 146 virtual void seek(float p_time); 147 148 void set_file(const String &p_file); 149 150 virtual Ref<Texture> get_texture() const; 151 virtual void update(float p_delta); 152 153 virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); 154 virtual int get_channels() const; 155 virtual int get_mix_rate() const; 156 157 virtual void set_audio_track(int p_idx); 158 159 VideoStreamPlaybackTheora(); 160 ~VideoStreamPlaybackTheora(); 161 }; 162 163 class VideoStreamTheora : public VideoStream { 164 165 GDCLASS(VideoStreamTheora, VideoStream); 166 167 String file; 168 int audio_track; 169 170 protected: 171 static void _bind_methods(); 172 173 public: instance_playback()174 Ref<VideoStreamPlayback> instance_playback() { 175 Ref<VideoStreamPlaybackTheora> pb = memnew(VideoStreamPlaybackTheora); 176 pb->set_audio_track(audio_track); 177 pb->set_file(file); 178 return pb; 179 } 180 set_file(const String & p_file)181 void set_file(const String &p_file) { file = p_file; } get_file()182 String get_file() { return file; } set_audio_track(int p_track)183 void set_audio_track(int p_track) { audio_track = p_track; } 184 VideoStreamTheora()185 VideoStreamTheora() { audio_track = 0; } 186 }; 187 188 class ResourceFormatLoaderTheora : public ResourceFormatLoader { 189 public: 190 virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); 191 virtual void get_recognized_extensions(List<String> *p_extensions) const; 192 virtual bool handles_type(const String &p_type) const; 193 virtual String get_resource_type(const String &p_path) const; 194 }; 195 196 #endif 197