Skip to content

Commit 3f4f704

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

File tree

95 files changed

+1624
-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.

95 files changed

+1624
-905
lines changed

.github/copilot-instructions.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copilot Instructions for Video-Code
2+
3+
## Project context
4+
- `Video-Code` is a hybrid C++ and Python project for programmatic video generation.
5+
- Main C++ entrypoint is `src/Main.cpp` and build output binary is `video-code`.
6+
- Python API lives under `videocode/` and top-level usage examples exist in `video.py` and `test/`.
7+
8+
## Scope and change philosophy
9+
- Prefer minimal, targeted edits that directly satisfy the user request.
10+
- Preserve existing public APIs and naming unless change is explicitly requested.
11+
- Do not refactor unrelated modules while addressing a focused task.
12+
13+
## Build and run workflow
14+
- Prefer existing project commands and CMake flow:
15+
- Configure/build via `make cmake` (uses CMake + Ninja + vcpkg flags).
16+
- Debug build via `make debug`.
17+
- Clean via `make clean` / `make fclean`.
18+
- CI uses Ubuntu, GCC 13, Qt 6.2.4, and CMake configure/build in `build/`.
19+
- If a change impacts runtime behavior, validate by building and (when reasonable) running `./video-code --generate`.
20+
21+
## Testing expectations
22+
- Run the smallest relevant validation first (targeted build/test), then broader checks only if needed.
23+
- C++ tests are under `tests/cpp/`; Python tests/helpers are under `tests/python/`.
24+
- Do not attempt to repair unrelated failing tests; mention them separately if encountered.
25+
26+
## File and directory safety
27+
- Treat generated/artifact paths as non-source unless explicitly requested:
28+
- `build/`, `htmlcov/`, `__pycache__/`, `vcpkg_installed/`, generated videos/images.
29+
- Do not edit CI/CD workflows unless task explicitly asks for pipeline changes.
30+
31+
## Coding conventions
32+
- Follow local style in touched files (indentation, includes/import ordering, naming).
33+
- Avoid adding new dependencies unless necessary; when needed, wire them through existing tooling (`vcpkg.json`, CMake, or Python requirements) consistently.
34+
- Avoid one-letter variable names and avoid inline comments unless they add real value.
35+
36+
## Documentation updates
37+
- When behavior, setup, or developer workflow changes, update relevant docs (`README.md` or `docs/`) in the same change.
38+
39+
## Agent behavior
40+
- Before destructive actions (deletions, large refactors, security-sensitive changes), ask for confirmation.
41+
- Explain assumptions briefly when requirements are ambiguous and choose the simplest valid implementation path.

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"chat.tools.terminal.autoApprove": {
3+
"./video-code": true
4+
}
5+
}

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")

0 commit comments

Comments
 (0)