oximedia_graph/lib.rs
1//! Filter graph pipeline for `OxiMedia`.
2//!
3//! This crate provides a filter graph implementation for processing media data
4//! through a pipeline of operations. The graph connects nodes (filters) together
5//! to form a processing pipeline.
6//!
7//! # Architecture
8//!
9//! The filter graph consists of:
10//!
11//! - **Nodes**: Processing units that implement the [`node::Node`] trait
12//! - **Ports**: Connection points for data flow between nodes
13//! - **Connections**: Links between output and input ports
14//! - **Frames**: Data units passed through the graph
15//!
16//! # Example
17//!
18//! ```
19//! use oximedia_graph::graph::GraphBuilder;
20//! use oximedia_graph::filters::video::{PassthroughFilter, NullSink};
21//! use oximedia_graph::node::NodeId;
22//! use oximedia_graph::port::PortId;
23//!
24//! fn build_graph() -> Result<(), Box<dyn std::error::Error>> {
25//! // Create a simple graph: source -> sink
26//! let source = PassthroughFilter::new_source(NodeId(0), "source");
27//! let sink = NullSink::new(NodeId(0), "sink");
28//!
29//! let (builder, source_id) = GraphBuilder::new().add_node(Box::new(source));
30//! let (builder, sink_id) = builder.add_node(Box::new(sink));
31//!
32//! let graph = builder
33//! .connect(source_id, PortId(0), sink_id, PortId(0))?
34//! .build()?;
35//!
36//! assert_eq!(graph.node_count(), 2);
37//! Ok(())
38//! }
39//!
40//! build_graph().expect("graph construction should succeed");
41//! ```
42//!
43//! # Node Types
44//!
45//! Nodes are classified into three types:
46//!
47//! - **Source**: Entry points that produce frames (e.g., decoders)
48//! - **Filter**: Transform frames (e.g., scalers, color converters)
49//! - **Sink**: Consume frames (e.g., encoders, displays)
50//!
51//! # Frame Flow
52//!
53//! Frames flow through the graph following the connections. The graph
54//! automatically computes a topological order for execution to ensure
55//! correct data flow.
56
57#![forbid(unsafe_code)]
58#![warn(missing_docs)]
59// Allow common pedantic lints for this crate
60#![allow(
61 clippy::missing_errors_doc,
62 clippy::missing_panics_doc,
63 clippy::must_use_candidate,
64 clippy::cast_possible_truncation,
65 clippy::cast_precision_loss,
66 clippy::cast_sign_loss,
67 clippy::redundant_closure_for_method_calls,
68 clippy::similar_names,
69 dead_code,
70 clippy::pedantic
71)]
72
73pub mod context;
74pub mod data_flow;
75pub mod edge_weight;
76pub mod error;
77pub mod filters;
78pub mod frame;
79pub mod graph;
80pub mod graph_stats;
81pub mod layout;
82pub mod metrics_graph;
83pub mod node;
84pub mod node_registry;
85pub mod optimization;
86pub mod port;
87pub mod processing_graph;
88pub mod profiling;
89pub mod scheduler;
90pub mod serialize;
91pub mod visualization;
92
93// Wave-10 new modules
94pub mod graph_validation;
95pub mod pipeline_graph;
96pub mod subgraph;
97
98// Wave-13 new modules
99pub mod cycle_detect;
100pub mod graph_merge;
101pub mod topological;
102
103// Wave-14 new modules
104pub mod dependency_graph;
105pub mod graph_partition;
106pub mod node_cache;
107
108// Graph DSL parser
109pub mod dsl;
110
111// Lock-free SPSC ring buffer and typed channel split
112pub mod async_exec;
113pub mod graph_evaluator;
114pub mod graph_rewrite;
115pub mod lock_free_ring;
116pub mod node_priority;
117pub mod port_buffer;
118
119// Dynamic graph reconfiguration (hot-swap nodes)
120pub mod hot_swap;
121
122// Re-export commonly used items
123pub use context::{GraphContext, ProcessingStats};
124pub use error::{GraphError, GraphResult};
125pub use frame::{
126 simd_copy_frame, FilterFrame, FramePool, FramePoolConfig, FrameRef, SharedFrame, ZeroCopyPort,
127};
128pub use graph::{FilterGraph, GraphBuilder};
129pub use graph_stats::{LatencyHistogram, NodeLatencyStats};
130pub use lock_free_ring::{spsc_channel, SpscConsumer, SpscProducer, SpscRingBuffer};
131pub use node::{Node, NodeConfig, NodeId, NodeState, NodeType};
132pub use port::{Connection, InputPort, OutputPort, PortFormat, PortId, PortType};
133pub use processing_graph::RetryPolicy;
134pub use topological::{CycleError, FastTopoSorter};