Path: blob/master/modules/theora/video_stream_theora.h
10277 views
/**************************************************************************/1/* video_stream_theora.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/io/file_access.h"33#include "core/io/resource_loader.h"34#include "core/os/thread.h"35#include "scene/resources/video_stream.h"3637#include <theora/theoradec.h>38#include <vorbis/codec.h>3940class ImageTexture;4142class VideoStreamPlaybackTheora : public VideoStreamPlayback {43GDCLASS(VideoStreamPlaybackTheora, VideoStreamPlayback);4445Image::Format format = Image::Format::FORMAT_L8;46Vector<uint8_t> frame_data;47int frames_pending = 0;48Ref<FileAccess> file;49String file_name;50Point2i size;51Rect2i region;5253float *audio_buffer = nullptr;54int audio_buffer_size = 0;55int audio_ptr_start = 0;56int audio_ptr_end = 0;5758int buffer_data();59int queue_page(ogg_page *page);60int read_page(ogg_page *page);61int feed_pages();62double get_page_time(ogg_page *page);63int64_t seek_streams(double p_time, int64_t &video_granulepos, int64_t &audio_granulepos);64void find_streams(th_setup_info *&ts);65void read_headers(th_setup_info *&ts);66void video_write(th_ycbcr_buffer yuv);67double get_time() const;6869bool theora_eos = false;70bool vorbis_eos = false;7172ogg_sync_state oy;73ogg_stream_state vo;74ogg_stream_state to;75th_info ti;76th_comment tc;77th_dec_ctx *td = nullptr;78vorbis_info vi = {};79vorbis_dsp_state vd;80vorbis_block vb;81vorbis_comment vc;82th_pixel_fmt px_fmt;83double frame_duration = 0;84double stream_length = 0;85int64_t stream_data_offset = 0;86int64_t stream_data_size = 0;8788int pp_level_max = 0;89int pp_level = 0;90int pp_inc = 0;9192bool playing = false;93bool paused = false;9495bool dup_frame = false;96bool has_video = false;97bool has_audio = false;98bool video_ready = false;99bool video_done = false;100bool audio_done = false;101102double time = 0;103double next_frame_time = 0;104double current_frame_time = 0;105double delay_compensation = 0;106107Ref<ImageTexture> texture;108109int audio_track = 0;110111protected:112void clear();113114_FORCE_INLINE_ bool send_audio() {115if (audio_ptr_end > 0) {116int mixed = mix_callback(mix_udata, &audio_buffer[audio_ptr_start * vi.channels], audio_ptr_end - audio_ptr_start);117audio_ptr_start += mixed;118if (audio_ptr_start == audio_ptr_end) {119audio_ptr_start = 0;120audio_ptr_end = 0;121} else {122return false;123}124}125return true;126}127128public:129virtual void play() override;130virtual void stop() override;131virtual bool is_playing() const override;132133virtual void set_paused(bool p_paused) override;134virtual bool is_paused() const override;135136virtual double get_length() const override;137138virtual double get_playback_position() const override;139virtual void seek(double p_time) override;140141void set_file(const String &p_file);142143virtual Ref<Texture2D> get_texture() const override;144virtual void update(double p_delta) override;145146virtual int get_channels() const override;147virtual int get_mix_rate() const override;148149virtual void set_audio_track(int p_idx) override;150151VideoStreamPlaybackTheora();152~VideoStreamPlaybackTheora();153};154155class VideoStreamTheora : public VideoStream {156GDCLASS(VideoStreamTheora, VideoStream);157158protected:159static void _bind_methods();160161public:162Ref<VideoStreamPlayback> instantiate_playback() override {163Ref<VideoStreamPlaybackTheora> pb = memnew(VideoStreamPlaybackTheora);164pb->set_audio_track(audio_track);165pb->set_file(file);166return pb;167}168169void set_audio_track(int p_track) override { audio_track = p_track; }170171VideoStreamTheora() { audio_track = 0; }172};173174class ResourceFormatLoaderTheora : public ResourceFormatLoader {175public:176virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;177virtual void get_recognized_extensions(List<String> *p_extensions) const override;178virtual bool handles_type(const String &p_type) const override;179virtual String get_resource_type(const String &p_path) const override;180};181182183