Files
hms-mediaengine/native/render_bridge/src/lib.rs
T
HMS MediaEngine Agent cbe1360aaa Native Renderkern: Rust/GStreamer-Plugin nach ADR-0004 (996 Zeilen)
- Cargo.toml: gstreamer-rs 0.22, windows-rs 0.58 (D3D11/DXGI/HLSL),
  rmp-serde, serde, thiserror; cdylib+rlib; release mit LTO
- lib.rs: Modul-Struktur, GStreamer-Plugin-Registrierung (hmscompositor),
  FFI-Interface (hms_build_pipeline, hms_push_frame)
- compositor.rs: alle 9 Blend-Modi (§12.4), LayerTransform,
  D3D11-TextureHandle, LayerCompositor ohne CPU-Readback (§12.6)
- shader_loader.rs: HmsParams-cbuffer nach §14.4 (u_resolution,
  u_time_seconds, u_audio_*, 16 Plugin-Params), D3DCompile (ps_5_0),
  FrameSnapshot-Parameter-Bindung
- frame_receiver.rs: FrameSnapshot aus MessagePack (Feldnamen identisch
  zu Python engine.py), Thread-sicher
- pipeline_builder.rs: d3d11h264dec -> d3d11convert -> hmscompositor ->
  d3d11videosink (§13.1)
- README.md: Windows-Build-Anleitung, Python-Integration (ctypes)
- Nicht kompiliert (ADR-0008: kein cargo im Container); zwei
  Pruefpunkte fuer Windows-Durchlauf dokumentiert:
  SimpleElement-Subklasse, D3DCompile-Signatur
2026-09-11 08:37:06 +02:00

104 lines
3.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 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,
}
}
}