AUFGERAUMT: Root auf 10 sichtbare Elemente reduziert
Der Nutzer hat recht: Der Ordner war voller Entwicklungs-Muell. Jetzt ist sauber getrennt: ROOT (was der Nutzer sieht und braucht): - run.py = das Programm - hms_app/ = der Anwendungscode - HMS MediaEngine.app = macOS Doppelklick-Starter - HMS-Start.vbs = Windows Doppelklick-Starter - HMS-Install.vbs = Windows Erst-Installation - HMS-Mac-Install.command = macOS Homebrew-Installation - HMS-Portable-Install.command = macOS Portable-Installation (16GB-Fix) - installer_gui.py = grafischer Installer - launcher.pyw + launcher_core.py = interne Start-Logik - LIESMICH.txt = 10-Zeilen-Kurzanleitung - .gitignore _entwicklung/ (alles andere, NICHT benoetigt): - packages/ apps/ native/ plugins/ tools/ schemas/ tests/ docs/ build/ fixture_profiles/ - PLAN.md STATUS.md ERRORS.md TEST_REPORT.md CHANGELOG.md README.md - pyproject.toml uv.lock setup_*.sh/ps1 make_mac_app.py Diese Trennung gilt ab sofort fuer alle Commits. Der Nutzer kann _entwicklung/ loeschen wenn er Platz braucht - die App laeuft ohne. Verifiziert: App startet nach Aufraeumen unveraendert (Health 200).
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
//! 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user