diff --git a/include/ffcpp/Player.h b/include/ffcpp/Player.h index 2a3348b..ee545d6 100644 --- a/include/ffcpp/Player.h +++ b/include/ffcpp/Player.h @@ -3,6 +3,7 @@ #include "ffcpp/MediaFile.h" #include +#include namespace ffcpp { @@ -15,12 +16,20 @@ namespace ffcpp { int uPitch, int vPitch) = 0; }; + enum class PlayerState { + Stopped, + Playing, + Paused + }; + class Player { private: std::shared_ptr _vSink; std::unique_ptr _curMedia; StreamPtr _aStream; StreamPtr _vStream; + std::thread _decodeThread; + PlayerState _state; public: Player(std::shared_ptr vSink); @@ -28,6 +37,9 @@ namespace ffcpp { void setMedia(std::string path); void play(); + + private: + void decode(); }; } diff --git a/include/ffcpp/TSQueue.h b/include/ffcpp/TSQueue.h index 99656cb..8a34d4c 100644 --- a/include/ffcpp/TSQueue.h +++ b/include/ffcpp/TSQueue.h @@ -13,10 +13,16 @@ namespace ffcpp { private: mutable std::mutex _mutex; - std::condition_variable _cond; + std::condition_variable _readCond; + std::condition_variable _writeCond; std::queue> _queue; + size_t _maxSize; public: + TSQueue(size_t maxSize): _maxSize(maxSize) { + + } + bool empty() const { LockType lock(_mutex); return _queue.empty(); @@ -26,7 +32,44 @@ namespace ffcpp { auto data = std::make_shared(std::move(value)); LockType lock(_mutex); _queue.push(data); - _cond.notify_one(); + _readCond.notify_one(); + } + + void pushOrWait(T value) { + auto data = std::make_shared(std::move(value)); + std::unique_lock lock(_mutex); + if(_queue.size() == _maxSize) { + _writeCond.wait(lock, [this]{ return _queue.size() < _maxSize; }); + } + _queue.push(data); + _readCond.notify_one(); + } + + std::shared_ptr waitAndPop() { + std::unique_lock lock(_mutex); + _readCond.wait(lock, [this]{ return !_queue.empty(); }); + auto res = _queue.front(); + _queue.pop(); + return res; + } + + std::shared_ptr tryPop() { + LockType lock(_mutex); + if(_queue.empty()) + return std::shared_ptr(); + auto res = _queue.front(); + _queue.pop(); + return res; + } + + std::shared_ptr popOrWait() { + std::unique_lock lock(_mutex); + if(_queue.empty()) { + _readCond.wait(lock, [this]{ return !_queue.empty(); }); + } + auto res = _queue.front(); + _queue.pop(); + return res; } }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 451dd61..f37d3ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,9 @@ project(ffcpp) find_package(FFMPEG REQUIRED) -include_directories(${FFMPEG_INCLUDE_DIR}) +# FIXME: FFMPEG_INCLUDE_DIR is incorrect and causes errors +# http://stackoverflow.com/questions/35982639/ctime-std-namespace-conflict +#include_directories(${FFMPEG_INCLUDE_DIR}) link_directories(${FFMPEG_LIBRARY_DIRS}) if(NOT FFMPEG_FOUND) diff --git a/src/Player.cpp b/src/Player.cpp index 6c53bb2..719f4fa 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1,11 +1,17 @@ #include "ffcpp/Player.h" #include "ffcpp/Stream.h" #include "ffcpp/Scaler.h" +#include namespace ffcpp { - Player::Player(std::shared_ptr vSink): _vSink(vSink), _curMedia(nullptr), _aStream(nullptr), _vStream( - nullptr) { + Player::Player(std::shared_ptr vSink): _vSink(vSink), + _curMedia(nullptr), + _aStream(nullptr), + _vStream(nullptr), + _decodeThread(&Player::decode, this), + _state(PlayerState::Stopped) + { init(); } @@ -36,8 +42,13 @@ namespace ffcpp { frame = scaler.scale(frame); AVFrame* f = frame; //_vSink->drawFrame(f->data, f->linesize[0]); - _vSink->drawPlanarYUVFrame(f->data[0], f->data[1], f->data[2], f->linesize[0], f->linesize[1], f->linesize[2]); + _vSink->drawPlanarYUVFrame(f->data[0], f->data[1], f->data[2], + f->linesize[0], f->linesize[1], f->linesize[2]); } } } + + void Player::decode() { + std::cout << "decode function started" << std::endl; + } } \ No newline at end of file