Skip to content

Commit ffd9f2e

Browse files
committed
feat: implement plugin system
1 parent 43b7be9 commit ffd9f2e

File tree

93 files changed

+1578
-905
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+1578
-905
lines changed

CMakeLists.txt

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,28 +107,11 @@ set(SOURCES
107107
# --- Core ---
108108
src/core/Core.cpp
109109

110-
# --- Inputs ---
110+
# --- Input Runtime ---
111111
src/input/AInput.cpp
112-
# Media
113-
src/input/media/Image.cpp
114-
src/input/media/WebImage.cpp
115-
src/input/media/Video.cpp
116-
# Text
117-
src/input/text/Text.cpp
118-
# Shape
119-
src/input/shape/Circle.cpp
120-
src/input/shape/Rectangle.cpp
121-
src/input/shape/Line.cpp
122-
123-
# --- Fragment Shader ---
124-
src/shader/Grayscale.cpp
125-
src/shader/Opacity.cpp
126-
src/shader/Blur.cpp
127-
src/shader/Gamma.cpp
128-
src/shader/Grain.cpp
129-
src/shader/Brightness.cpp
130-
src/shader/Contrast.cpp
131-
src/shader/Sharpen.cpp
112+
113+
# --- Plugin Runtime ---
114+
src/plugin/PluginRegistry.cpp
132115
)
133116

