#ifndef PROJECT_PLAYER_H #define PROJECT_PLAYER_H #include "ffcpp/MediaFile.h" #include "ffcpp/Scaler.h" #include "TSQueue.h" #include "Resampler.h" #include "readerwriterqueue.h" #include #include #include #include #include #include namespace ffcpp { struct IVideoSink { virtual AVPixelFormat getPixelFormat() const noexcept = 0; virtual void drawFrame(void* pixelsData, int pitch) = 0; virtual void drawPlanarYUVFrame(const void *yPlane, const void *uPlane, const void *vPlane, int yPitch, int uPitch, int vPitch) = 0; }; struct IAudioSource { virtual void fillSampleBuffer(uint8_t *data, int length) = 0; }; struct IAudioSink { virtual void setAudioSource(IAudioSource* audioSrc) = 0; virtual AVSampleFormat getSampleFormat() = 0; virtual int getChannelsCount() = 0; virtual int getSampleRate() = 0; }; enum class PlayerState { Shutdown, Stopped, Playing, Paused }; class Player: private IAudioSource { private: static constexpr size_t AUDIO_BUFFER_LENGTH = 16*1024; private: typedef moodycamel::ReaderWriterQueue FrameQueue; private: std::shared_ptr _vSink; std::shared_ptr _aSink; std::unique_ptr _curMedia; StreamPtr _aStream; StreamPtr _vStream; ScalerPtr _scaler; ResamplerPtr _resampler; PlayerState _state; std::unique_ptr _aSamplesBuffer; int _samplesInBuffer; FILE* _asFile; std::mutex _mutex; std::condition_variable _stateCond; FrameQueue _videoFrames; FrameQueue _audioFrames; std::thread _decodeThread; std::thread _vPlayThread; public: Player(std::shared_ptr vSink, std::shared_ptr aSink); ~Player(); void setMedia(std::string path); void setVideoSize(size_t width, size_t height); void play(); private: void decode(); void displayFrames(); private: void fillSampleBuffer(uint8_t *data, int length) override; }; } #endif //PROJECT_PLAYER_H