pixelflow 0.1.0

Public facade for PixelFlow embedding APIs.
Documentation
#![warn(missing_docs)]
#![forbid(unsafe_code)]

//! Public facade for PixelFlow embedding APIs.

pub use pixelflow_core::PIXELFLOW_ABI_VERSION;
pub use pixelflow_core::{
    AllocatorConfig, ChromaSiting, ChromaSubsampling, Clip, ClipFormat, ClipMedia, ClipResolution,
    ColorMatrix, ColorPrimaries, ColorRange, ColorTransfer, ConcurrencyClass, Core, CoreConfig,
    DependencyPattern, DynamicDependencyBounds, ErrorCategory, ErrorCode, FilterChangeSet,
    FilterCompatibility, FilterDescriptor, FilterOptionValue, FilterOptions, FilterPlan,
    FilterPlanRequest, FilterRegistry, FilterTiming, FormatDescriptor, FormatFamily, Frame,
    FrameBuilder, FrameCount, FrameExecutor, FrameRate, FrameRequest, Graph, GraphBuilder,
    GraphNode, LoadedPlugin, LogLevel, LogRecord, LogSink, Logger, Metadata, MetadataKind,
    MetadataSchema, MetadataValue, NodeId, NodeKind, NoopLogSink, OrderedRender, PixelFlowError,
    Plane, PlaneDescriptor, PlaneMut, PlaneRole, PlaneRows, Rational, RawPlane, RawPlaneMut,
    RenderEngine, RenderExecutorMap, RenderOptions, RenderRange, Result, Sample, SampleType,
    SourceCapabilities, SourceOptionValue, SourceRequest, TimingReport, ValidatedGraph,
    ValidationPlan, WorkerPoolConfig, Y4mWriter, format_with_bit_depth, is_y4m_compatible_format,
    load_plugins_from_directories, platform_plugin_directories, resolve_format_alias, version,
    y4m_chroma_tag,
};

#[cfg(feature = "plugin-sdk")]
pub mod plugin_sdk {
    //! Re-exports for plugin authors.

    pub use pixelflow_plugin_sdk::*;
}

#[cfg(feature = "script")]
pub mod script {
    //! Re-exports for script integration.

    pub use pixelflow_script::*;
}

#[cfg(test)]
mod tests {
    use super::{AllocatorConfig, MetadataSchema, resolve_format_alias};

    #[test]
    fn facade_reexports_core_types() {
        let format = resolve_format_alias("gray8").expect("format should resolve");
        let schema = MetadataSchema::core();
        let allocator = AllocatorConfig::default();
        let media = super::ClipMedia::fixed(
            format.clone(),
            1280,
            720,
            1,
            super::Rational {
                numerator: 24,
                denominator: 1,
            },
        );

        assert_eq!(format.name(), "gray8");
        assert!(schema.contains_key("core:matrix"));
        assert!(allocator.actual_alignment() >= 64);
        assert!(super::is_y4m_compatible_format(&format));
        assert!(matches!(media.frame_rate(), super::FrameRate::Cfr(_)));
        assert_eq!(super::ColorMatrix::Bt709.as_str(), "bt709");
        assert_eq!(super::ChromaSiting::Center.offsets(), (0.5, 0.5));
    }

    #[test]
    fn facade_reexports_render_types() {
        let config = super::WorkerPoolConfig::new(2);
        let engine = super::RenderEngine::new(config);

        assert_eq!(engine.worker_threads(), 2);
        assert!(super::DependencyPattern::same_frame().allows(1, 1));
    }

    #[test]
    fn facade_reexports_filter_planning_types() {
        let schema = super::MetadataSchema::core();
        let media = super::ClipMedia::fixed(
            super::resolve_format_alias("gray8").expect("format should resolve"),
            2,
            2,
            1,
            super::Rational {
                numerator: 24,
                denominator: 1,
            },
        );
        let options = super::FilterOptions::new();
        let _value = super::FilterOptionValue::Array(vec![super::FilterOptionValue::None]);
        let request =
            super::FilterPlanRequest::new(std::slice::from_ref(&media), &options, &schema);
        let plan = super::FilterPlan::new(media.clone(), super::FilterCompatibility::Preserve);

        assert_eq!(request.input_media(), std::slice::from_ref(&media));
        assert_eq!(plan.output_media(), &media);
    }

    #[test]
    fn facade_reexports_plugin_loading_helpers() {
        let _loader: fn(
            &[std::path::PathBuf],
            &mut super::FilterRegistry,
            &super::Logger,
        ) -> Vec<super::LoadedPlugin> = super::load_plugins_from_directories;
    }

    #[cfg(feature = "script")]
    #[test]
    fn facade_reexports_script_engine() {
        let _changes = super::FilterChangeSet {
            format: false,
            resolution: true,
            frame_count: false,
            frame_rate: false,
        };
        let engine = super::script::ScriptEngine::new();
        let graph = engine
            .evaluate("output = source(\"input.mkv\")", &[])
            .expect("script should evaluate");

        assert_eq!(graph.graph().outputs().len(), 1);
    }
}