Skip to main content

g2g_core/
lib.rs

1//! Core types for the `glass2glass` multimedia framework.
2//!
3//! This crate is `no_std`. It defines the data carriers (`Frame`,
4//! `PipelinePacket`), the memory domain model, capability negotiation types,
5//! the `AsyncElement` execution trait, the pipeline clock, the link backpressure
6//! policy, and the error enum. It contains no I/O and no executor.
7//!
8//! The default build enables `alloc`. Building `--no-default-features` yields the
9//! heap-free MCU / safety subset: it links no allocator and carries only the
10//! data-plane types (`Frame`, `Caps`, `System`/`Foreign` memory, the const-generic
11//! `StaticLendRing`, the clock / time newtypes). The dynamic graph, caps solver,
12//! `parse_launch`, the `dyn` element traits, and the tooling (conformance, dot,
13//! copy plan, wire codec) all live behind the `alloc` feature.
14//!
15//! See `DESIGN.md` for the full specification.
16
17#![no_std]
18#![forbid(unsafe_op_in_unsafe_fn)]
19
20#[cfg(feature = "alloc")]
21extern crate alloc;
22
23/// The ABI compatibility tag for dynamically loaded (`dlopen`ed) plugins.
24///
25/// Rust has no stable ABI, so a third-party `.so` built against this crate and
26/// the host that loads it must share the same `g2g-core` version, the same
27/// `rustc`, and the same layout-affecting features (`metadata` resizes
28/// [`Frame`], `multi-thread` changes the `Send` bound on the element trait
29/// objects). This string folds all three together; the plugin loader compares
30/// the plugin's embedded copy against the host's and refuses a mismatch rather
31/// than risk undefined behavior. Computed by `build.rs`. See `g2g-plugin`
32/// (`declare_plugin!`) and `g2g_plugins::plugin_loader`.
33pub const ABI_VERSION: &str = env!("G2G_ABI_VERSION");
34
35// ---- heap-free data-plane subset (compiles with `--no-default-features`) ----
36pub mod caps;
37// Speaker channel positions / layouts for multichannel PCM (M816): the layout
38// convention behind a `Caps::Audio` channel count.
39pub mod channels;
40pub mod error;
41pub mod frame;
42pub mod link;
43// ST 2110-10 media clock (M595): PTP/TAI <-> RTP-timestamp mapping. Pure no_std
44// arithmetic tying RTP media transport to the pipeline's PTP clock.
45pub mod mediaclock;
46pub mod memory;
47pub mod meta;
48pub mod metrics;
49pub mod query;
50// RFC 3550 RTP fixed header (M643): the one shared header builder for every
51// RTP packetizer (MCU packet sink + the std packetizers in g2g-plugins).
52pub mod rtp;
53pub mod segment;
54pub mod state;
55// Static (heap-free) element model (M624, Phase 2 of the alloc-optional core):
56// generic `async fn`-in-trait source/transform/sink + const-arity runners that
57// monomorphize to unboxed futures, so an MCU pipeline needs no `dyn` and no heap.
58pub mod spsc;
59pub mod staticelem;
60pub mod staticpool;
61// Concurrency-primitive compat layer so the SpscFrameRing can be model-checked
62// under loom (`--cfg loom`); the core primitives in every normal build.
63mod sync;
64// Runtime fault recovery (M652): a supervisor that turns a returned fault into a
65// bounded retry / degrade / reset / escalate action + a watchdog seam, for the
66// safety / cert MCU market. In the no-alloc subset.
67pub mod supervise;
68pub mod tensor;
69// Boundary-scoped time newtypes (M618): TaiNs / RtpTs at the clock/PTP/RTP seam.
70pub mod time;
71
72// ---- dynamic / build-time / tooling layer (needs the heap) ----
73#[cfg(feature = "alloc")]
74pub mod aggregator;
75// The `gst-launch` caps-string parser, inverse of `Caps::to_gst_string`.
76#[cfg(feature = "alloc")]
77pub mod caps_parse;
78// Declarative field-wise caps derivation (M837): the data form of a transform's
79// forward derivation, from which the solver reads its backward-coupling mask.
80#[cfg(feature = "alloc")]
81pub mod caps_transform;
82// Conformance vocabulary + derived maturity (M614): a maturity level computed from
83// evidence produced by passing conformance cases, never hand-authored. Pure.
84#[cfg(feature = "alloc")]
85pub mod chapter;
86#[cfg(feature = "alloc")]
87pub mod clock;
88#[cfg(feature = "alloc")]
89pub mod conformance;
90#[cfg(feature = "alloc")]
91pub mod format_element;
92// Copy / allocation plan (M613): static memory-domain path analysis over a
93// negotiated graph. Pure (like `dot`); the runner extracts its flat inputs.
94#[cfg(feature = "alloc")]
95pub mod copyplan;
96#[cfg(feature = "alloc")]
97pub mod dot;
98#[cfg(feature = "alloc")]
99pub mod element;
100#[cfg(feature = "alloc")]
101pub mod graph;
102#[cfg(feature = "alloc")]
103pub mod log;
104#[cfg(feature = "alloc")]
105pub mod pool;
106#[cfg(feature = "alloc")]
107pub mod property;
108#[cfg(feature = "alloc")]
109pub mod stream;
110#[cfg(feature = "alloc")]
111pub mod tag;
112#[cfg(feature = "alloc")]
113pub mod wire;
114// PTP clock servo (M593 phase A): disciplines a monotonic reference to a
115// grandmaster. Needs the `DriftClock` servo core, hence the `runtime` gate.
116#[cfg(feature = "runtime")]
117pub mod ptp;
118
119#[cfg(feature = "runtime")]
120pub mod bus;
121
122#[cfg(feature = "runtime")]
123pub mod qos;
124
125// Sink-side presentation pacing (M881): the PTS -> clock deadline, the anchor,
126// and the QoS late-drop verdict every display sink shares.
127#[cfg(feature = "runtime")]
128pub mod pacing;
129
130#[cfg(feature = "runtime")]
131pub mod fanout;
132
133// Animated properties (M882): keyframed control sources the runner samples per
134// frame, the gst-controller analog. Dynamic layer (heap + the dyn element
135// traits), so `runtime` like the graph runner that applies it.
136#[cfg(feature = "runtime")]
137pub mod controller;
138
139#[cfg(feature = "runtime")]
140pub mod runtime;
141
142#[cfg(feature = "runtime")]
143pub mod pad_template;
144
145#[cfg(feature = "dyn-slot")]
146pub mod slot;
147
148#[cfg(feature = "alloc")]
149pub use aggregator::InputAggregator;
150pub use caps::{
151    pcm_formats, pcm_from_gst_format, pcm_gst_format, AudioFormat, ByteStreamEncoding, Caps,
152    ClosedCaptionFormat, Dim, Interlace, PassthroughFields, Rate, RawVideoFormat, SubPictureFormat,
153    TensorDType, TensorLayout, TensorShape, TextFormat, VideoCodec, ANY_CHANNELS, ANY_SAMPLE_RATE,
154    PCM_FORMATS,
155};
156pub use channels::{ChannelLayout, ChannelPosition};
157// `CapsSet` (negotiation-time alternatives) needs alloc; `TensorShape` is
158// fixed-rank inline (M636) and part of the no-alloc subset above.
159#[cfg(feature = "alloc")]
160pub use caps::CapsSet;
161#[cfg(feature = "alloc")]
162pub use caps_transform::{AudioShape, CapsTransform, FieldTransform, RawVideoShape};
163#[cfg(feature = "alloc")]
164pub use chapter::Chapter;
165#[cfg(feature = "std")]
166pub use clock::MonotonicClock;
167#[cfg(feature = "alloc")]
168pub use clock::{
169    elect_clock, AsyncClock, ClockCandidate, ClockPriority, ClockSync, DynAsyncClock, ElectedClock,
170    PipelineClock,
171};
172#[cfg(feature = "runtime")]
173pub use clock::{DriftClock, DriftObservation};
174#[cfg(feature = "alloc")]
175pub use conformance::{
176    ConformanceDimension, ConformanceReport, Evidence, MaturityLevel, MaturityRecord,
177};
178#[cfg(feature = "runtime")]
179pub use controller::{
180    ArmController, ControlFault, ControlProgram, ControlReason, ControlSource, ControlTarget,
181};
182#[cfg(feature = "alloc")]
183pub use copyplan::{
184    classify as classify_transfer, CopyBudgetError, CopyPlan, CopyPolicy, EdgeProfile, Hop,
185    NodeProfile, Transfer, TransferKind,
186};
187#[cfg(feature = "alloc")]
188pub use dot::DotAnnotations;
189#[cfg(feature = "alloc")]
190pub use element::{
191    AsyncElement, ConfigureOutcome, ElementBound, OutputSink, OutputSinkExt, PresentationStats,
192    PushFuture, PushOutcome, QosMessage, Reconfigure,
193};
194pub use error::{G2gError, HardwareError};
195#[cfg(feature = "alloc")]
196pub use format_element::{
197    legacy_sink_constraint, legacy_transform_constraint, CapsConstraint, CapsPreferences,
198    FormatElement,
199};
200pub use frame::{Frame, FrameTiming, PipelinePacket};
201#[cfg(feature = "alloc")]
202pub use graph::{
203    Bin, BinInstance, Demux, Edge, Graph, GraphError, Muxer, NodeId, NodeIdOffset, NodeKind,
204    PadDir, PadId, Tee, ValidatedGraph,
205};
206pub use link::LinkPolicy;
207pub use mediaclock::MediaClock;
208pub use meta::FrameMetaSet;
209#[cfg(feature = "metadata")]
210pub use meta::{
211    blob_decoder, decode_blob, AnalyticsMeta, AnalyticsNode, BBox, Blob, BlobDecoder, BlobMeta,
212    CaptionMeta, CaptionTriple, Chromaticity, Classification, DecodedBlob, FrameMeta,
213    HdrStaticMeta, Mask, MasteringDisplay, NamedTensor, ObjectDetection, Propagation, Relation,
214    RelationKind, Roi, Segmentation, TensorMeta, TimecodeMeta, Tracking, Transform, BLOB_DECODERS,
215};
216#[cfg(feature = "alloc")]
217pub use property::{
218    takes_undeclared_properties, ElementMetadata, PropError, PropFlags, PropKind, PropValue,
219    PropertySpec, ValueError, UNDECLARED_PROPERTIES,
220};
221#[cfg(feature = "runtime")]
222pub use ptp::{
223    ExchangeResult, PtpClock, PtpHeader, PtpMessageType, PtpServo, PtpSlave, PtpState, SlaveAction,
224};
225// The heap-free memory subset: the domain enum + its discriminant / set, and the
226// `System` slice (whose `Foreign` variant the StaticLendRing lends zero-copy).
227pub use memory::{DomainSet, MemoryDomain, MemoryDomainKind, SystemSlice};
228// The GPU / shared-CPU domains are heap-backed (Arc/Box keep-alives).
229#[cfg(feature = "alloc")]
230pub use memory::{
231    CudaKeepAlive, CvPixelBufferKeepAlive, D3D11KeepAlive, OwnedCudaBuffer, OwnedCvPixelBuffer,
232    OwnedD3D11Texture, OwnedDmaBuf, OwnedVulkanTexture, OwnedWebGPUBuffer,
233    OwnedWebGPUExternalTexture, OwnedWgpuBuffer, OwnedWgpuTexture, SyncFd, SystemView,
234    WebGPUKeepAlive, WgpuBufferKeepAlive, WgpuKeepAlive,
235};
236pub use metrics::{LatencyHistogram, LatencySnapshot};
237pub use query::{AllocationParams, LatencyReport};
238pub use rtp::{RtpHeader, RtpParsed, RTP_HEADER_LEN};
239pub use segment::{Seek, SeekFlags, SeekType, Segment};
240pub use spsc::{Overrun, SpscFrameRing};
241// SpscCaptureSrc uses the zero-copy lend, which is not built under loom.
242#[cfg(not(loom))]
243pub use spsc::SpscCaptureSrc;
244pub use state::{PipelineState, StateChangeReturn};
245pub use staticelem::{
246    drive_ready, run_source_sink, run_source_transform_sink, run_sources_fanin_sink,
247    step_source_sink, Chain, SinkChain, SourceChain, StaticFanIn2, StaticSink, StaticSource,
248    StaticTransform, Step,
249};
250pub use staticpool::{RingSlot, StaticAcquire, StaticBufferPool, StaticLendRing, StaticPooled};
251#[cfg(feature = "alloc")]
252pub use stream::{Stream, StreamCollection, StreamType};
253pub use supervise::{
254    run_supervised, step_supervised, FaultPolicy, NoWatchdog, Recover, Recovery, RetryThenReset,
255    RunOutcome, SkipBounded, Supervised, SupervisorReport, Watchdog, MAX_ATTEMPTS,
256};
257#[cfg(feature = "alloc")]
258pub use tag::{resolve_tags, split_tags, Tag, TagList};
259pub use tensor::{TensorView, MAX_TENSOR_RANK};
260pub use time::{RefNs, RtpTs, TaiNs};
261#[cfg(feature = "alloc")]
262pub use wire::{
263    decode_packet, encode_packet, raw_format_from_u8, raw_format_to_u8, WireError, WIRE_VERSION,
264};
265
266#[cfg(feature = "runtime")]
267pub use pool::{BufferPool, PooledBuffer};
268
269#[cfg(feature = "runtime")]
270pub use bus::{Bus, BusHandle, BusMessage};
271
272#[cfg(feature = "runtime")]
273pub use qos::QosTracker;
274
275#[cfg(feature = "runtime")]
276pub use pacing::{
277    Pace, PresentationPacer, MAX_LATENESS_PROPERTY, PACING_PROPERTIES, QOS_INTERVAL_PROPERTY,
278};
279
280#[cfg(feature = "runtime")]
281pub use runtime::{CapsConflict, LinkInterceptor, NegotiationFailure, ProbeAction, ProbeSlot};
282
283#[cfg(feature = "runtime")]
284pub use pad_template::{
285    pad_link, types_can_link, PadCaps, PadDirection, PadTemplate, PadTemplates,
286};
287
288#[cfg(feature = "runtime")]
289pub use fanout::{
290    DuplexInbound, Gate, GateHandle, Merger, MergerHandle, MultiDuplexSession, MultiInputElement,
291    MultiOutputElement, MultiOutputSink, MultiOutputSinkExt, MultiOutputSource, MultiSenderSink,
292    PushToFuture, ReverseChannel, Router, RouterHandle,
293};
294
295#[cfg(feature = "dyn-slot")]
296pub use slot::{ElementSlot, SwapHandle};