2014-02-10 02:10:30 +01:00
|
|
|
#ifndef VIDEO_STREAM_THEORA_H
|
|
|
|
#define VIDEO_STREAM_THEORA_H
|
|
|
|
|
|
|
|
#ifdef THEORA_ENABLED
|
|
|
|
|
|
|
|
#include "theora/theoradec.h"
|
|
|
|
#include "vorbis/codec.h"
|
|
|
|
#include "os/file_access.h"
|
2015-12-06 03:16:41 +01:00
|
|
|
#include "ring_buffer.h"
|
2014-02-10 02:10:30 +01:00
|
|
|
#include "io/resource_loader.h"
|
|
|
|
#include "scene/resources/video_stream.h"
|
2015-12-06 03:16:41 +01:00
|
|
|
#include "os/thread.h"
|
|
|
|
#include "os/semaphore.h"
|
|
|
|
|
|
|
|
//#define THEORA_USE_THREAD_STREAMING
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
class VideoStreamPlaybackTheora : public VideoStreamPlayback {
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
OBJ_TYPE(VideoStreamPlaybackTheora, VideoStreamPlayback);
|
2014-02-10 02:10:30 +01:00
|
|
|
|
|
|
|
enum {
|
|
|
|
MAX_FRAMES = 4,
|
|
|
|
};
|
|
|
|
|
|
|
|
//Image frames[MAX_FRAMES];
|
|
|
|
Image::Format format;
|
|
|
|
DVector<uint8_t> frame_data;
|
|
|
|
int frames_pending;
|
|
|
|
FileAccess* file;
|
|
|
|
String file_name;
|
|
|
|
int audio_frames_wrote;
|
|
|
|
Point2i size;
|
|
|
|
|
|
|
|
int buffer_data();
|
|
|
|
int queue_page(ogg_page *page);
|
|
|
|
void video_write(void);
|
|
|
|
float get_time() const;
|
|
|
|
|
2016-01-23 21:58:17 +01:00
|
|
|
bool theora_eos;
|
|
|
|
bool vorbis_eos;
|
2015-11-03 13:30:28 +01:00
|
|
|
|
2014-02-10 02:10:30 +01:00
|
|
|
ogg_sync_state oy;
|
|
|
|
ogg_page og;
|
|
|
|
ogg_stream_state vo;
|
|
|
|
ogg_stream_state to;
|
|
|
|
th_info ti;
|
|
|
|
th_comment tc;
|
|
|
|
th_dec_ctx *td;
|
|
|
|
vorbis_info vi;
|
|
|
|
vorbis_dsp_state vd;
|
|
|
|
vorbis_block vb;
|
|
|
|
vorbis_comment vc;
|
|
|
|
th_pixel_fmt px_fmt;
|
|
|
|
double videobuf_time;
|
|
|
|
int pp_inc;
|
|
|
|
|
|
|
|
int theora_p;
|
|
|
|
int vorbis_p;
|
|
|
|
int pp_level_max;
|
|
|
|
int pp_level;
|
|
|
|
int videobuf_ready;
|
|
|
|
|
|
|
|
bool playing;
|
|
|
|
bool buffering;
|
|
|
|
|
|
|
|
double last_update_time;
|
|
|
|
double time;
|
2015-09-26 19:50:42 +02:00
|
|
|
double delay_compensation;
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
Ref<ImageTexture> texture;
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
AudioMixCallback mix_callback;
|
|
|
|
void* mix_udata;
|
2015-12-16 03:39:36 +01:00
|
|
|
bool paused;
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-12-06 03:16:41 +01:00
|
|
|
#ifdef THEORA_USE_THREAD_STREAMING
|
|
|
|
|
|
|
|
enum {
|
|
|
|
RB_SIZE_KB=1024
|
|
|
|
};
|
|
|
|
|
|
|
|
RingBuffer<uint8_t> ring_buffer;
|
|
|
|
Vector<uint8_t> read_buffer;
|
|
|
|
bool thread_eof;
|
|
|
|
Semaphore *thread_sem;
|
|
|
|
Thread *thread;
|
|
|
|
volatile bool thread_exit;
|
|
|
|
|
|
|
|
static void _streaming_thread(void *ud);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int audio_track;
|
2015-10-13 06:17:54 +02:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
protected:
|
2014-02-10 02:10:30 +01:00
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
void clear();
|
|
|
|
|
2014-02-10 02:10:30 +01:00
|
|
|
public:
|
|
|
|
|
|
|
|
virtual void play();
|
|
|
|
virtual void stop();
|
|
|
|
virtual bool is_playing() const;
|
|
|
|
|
|
|
|
virtual void set_paused(bool p_paused);
|
|
|
|
virtual bool is_paused(bool p_paused) const;
|
|
|
|
|
|
|
|
virtual void set_loop(bool p_enable);
|
|
|
|
virtual bool has_loop() const;
|
|
|
|
|
|
|
|
virtual float get_length() const;
|
|
|
|
|
|
|
|
virtual String get_stream_name() const;
|
|
|
|
|
|
|
|
virtual int get_loop_count() const;
|
|
|
|
|
|
|
|
virtual float get_pos() const;
|
|
|
|
virtual void seek_pos(float p_time);
|
|
|
|
|
|
|
|
|
|
|
|
void set_file(const String& p_file);
|
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
virtual Ref<Texture> get_texture();
|
|
|
|
virtual void update(float p_delta);
|
|
|
|
|
|
|
|
virtual void set_mix_callback(AudioMixCallback p_callback,void *p_userdata);
|
|
|
|
virtual int get_channels() const;
|
|
|
|
virtual int get_mix_rate() const;
|
|
|
|
|
|
|
|
virtual void set_audio_track(int p_idx);
|
|
|
|
|
|
|
|
VideoStreamPlaybackTheora();
|
|
|
|
~VideoStreamPlaybackTheora();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VideoStreamTheora : public VideoStream {
|
|
|
|
|
|
|
|
OBJ_TYPE(VideoStreamTheora,VideoStream);
|
|
|
|
|
|
|
|
String file;
|
2015-12-07 00:22:45 +01:00
|
|
|
int audio_track;
|
2015-10-13 06:17:54 +02:00
|
|
|
|
|
|
|
|
2015-09-26 19:50:42 +02:00
|
|
|
public:
|
|
|
|
|
|
|
|
Ref<VideoStreamPlayback> instance_playback() {
|
|
|
|
Ref<VideoStreamPlaybackTheora> pb = memnew( VideoStreamPlaybackTheora );
|
2015-12-07 00:22:45 +01:00
|
|
|
pb->set_audio_track(audio_track);
|
2015-09-26 19:50:42 +02:00
|
|
|
pb->set_file(file);
|
|
|
|
return pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_file(const String& p_file) { file=p_file; }
|
2015-12-07 00:22:45 +01:00
|
|
|
void set_audio_track(int p_track) { audio_track=p_track; }
|
2015-10-13 06:17:54 +02:00
|
|
|
|
|
|
|
VideoStreamTheora() { audio_track=0; }
|
2014-02-10 02:10:30 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class ResourceFormatLoaderVideoStreamTheora : public ResourceFormatLoader {
|
|
|
|
public:
|
2015-08-24 01:15:56 +02:00
|
|
|
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
|
2014-02-10 02:10:30 +01:00
|
|
|
virtual void get_recognized_extensions(List<String> *p_extensions) const;
|
|
|
|
virtual bool handles_type(const String& p_type) const;
|
|
|
|
virtual String get_resource_type(const String &p_path) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|