From 37b115745e8e930e4fbf6738f711b659c94567ae Mon Sep 17 00:00:00 2001 From: matcool <26722564+matcool@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:25:35 -0300 Subject: [PATCH 1/3] remove submodule --- .gitmodules | 3 --- pl_mpeg | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 pl_mpeg diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 39fcfe5..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "pl_mpeg"] - path = pl_mpeg - url = git@github.com:phoboslab/pl_mpeg.git diff --git a/pl_mpeg b/pl_mpeg deleted file mode 160000 index 73e509a..0000000 --- a/pl_mpeg +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 73e509ac65031602a2f7443c24243d57b082f0bd From d161d46beabc9ae9433fe85110e8edfa19788045 Mon Sep 17 00:00:00 2001 From: matcool <26722564+matcool@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:26:17 -0300 Subject: [PATCH 2/3] update to 2.2074, dont expose pl mpeg header --- CMakeLists.txt | 18 ++++-------- include/VideoPlayer.hpp | 47 ++++++++++++------------------- mod.json | 12 +++++--- src/VideoPlayer.cpp | 61 ++++++++++++++++++++++++----------------- 4 files changed, 67 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38d76e3..707fb89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ -cmake_minimum_required(VERSION 3.3.0) +cmake_minimum_required(VERSION 3.21) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") project(VideoPlayer VERSION 1.0.0) @@ -10,10 +11,7 @@ file(GLOB SOURCES add_library(${PROJECT_NAME} SHARED ${SOURCES}) -target_include_directories(${PROJECT_NAME} PUBLIC - include - pl_mpeg -) +target_include_directories(${PROJECT_NAME} PUBLIC include) if (PROJECT_IS_TOP_LEVEL) target_compile_definitions(${PROJECT_NAME} PRIVATE _VIDEO_PLAYER_EXPORTING) @@ -27,12 +25,8 @@ endif() add_subdirectory($ENV{GEODE_SDK} $ENV{GEODE_SDK}/build) -if(WIN32) - target_link_libraries(${PROJECT_NAME} opengl32) -elseif(APPLE) - target_link_libraries(${PROJECT_NAME} "-framework OpenGL") -elseif(ANDROID) - target_link_libraries(${PROJECT_NAME} GLESv2) -endif() +CPMAddPackage("gh:phoboslab/pl_mpeg#e11f014") + +target_include_directories(${PROJECT_NAME} PUBLIC ${pl_mpeg_SOURCE_DIR}) setup_geode_mod(${PROJECT_NAME}) diff --git a/include/VideoPlayer.hpp b/include/VideoPlayer.hpp index 172bc5d..d5cfc3a 100644 --- a/include/VideoPlayer.hpp +++ b/include/VideoPlayer.hpp @@ -2,12 +2,6 @@ #define _VIDEO_PLAYER_HPP #include -#include - -#pragma warning(disable:4996) -#include "../pl_mpeg/pl_mpeg.h" -#pragma warning(default:4996) - #include #ifdef GEODE_IS_WINDOWS @@ -20,33 +14,14 @@ #define VIDEO_PLAYER_DLL #endif -typedef unsigned int GLuint; - - namespace videoplayer { class VIDEO_PLAYER_DLL VideoPlayer : public cocos2d::CCNodeRGBA { - protected: - bool init(ghc::filesystem::path const& path, bool loop); - - void initAudio(); - static FMOD_RESULT F_CALLBACK audioCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2); - - virtual void update(float delta) override; - virtual void draw() override; - - virtual ~VideoPlayer(); - virtual void onExit() override; - - static void videoCallback(plm_t* mpeg, plm_frame_t* frame, void* user); - static void audioCallback(plm_t* mpeg, plm_samples_t* samples, void* user); - - static FMOD_RESULT F_CALLBACK PCMRead(FMOD_SOUND *sound, void *data, unsigned int length); - - ghc::filesystem::path m_path; - plm_t* m_stream; + struct Impl; + std::unique_ptr m_impl; + friend struct Impl; cocos2d::CCSize m_dimensions; - GLuint m_textures[3]; // y, cb, cr + unsigned int m_textures[3]; // y, cb, cr std::queue m_samples; FMOD::Channel* m_channel; @@ -56,6 +31,18 @@ namespace videoplayer { bool m_loop; bool m_stopped; float m_volume = 1.0f; + + protected: + bool init(std::filesystem::path const& path, bool loop); + + void initAudio(); + + virtual void update(float delta) override; + virtual void draw() override; + + VideoPlayer(); + virtual ~VideoPlayer(); + virtual void onExit() override; public: /** @@ -65,7 +52,7 @@ namespace videoplayer { * @param loop Whether or not playback should loop upon completion. * @return A new initialized video player */ - static VideoPlayer* create(ghc::filesystem::path const& path, bool loop=false); + static VideoPlayer* create(std::filesystem::path const& path, bool loop=false); /** * @brief Sets the content height of the video player, maintaining aspect ratio diff --git a/mod.json b/mod.json index 952e3ee..02c7d12 100644 --- a/mod.json +++ b/mod.json @@ -1,14 +1,18 @@ { - "geode": "1.0.0", - "version": "v1.0.1", + "geode": "4.1.0", + "gd": { + "win": "2.2074", + "mac": "2.2074", + "android": "2.2074" + }, + "version": "v1.1.0", "id": "fig.video_player", "name": "Video Player", "developer": "fig", "description": "Provides an API for playing mpeg (.mpg) videos", "api": { "include": [ - "include/*.hpp", - "pl_mpeg/pl_mpeg.h" + "include/*.hpp" ] } } \ No newline at end of file diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp index 5eae9b4..8a2ffd5 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -1,6 +1,8 @@ // https://github.com/phoboslab/pl_mpeg/blob/master/pl_mpeg_player.c // https://katyscode.wordpress.com/2013/02/28/cutting-your-teeth-on-fmod-part-5-real-time-streaming-of-programmatically-generated-audio/ #define PL_MPEG_IMPLEMENTATION +#define _CRT_SECURE_NO_WARNINGS 1 +#include #include "VideoPlayer.hpp" #include @@ -43,26 +45,38 @@ const char* APP_FRAGMENT_SHADER_YCRCB = APP_SHADER_SOURCE( ); namespace videoplayer { - bool VideoPlayer::init(ghc::filesystem::path const& path, bool loop) { + struct VideoPlayer::Impl { + plm_t* m_stream = nullptr; + + static void videoCallback(plm_t* mpeg, plm_frame_t* frame, void* user); + static void audioCallback(plm_t* mpeg, plm_samples_t* samples, void* user); + static FMOD_RESULT F_CALLBACK audioCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2); + static FMOD_RESULT F_CALLBACK PCMRead(FMOD_SOUND *sound, void *data, unsigned int length); + }; + + VideoPlayer::VideoPlayer() { + m_impl = std::make_unique(); + } + + bool VideoPlayer::init(std::filesystem::path const& path, bool loop) { if (!CCNode::init()) return false; // GENERAL - m_path = path; - m_stream = plm_create_with_filename(m_path.string().c_str()); + auto* stream = m_impl->m_stream = plm_create_with_filename(path.string().c_str()); - if (!m_stream) { - log::error("File at " + m_path.string() + " not found."); + if (!stream) { + log::error("File at {} not found.", path); return false; }; - plm_set_loop(m_stream, loop); + plm_set_loop(stream, loop); m_loop = loop; - plm_set_video_decode_callback(m_stream, VideoPlayer::videoCallback, this); - plm_set_audio_decode_callback(m_stream, VideoPlayer::audioCallback, this); + plm_set_video_decode_callback(stream, Impl::videoCallback, this); + plm_set_audio_decode_callback(stream, Impl::audioCallback, this); // VIDEO - m_dimensions = CCSize(m_stream->video_decoder->mb_width, m_stream->video_decoder->mb_height); + m_dimensions = CCSize(stream->video_decoder->mb_width, stream->video_decoder->mb_height); CCGLProgram* shader = new CCGLProgram; @@ -77,7 +91,7 @@ namespace videoplayer { const char* texture_names[3] = {"texture_y", "texture_cb", "texture_cr"}; - plm_frame_t* frame = &m_stream->video_decoder->frame_current; + plm_frame_t* frame = &stream->video_decoder->frame_current; plm_plane_t planes[3] = {frame->y, frame->cb, frame->cr}; for (int i = 0; i < 3; i++) { @@ -112,33 +126,31 @@ namespace videoplayer { void VideoPlayer::initAudio() { FMODAudioEngine* engine = FMODAudioEngine::sharedEngine(); - int sampleRate = plm_get_samplerate(m_stream); + auto* stream = m_impl->m_stream; + int sampleRate = plm_get_samplerate(stream); FMOD_CREATESOUNDEXINFO soundInfo; memset(&soundInfo, 0, sizeof(FMOD_CREATESOUNDEXINFO)); soundInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); soundInfo.decodebuffersize = PLM_AUDIO_SAMPLES_PER_FRAME * 2; - soundInfo.length = sampleRate * 2 * sizeof(float) * plm_get_duration(m_stream); + soundInfo.length = sampleRate * 2 * sizeof(float) * plm_get_duration(stream); soundInfo.numchannels = 2; soundInfo.defaultfrequency = sampleRate; soundInfo.format = FMOD_SOUND_FORMAT_PCMFLOAT; - soundInfo.pcmreadcallback = &VideoPlayer::PCMRead; + soundInfo.pcmreadcallback = &VideoPlayer::Impl::PCMRead; soundInfo.userdata = this; m_samples = {}; engine->m_system->createStream(nullptr, FMOD_OPENUSER, &soundInfo, &m_sound); - FMOD::ChannelGroup* group; - engine->m_globalChannel->getChannelGroup(&group); - - engine->m_system->playSound(m_sound, group, false, &m_channel); + engine->m_system->playSound(m_sound, engine->m_globalChannel, false, &m_channel); m_channel->setVolume(m_volume); m_channel->setUserData(this); - if (m_loop) m_channel->setCallback(&VideoPlayer::audioCallback); + if (m_loop) m_channel->setCallback(&VideoPlayer::Impl::audioCallback); } - FMOD_RESULT F_CALLBACK VideoPlayer::audioCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2) { + FMOD_RESULT F_CALLBACK VideoPlayer::Impl::audioCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2) { if (callbackType != FMOD_CHANNELCONTROL_CALLBACK_END) return FMOD_OK; VideoPlayer* self; @@ -152,9 +164,8 @@ namespace videoplayer { return FMOD_OK; } - static int times = 0; void VideoPlayer::update(float delta) { - if (!m_paused) plm_decode(m_stream, delta); + if (!m_paused) plm_decode(m_impl->m_stream, delta); } void VideoPlayer::draw() { @@ -191,7 +202,7 @@ namespace videoplayer { onExit(); } - void VideoPlayer::videoCallback(plm_t* mpeg, plm_frame_t* frame, void* user) { + void VideoPlayer::Impl::videoCallback(plm_t* mpeg, plm_frame_t* frame, void* user) { VideoPlayer* self = (VideoPlayer*) user; plm_plane_t* frames[3] = {&frame->y, &frame->cb, &frame->cr}; @@ -209,7 +220,7 @@ namespace videoplayer { } } - void VideoPlayer::audioCallback(plm_t* mpeg, plm_samples_t* samples, void* user) { + void VideoPlayer::Impl::audioCallback(plm_t* mpeg, plm_samples_t* samples, void* user) { VideoPlayer* self = (VideoPlayer*) user; for (unsigned int i = 0; i < samples->count * 2; i++) { @@ -221,7 +232,7 @@ namespace videoplayer { } } - FMOD_RESULT F_CALLBACK VideoPlayer::PCMRead(FMOD_SOUND *sound, void *data, unsigned int length) { + FMOD_RESULT F_CALLBACK VideoPlayer::Impl::PCMRead(FMOD_SOUND *sound, void *data, unsigned int length) { VideoPlayer* self; ((FMOD::Sound*)sound)->getUserData((void**)&self); if (!self) return FMOD_OK; @@ -239,7 +250,7 @@ namespace videoplayer { return FMOD_OK; } - VideoPlayer* VideoPlayer::create(ghc::filesystem::path const& path, bool loop) { + VideoPlayer* VideoPlayer::create(std::filesystem::path const& path, bool loop) { VideoPlayer* ret = new VideoPlayer; if (ret && ret->init(path, loop)) { ret->autorelease(); From 3c69f330bdfc59a31765b3f8469e130d6ec07244 Mon Sep 17 00:00:00 2001 From: matcool <26722564+matcool@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:26:23 -0300 Subject: [PATCH 3/3] add little usage example --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index a4b8b24..48a03ea 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # VideoPlayer Provides an API for playing mpeg (.mpg) videos within the Geode SDK + +## Usage + +```cpp +#include + +auto* node = videoplayer::VideoPlayer::create(Mod::get()->getResourcesDir() / "video.mpg"); +addChild(node); +``` \ No newline at end of file