134117
add_executable(${PROJECT_NAME} ${SOURCES})
@@ -145,6 +128,7 @@ target_link_libraries(${PROJECT_NAME}
145128
argparse::argparse
146129
nlohmann_json::nlohmann_json
147130
${OpenCV_LIBS}
131+
${CMAKE_DL_LIBS}
148132
${FFMPEG_LIBRARIES}
149133
Qt6::Widgets
150134
Qt6::Core

docs/user/user.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,20 @@ go to [qt6](https://www.qt.io/download) and download the latest version of qt6.
4545
cp build/video-code video-code
4646
```
4747
48+
5. **Build plugins (decoupled from main build):**
49+
```sh
50+
./scripts/build_plugins.sh plugins/build
51+
```
52+
4853
### Launch
4954
5055
To launch the project, run:
5156
```sh
52-
./video-code --file path/to/your/script.py
57+
./video-code --file path/to/your/script.py --plugin-dir plugins/build
5358
```
5459
If you want to generate a video directly, use:
5560
```sh
56-
./video-code --file path/to/your/script.py --generate
61+
./video-code --file path/to/your/script.py --generate output.mp4 --plugin-dir plugins/build
5762
5863
```
5964

include/core/Core.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <opencv2/opencv.hpp>
1414

1515
#include "input/IInput.hpp"
16+
#include "plugin/PluginRegistry.hpp"
1617

1718
namespace VC
1819
{
@@ -64,6 +65,7 @@ namespace VC
6465
///< Source & Output file
6566
const std::string _sourceFile;
6667
const std::string _outputFile;
68+
const std::string _pluginDir;
6769

6870
///< Background frame, black with alpha 0
6971
const cv::Mat _bgFrame;
@@ -80,5 +82,8 @@ namespace VC
8082

8183
///< Stack containing the steps of the video
8284
json::array_t _stack{};
85+
86+
///< Runtime plugin registry
87+
PluginRegistry _pluginRegistry{};
8388
};
8489
};

include/input/AInput.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <memory>
1111
#include <nlohmann/json.hpp>
1212
#include <opencv2/core/mat.hpp>
13+
#include <string>
1314
#include <vector>
1415

1516
#include "input/IInput.hpp"
@@ -29,6 +30,8 @@ class AInput : public IInput
2930

3031
void add(nlohmann::basic_json<>& modification) final;
3132

33+
void setShaderFactory(void* context, ShaderFactoryCallback callback) final;
34+
3235
// -
3336

3437
Metadata getMetadata(size_t index);
@@ -41,6 +44,9 @@ class AInput : public IInput
4144

4245
protected:
4346

47+
void* _shaderFactoryContext{nullptr};
48+
ShaderFactoryCallback _shaderFactory{nullptr};
49+
4450
///< Arguments needed to generate the Input's matrix
4551
const json::object_t _baseArgs;
4652

include/input/IInput.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@
77

88
#pragma once
99

10+
#include <functional>
11+
#include <memory>
1012
#include <nlohmann/json.hpp>
1113
#include <opencv2/core/mat.hpp>
14+
#include <string>
15+
16+
#include "shader/IFragmentShader.hpp"
1217

1318
using json = nlohmann::json;
1419

1520
class IInput
1621
{
1722
public:
1823

24+
using ShaderFactoryCallback = std::unique_ptr<IFragmentShader> (*)(void* context, const std::string& name, const json::object_t& args);
25+
1926
IInput() = default;
2027
virtual ~IInput() = default;
2128

@@ -32,4 +39,12 @@ class IInput
3239
virtual void overlay(cv::Mat& bg, size_t t) = 0;
3340

3441
// -
42+
43+
virtual void setShaderFactory(void* context, ShaderFactoryCallback callback) = 0;
44+
45+
// -
46+
47+
virtual size_t maxFrameHint() const { return 0; }
48+
49+
// -
3550
};

include/plugin/PluginAPI.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
** EPITECH PROJECT, 2026
3+
** video-code
4+
** File description:
5+
** Plugin API
6+
*/
7+
8+
#pragma once
9+
10+
#include <memory>
11+
#include <nlohmann/json.hpp>
12+
13+
#include "input/IInput.hpp"
14+
#include "shader/IFragmentShader.hpp"
15+
16+
namespace VC
17+
{
18+
using InputFactoryFunction = std::unique_ptr<IInput> (*)(nlohmann::json::object_t&& args);
19+
using FragmentShaderFactoryFunction = std::unique_ptr<IFragmentShader> (*)(const nlohmann::json::object_t& args);
20+
21+
using RegisterInputFunction = void (*)(void* context, const char* name, InputFactoryFunction factory);
22+
using RegisterFragmentShaderFunction = void (*)(void* context, const char* name, FragmentShaderFactoryFunction factory);
23+
24+
struct PluginRegistrar
25+
{
26+
void* context;
27+
RegisterInputFunction registerInput;
28+
RegisterFragmentShaderFunction registerFragmentShader;
29+
};
30+
}
31+
32+
extern "C" {
33+
using VCRegisterPluginFunction = void (*)(VC::PluginRegistrar* registrar);
34+
}

include/plugin/PluginRegistry.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
** EPITECH PROJECT, 2026
3+
** video-code
4+
** File description:
5+
** Plugin registry
6+
*/
7+
8+
#pragma once
9+
10+
#include <filesystem>
11+
#include <map>
12+
#include <memory>
13+
#include <nlohmann/json.hpp>
14+
#include <string>
15+
#include <vector>
16+
17+
#include "plugin/PluginAPI.hpp"
18+
19+
namespace VC
20+
{
21+
class PluginRegistry
22+
{
23+
public:
24+
25+
void registerInput(const std::string& name, InputFactoryFunction factory);
26+
void registerFragmentShader(const std::string& name, FragmentShaderFactoryFunction factory);
27+
28+
std::unique_ptr<IInput> createInput(const std::string& name, nlohmann::json::object_t&& args) const;
29+
std::unique_ptr<IFragmentShader> createFragmentShader(const std::string& name, const nlohmann::json::object_t& args) const;
30+
31+
void loadPluginDirectories(const std::vector<std::string>& directories);
32+
33+
private:
34+
35+
void loadMetadataFile(const std::filesystem::path& metadataPath);
36+
void loadCppPlugin(const std::filesystem::path& metadataPath, const std::filesystem::path& libraryPath);
37+
38+
std::map<std::string, InputFactoryFunction> _inputFactories{};
39+
std::map<std::string, FragmentShaderFactoryFunction> _shaderFactories{};
40+
std::vector<void*> _libraryHandles{};
41+
};
42+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
cmake_minimum_required(VERSION 3.21)
2+
project(vc-plugin-blur LANGUAGES CXX)
3+
set(CMAKE_CXX_STANDARD 20)
4+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
5+
if(NOT VIDEO_CODE_ROOT)
6+
message(FATAL_ERROR "VIDEO_CODE_ROOT must be provided")
7+
endif()
8+
find_package(OpenCV REQUIRED)
9+
find_package(nlohmann_json CONFIG REQUIRED)
10+
add_library(blur_plugin SHARED blur_plugin.cpp)
11+
target_include_directories(blur_plugin PRIVATE ${VIDEO_CODE_ROOT}/include)
12+
target_link_libraries(blur_plugin PRIVATE ${OpenCV_LIBS} nlohmann_json::nlohmann_json)
13+
set_target_properties(blur_plugin PROPERTIES OUTPUT_NAME "blur_plugin")
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <cmath>
2+
#include <opencv2/opencv.hpp>
3+
4+
#include "plugin/PluginAPI.hpp"
5+
6+
class Blur final : public IFragmentShader
7+
{
8+
public:
9+
explicit Blur(const nlohmann::json::object_t& args)
10+
: _start(args.at("start").get<size_t>())
11+
, _args(args)
12+
{
13+
}
14+
15+
size_t start() const override
16+
{
17+
return _start;
18+
}
19+
20+
void render(cv::Mat& mat, size_t) const override
21+
{
22+
size_t strength = _args.at("strength");
23+
24+
if (strength < 1) {
25+
strength = 1;
26+
}
27+
if (strength % 2 == 0) {
28+
strength++;
29+
}
30+
31+
cv::GaussianBlur(mat, mat, cv::Size(strength, strength), 0);
32+
}
33+
34+
private:
35+
size_t _start;
36+
nlohmann::json::object_t _args;
37+
};
38+
39+
static std::unique_ptr<IFragmentShader> createShader(const nlohmann::json::object_t& args)
40+
{
41+
return std::make_unique<Blur>(args);
42+
}
43+
44+
extern "C" void vc_register_plugin(VC::PluginRegistrar* registrar)
45+
{
46+
registrar->registerFragmentShader(registrar->context, "Blur", createShader);
47+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from videocode.shader.ishader import FragmentShader
2+
from videocode.ty import *
3+
4+
5+
class blur(FragmentShader):
6+
def __init__(self, strength: unumber = 1.0):
7+
self.strength = strength
8+
9+
10+
def register(target):
11+
target["blur"] = blur

0 commit comments

Comments
 (0)