#ifndef CHARGE_VIDEO_BASE_H #define CHARGE_VIDEO_BASE_H #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ChargeVideo { namespace _ffmpeg { extern "C" { #include #include #include #include #include #include #include #include #include #include #include #include } } // namespace _ffmpeg using namespace Corrade; using namespace Magnum; using namespace Math::Literals; // ======================== CLASSES ======================== class Manager { public: static void Advance(); static float DeltaTime; private: static Timeline time; static uint16_t videoIDCounter; static std::unordered_map> videoPlayMethods; static std::vector toUnhook; // Specific for internal controls static uint16_t hookVideo(std::function videoPlay); static void unhookVideo(uint16_t ID); friend class Video; }; class Video { public: // Enums & Flags enum class State { Playing, Finished, Paused, Idle }; enum class Flags : uint32_t { None = 0, Looping = 1 << 0 }; Video(std::string path, ChargeAudio::Engine *audioEngine = nullptr, Flags videoFlags = Flags::None, float bufferSizeInSeconds = 1.0f); ~Video(); // Manual Control void AdvanceToNextFrame(); // Automatic play void Play(); void Pause(); void SwitchLooping(); void Restart(); // Info const double GetDuration(); const double GetPlaybackTime(); const Vector2i GetDimensions(); State GetState(); Flags GetFlags(); // Frame and buffer GL::Texture2D CurrentFrame; // Audio ChargeAudio::SoundContainer Sound; private: // Contextes _ffmpeg::AVFormatContext *ctx; const _ffmpeg::AVCodec *vCodec; const _ffmpeg::AVCodec *aCodec; _ffmpeg::AVCodecContext *vCodecCtx, *aCodecCtx; _ffmpeg::AVStream *videoStream, *audioStream; struct _ffmpeg::SwsContext *swsCtx = NULL; // Visual struct _ffmpeg::SwrContext *swrCtx = NULL; // Audio // State int8_t videoStreamNum = -1, audioStreamNum = -1; State videoState; Flags videoFlags; uint16_t ID = 0; // Frames _ffmpeg::AVFrame *frame = _ffmpeg::av_frame_alloc(), *convertedFrame = _ffmpeg::av_frame_alloc(), *audioFrame = _ffmpeg::av_frame_alloc(), *convertedAudioFrame = _ffmpeg::av_frame_alloc(); _ffmpeg::AVPacket *packet = _ffmpeg::av_packet_alloc(); // Time specific uint32_t currentFrameNumber = 0; double timeBase = 0, clock = 0; // Audio ChargeAudio::Engine *audioEngine; // Audio Channel data _ffmpeg::AVChannelLayout outLayout; _ffmpeg::AVSampleFormat sampleFormat = _ffmpeg::AV_SAMPLE_FMT_FLT; // Image Buffering std::map frameBuffer; uint32_t bufferMaxFrames = 0; // SAR / Sizing uint32_t scaleFactor = 1; Vector2i Dimensions{0, 0}; // Frame handling bool frameSet = false; float bufferLenghtInSeconds; // Methods void continueVideo(); std::pair> loadNextFrame(); inline void frameDebug(_ffmpeg::AVFrame *frame); inline void frameSetScaleSAR(_ffmpeg::AVFrame *frame); inline void frameConvert(); inline void frameFlip(_ffmpeg::AVFrame *frame); inline void restartVideo(); void dumpAndRefillBuffer(); void loadTexture(Containers::Array data); void loadTexture(ImageView2D image); Image2D loadImage(Containers::Array data); void reinitSound(); }; inline Video::Flags operator|(Video::Flags x, Video::Flags y) { return static_cast( static_cast>(x) | static_cast>(y)); } inline Video::Flags operator&(Video::Flags x, Video::Flags y) { return static_cast( static_cast>(x) & static_cast>(y)); } inline Video::Flags operator^(Video::Flags x, Video::Flags y) { return static_cast( static_cast>(x) ^ static_cast>(y)); } } // namespace ChargeVideo #endif