phaneron_plugin/
traits.rs

1pub use crate::{
2    audio::{AudioChannelLayout, AudioFormat},
3    colour::*,
4    graph::{AudioInputId, AudioOutputId, VideoInputId, VideoOutputId},
5    video::{InterlaceMode, VideoFormat},
6    AudioFrameWithId, VideoFrameWithId,
7};
8use abi_stable::{
9    sabi_trait,
10    std_types::{RHashMap, ROption, RResult, RSlice, RStr, RString, RVec},
11    StableAbi,
12};
13
14#[sabi_trait]
15pub trait PhaneronPlugin: Send + Sync {
16    fn get_available_node_types(&self) -> RVec<PluginNodeDescription>;
17    fn create_node(
18        &self,
19        description: CreateNodeDescription,
20    ) -> RResult<crate::types::NodeHandle, RString>;
21    fn destroy_node(&self, node_id: RString) -> RResult<(), RString>;
22}
23
24/// Provides a description of an available node type provided by a plugin.
25#[repr(C)]
26#[derive(StableAbi)]
27pub struct PluginNodeDescription {
28    /// The Id that should be passed to `create_node` in order to create a node of this type
29    pub id: RString,
30    /// Human-readable name of the node
31    pub name: RString,
32}
33
34/// Passed to a plugin in order to request the creation of a node.
35#[repr(C)]
36#[derive(StableAbi)]
37pub struct CreateNodeDescription {
38    /// Id the node that will be used to refer to the node for the entirety of its lifespan.
39    pub node_id: RString,
40    /// Type of node that is being requested for creation (provided by the plugin).
41    pub node_type: RString,
42}
43
44/// A handle to a node that can be initialized later.
45/// Serves as a reservation of the node and associated resources.
46#[sabi_trait]
47pub trait NodeHandle: Send + Sync {
48    fn initialize(
49        &self,
50        context: crate::types::NodeContext,
51        configuration: ROption<RString>,
52    ) -> crate::types::Node;
53}
54
55/// An initialized node.
56#[sabi_trait]
57pub trait Node: Send + Sync {
58    /// Apply the given state, return true if the state has been successfully applied
59    fn apply_state(&self, state: RString) -> bool;
60    /// Called when the node should produce a frame.
61    fn process_frame(
62        &self,
63        frame_context: crate::types::ProcessFrameContext,
64        video_frames: RHashMap<VideoInputId, VideoFrameWithId>,
65        audio_frames: RHashMap<AudioInputId, AudioFrameWithId>,
66        black_frame: VideoFrameWithId,
67        silence_frame: AudioFrameWithId,
68    );
69}
70
71/// Context provided to nodes when they are initialized.
72#[sabi_trait]
73pub trait NodeContext: Send + Sync {
74    /// Add an audio input to the node.
75    fn add_audio_input(&self) -> AudioInputId;
76    /// Add a video input to the node.
77    fn add_video_input(&self) -> VideoInputId;
78    /// Add an audio output to the node.
79    fn add_audio_output(&self) -> crate::types::AudioOutput;
80    /// Add a video output to the node.
81    fn add_video_output(&self) -> crate::types::VideoOutput;
82    /// Create a [`ToRGBA`] that can be used to load video frames onto the GPU.
83    fn create_to_rgba(
84        &self,
85        video_format: &VideoFormat,
86        colour_space: &ColourSpec,
87        width: usize,
88        height: usize,
89    ) -> crate::types::ToRGBA;
90    /// Create a ['FromRGBA`] that can be used to consume video frames from the GPU.
91    fn create_from_rgba(
92        &self,
93        video_format: &VideoFormat,
94        colour_space: &ColourSpec,
95        width: usize,
96        height: usize,
97        interlace: InterlaceMode,
98    ) -> crate::types::FromRGBA;
99    /// Create a [`ToAudioF32`] that can be used to load audio in 32 bit floating-point format.
100    fn create_to_audio_f32(
101        &self,
102        audio_format: AudioFormat,
103        channel_layout: AudioChannelLayout,
104    ) -> crate::types::ToAudioF32;
105    /// Create a [`FromAudioF32`] that can be used to consume 32 bit floating-point audio in other formats.
106    fn create_from_audio_f32(
107        &self,
108        audio_format: AudioFormat,
109        channel_layout: AudioChannelLayout,
110    ) -> crate::types::FromAudioF32;
111    /// Create a shader from a source string.
112    /// * `kernel` - Shader code.
113    /// * `program_name` - Name of the kernel function.
114    fn create_process_shader(
115        &self,
116        kernel: RStr<'_>,
117        program_name: RStr<'_>,
118    ) -> crate::types::ProcessShader;
119}
120
121/// Provides proof that frame processing operations can be performed.
122/// Must be submitted to acquire a [`FrameContext`] that can be used for copy
123/// operations. This proves that all of the processing operations for a node
124/// have been submitted before the frame attempts to consume a frame.
125#[sabi_trait]
126pub trait ProcessFrameContext {
127    /// Returns an error if called twice
128    fn submit(&self) -> RResult<crate::types::FrameContext, RString>;
129}
130
131/// Provides proof that frame copy operations can be performed.
132#[sabi_trait]
133pub trait FrameContext {}
134
135/// Once a process shader has been created, this trait allows a node
136/// to interact with the shader.
137#[sabi_trait]
138pub trait ProcessShader: Send + Sync {
139    fn run(
140        &self,
141        params: crate::ShaderParams,
142        global_work_size: &[usize; 2],
143    ) -> RVec<crate::types::VideoFrame>;
144}
145
146/// Provides a handle to a video frame on the GPU.
147#[sabi_trait]
148pub trait VideoFrame: Send + Sync {
149    fn buffer_index(&self) -> usize;
150    fn width(&self) -> usize;
151    fn height(&self) -> usize;
152}
153
154/// Provides a handle to an audio frame (and the data).
155#[sabi_trait]
156pub trait AudioFrame: Send + Sync {
157    fn buffers(&self) -> &RVec<RVec<f32>>;
158}
159
160/// A video output from a node, this is where the video frames a node creates should be sent to
161/// be forwarded to other nodes.
162#[sabi_trait]
163pub trait VideoOutput: Send + Sync {
164    fn push_frame(&self, context: &crate::types::FrameContext, frame: crate::types::VideoFrame);
165}
166
167/// An audio output from a node, this is where the audio frames a node creates shoud be sent to
168/// be forwarded to other nodes.
169#[sabi_trait]
170pub trait AudioOutput: Send + Sync {
171    fn push_frame(&self, context: &crate::types::FrameContext, frame: crate::types::AudioFrame);
172}
173
174/// Provides functions for loading video frames onto the GPU.
175#[sabi_trait]
176pub trait ToRGBA: Send + Sync {
177    /// Used internally by Phaneron to get the size of a frame before loading.
178    fn get_num_bytes(&self) -> RVec<usize>;
179    /// Used internally by Phaneron to get the size of a frame after it is loaded onto the GPU.
180    fn get_num_bytes_rgba(&self) -> usize;
181    /// Used internally by Phaneron during the loading process.
182    fn get_total_bytes(&self) -> usize;
183    /// Loads a frame onto the GPU. For YUV formats, each of the Y,U, and V planes should be
184    /// provided in its own slice, thus a slice of slices is taken as an argument.
185    /// This does not perform the format conversion, only the copy.
186    /// Both this function and `process_frame` may be called in a background task/thread outside of the
187    /// `process_frame` function. A node should ensure that it only copies a "reasonable" amount of frames
188    /// onto the GPU at any point in time.
189    fn load_frame(&self, inputs: &RSlice<RSlice<u8>>) -> crate::types::LoadedVideoFrame;
190    /// After loading a frame it must be processed into the common video format by calling this function.
191    fn process_frame(&self, sources: crate::types::LoadedVideoFrame) -> crate::types::VideoFrame;
192}
193
194/// A handle to a video frame that has been loaded onto the GPU but not yet converted.
195#[sabi_trait]
196pub trait LoadedVideoFrame {}
197
198/// Provides functions for consuming video frames from the GPU.
199#[sabi_trait]
200pub trait FromRGBA: Send + Sync {
201    /// Can be used to obtain the size of the copied frame.
202    fn get_num_bytes(&self) -> RVec<usize>;
203    /// Used internally by Phaneron to get the size of the frame on the GPU.
204    fn get_num_bytes_rgba(&self) -> usize;
205    /// Used internally by Phaneron during the process of colour space conversion.
206    fn get_total_bytes(&self) -> usize;
207    /// Transforms a video frame into the described colour space / format.
208    fn process_frame(
209        &self,
210        context: &crate::types::ProcessFrameContext,
211        frame: crate::types::VideoFrame,
212    ) -> crate::types::ConsumedVideoFrame;
213    /// Copies a frame from the GPU.
214    fn copy_frame(
215        &self,
216        context: &crate::types::FrameContext, // Required to prove that processing has finished
217        frame: crate::types::ConsumedVideoFrame,
218    ) -> RVec<RVec<u8>>;
219}
220
221/// A handle to a video frame that has been transformed into a requested colour space.
222/// This handle is used to request a copy of the frame.
223#[sabi_trait]
224pub trait ConsumedVideoFrame {}
225
226/// Provides functions for creating audio frames in 32 bit floating point format.
227#[sabi_trait]
228pub trait ToAudioF32: Send + Sync {
229    /// Copies the input but does not transform it into the required format.
230    fn load_frame(&self, input: &RSlice<u8>) -> crate::types::LoadedAudioFrame;
231    /// Transforms a loaded audio frame into the common audio format.
232    fn process_frame(&self, source: crate::types::LoadedAudioFrame) -> crate::types::AudioFrame;
233}
234
235/// A handle to an audio frame that has been copied into Phaneron's memory.
236#[sabi_trait]
237pub trait LoadedAudioFrame {}
238
239/// Provides functions for consuming an audio frame in a prescribed format.
240#[sabi_trait]
241pub trait FromAudioF32: Send + Sync {
242    /// Consumes an audio frame in the requested audio format.
243    fn process_frame(
244        &self,
245        context: &crate::types::ProcessFrameContext,
246        frame: crate::types::AudioFrame,
247    ) -> crate::types::ConsumedAudioFrame;
248    /// Provides an audio frame as a single buffer.
249    fn copy_frame(
250        &self,
251        context: &crate::types::FrameContext,
252        frame: crate::types::ConsumedAudioFrame,
253    ) -> RVec<u8>;
254}
255
256/// Provides a handle to an audio frame that has been transformed into a requested format.
257#[sabi_trait]
258pub trait ConsumedAudioFrame {}