/* * CVideoHandler.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "../lib/Rect.h" #include "../lib/filesystem/ResourcePath.h" struct SDL_Surface; struct SDL_Texture; enum class EVideoType : ui8 { INTRO = 0, // use entire window: stopOnKey = true, scale = true, overlay = false SPELLBOOK // overlay video: stopOnKey = false, scale = false, overlay = true }; class IVideoPlayer : boost::noncopyable { public: virtual bool open(const VideoPath & name, bool scale = false)=0; //true - succes virtual void close()=0; virtual bool nextFrame()=0; virtual void show(int x, int y, SDL_Surface *dst, bool update = true)=0; virtual void redraw(int x, int y, SDL_Surface *dst, bool update = true)=0; //reblits buffer virtual bool wait()=0; virtual int curFrame() const =0; virtual int frameCount() const =0; }; class IMainVideoPlayer : public IVideoPlayer { public: virtual ~IMainVideoPlayer() = default; virtual void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update = true, std::function restart = nullptr){} virtual bool openAndPlayVideo(const VideoPath & name, int x, int y, EVideoType videoType) { return false; } virtual std::pair, si64> getAudio(const VideoPath & videoToOpen) { return std::make_pair(nullptr, 0); }; virtual Point size() { return Point(0, 0); }; }; class CEmptyVideoPlayer final : public IMainVideoPlayer { public: int curFrame() const override {return -1;}; int frameCount() const override {return -1;}; void redraw( int x, int y, SDL_Surface *dst, bool update = true ) override {}; void show( int x, int y, SDL_Surface *dst, bool update = true ) override {}; bool nextFrame() override {return false;}; void close() override {}; bool wait() override {return false;}; bool open(const VideoPath & name, bool scale = false) override {return false;}; }; #ifndef DISABLE_VIDEO struct AVFormatContext; struct AVCodecContext; struct AVCodec; struct AVFrame; struct AVIOContext; VCMI_LIB_NAMESPACE_BEGIN class CInputStream; VCMI_LIB_NAMESPACE_END class CVideoPlayer final : public IMainVideoPlayer { int stream; // stream index in video AVFormatContext *format; AVCodecContext *codecContext; // codec context for stream const AVCodec *codec; AVFrame *frame; struct SwsContext *sws; AVIOContext * context; VideoPath fname; //name of current video file (empty if idle) // Destination. Either overlay or dest. SDL_Texture *texture; SDL_Surface *dest; Rect destRect; // valid when dest is used Rect pos; // destination on screen /// video playback currnet progress, in seconds double frameTime; bool doLoop; // loop through video bool playVideo(int x, int y, bool stopOnKey, bool overlay); bool open(const VideoPath & fname, bool loop, bool useOverlay = false, bool scale = false); public: CVideoPlayer(); ~CVideoPlayer(); bool init(); bool open(const VideoPath & fname, bool scale = false) override; void close() override; bool nextFrame() override; // display next frame void show(int x, int y, SDL_Surface *dst, bool update = true) override; //blit current frame void redraw(int x, int y, SDL_Surface *dst, bool update = true) override; //reblits buffer void update(int x, int y, SDL_Surface *dst, bool forceRedraw, bool update = true, std::function onVideoRestart = nullptr) override; //moves to next frame if appropriate, and blits it or blits only if redraw parameter is set true // Opens video, calls playVideo, closes video; returns playVideo result (if whole video has been played) bool openAndPlayVideo(const VideoPath & name, int x, int y, EVideoType videoType) override; std::pair, si64> getAudio(const VideoPath & videoToOpen) override; Point size() override; //TODO: bool wait() override {return false;}; int curFrame() const override {return -1;}; int frameCount() const override {return -1;}; // public to allow access from ffmpeg IO functions std::unique_ptr data; std::unique_ptr dataAudio; }; #endif