//! HMS MediaEngine – native render bridge (ADR-0004). //! //! Rust/GStreamer-D3D11-Renderkern. Der Python-Render-Worker (§6.1C) orchestriert //! Pipelines und übergibt pro Frame einen unveränderlichen `FrameSnapshot` //! (MessagePack über IPC). Dieser Crate stellt: //! //! - ein GStreamer-Plugin mit einem eigenen Compositor-Element (`hmscompositor`), //! - einen D3D11-Layer-Compositor (Blend-Modi §12.4), //! - einen HLSL-Shader-Loader mit dem Standard-cbuffer-Layout (§14.4), //! - einen FrameReceiver für binäres MessagePack, //! - Pipeline-Builder für die D3D11-Elementkette (§13.1). //! //! Kein CPU-Readback im Normalpfad (§12.6, §33). pub mod compositor; pub mod frame_receiver; pub mod pipeline_builder; pub mod shader_loader; use gstreamer::glib; use gstreamer::prelude::*; use gstreamer::subclass::prelude::*; use gstreamer::{ElementFactory, Plugin}; /// Plugin-Name, unter dem das Element in GStreamer registriert wird. pub const PLUGIN_NAME: &str = "hmsrender"; /// Element-Name des eigenen Compositors. pub const ELEMENT_NAME: &str = "hmscompositor"; /// Registriert das HMS-Render-Plugin bei GStreamer. /// /// Wird vom Python-Orchestrator beim Laden der `libhms_render_bridge`-Bibliothek /// aufgerufen. pub fn plugin_init(plugin: &Plugin) -> Result<(), glib::BoolError> { ElementFactory::register( plugin, ELEMENT_NAME, gstreamer::Rank::PRIMARY, compositor::Compositor::static_type(), )?; Ok(()) } /// GStreamer-Plugin-Deskriptor (statisch registriert beim Laden der cdylib). gstreamer::plugin_define!( hmsrender, env!("CARGO_PKG_DESCRIPTION"), plugin_init, concat!(env!("CARGO_PKG_VERSION"), "-", env!("CARGO_PKG_NAME")), "MIT", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"), "2026-09-11", "hmsrender/plugin.rs" ); /// Bridge-API für den Python-Orchestrator (FFI-freundlich, C-kompatibel). /// /// Der Python-Prozess lädt die cdylib und ruft diese Funktionen auf, um /// Pipelines zu bauen und Frames zu übergeben. Keine Pixelverarbeitung in /// Python (§33). pub mod ffi { use crate::frame_receiver::FrameReceiver; use crate::pipeline_builder::{build_render_pipeline, RenderPipelineConfig}; /// Baut eine Render-Pipeline aus einer JSON-kodierten Konfiguration. /// /// # Safety /// `config_json` muss ein gültiger, null-terminierter C-String sein. #[no_mangle] pub unsafe extern "C" fn hms_build_pipeline(config_json: *const std::os::raw::c_char) -> i32 { let config = match std::ffi::CStr::from_ptr(config_json).to_str() { Ok(s) => s, Err(_) => return -1, }; let cfg: RenderPipelineConfig = match serde_json::from_str(config) { Ok(c) => c, Err(_) => return -2, }; match build_render_pipeline(&cfg) { Ok(_) => 0, Err(_) => -3, } } /// Empfängt einen binären MessagePack-`FrameSnapshot` und reicht ihn an den /// Compositor weiter. /// /// # Safety /// `data` muss `len` gültige Bytes zeigen. #[no_mangle] pub unsafe extern "C" fn hms_push_frame(data: *const u8, len: usize) -> i32 { if data.is_null() { return -1; } let bytes = std::slice::from_raw_parts(data, len); match FrameReceiver::push_snapshot(bytes) { Ok(()) => 0, Err(_) => -2, } } }