57 lines
1.6 KiB
Rust
57 lines
1.6 KiB
Rust
#![forbid(unsafe_code)]
|
|
|
|
use gstreamer as gst;
|
|
|
|
/// Pick the client-side H.264 decoder in a predictable preference order.
|
|
///
|
|
/// Inputs: none, though operators may override the choice with
|
|
/// `LESAVKA_H264_DECODER=<element>`.
|
|
/// Outputs: the chosen decoder element name, or `decodebin` as a last-resort
|
|
/// fallback when no explicit decoder is present.
|
|
/// Why: `decodebin` is flexible, but a stable preference order makes decode
|
|
/// behavior easier to reason about and compare in diagnostics.
|
|
#[must_use]
|
|
pub fn pick_h264_decoder() -> String {
|
|
if let Ok(raw) = std::env::var("LESAVKA_H264_DECODER") {
|
|
let name = raw.trim();
|
|
if name.eq_ignore_ascii_case("decodebin") {
|
|
return "decodebin".to_string();
|
|
}
|
|
if !name.is_empty() && buildable_decoder(name) {
|
|
return name.to_string();
|
|
}
|
|
}
|
|
|
|
for name in [
|
|
"avdec_h264",
|
|
"openh264dec",
|
|
"nvh264dec",
|
|
"nvh264sldec",
|
|
"vah264dec",
|
|
"vaapih264dec",
|
|
"v4l2h264dec",
|
|
"v4l2slh264dec",
|
|
] {
|
|
if buildable_decoder(name) {
|
|
return name.to_string();
|
|
}
|
|
}
|
|
|
|
"decodebin".to_string()
|
|
}
|
|
|
|
fn buildable_decoder(name: &str) -> bool {
|
|
#[cfg(coverage)]
|
|
if std::env::var("TEST_FAIL_GST_INIT").is_ok() {
|
|
return false;
|
|
}
|
|
if gst::init().is_err() {
|
|
return false;
|
|
}
|
|
#[cfg(coverage)]
|
|
if std::env::var("TEST_DISABLE_H264_DECODER_FACTORY").is_ok() {
|
|
return false;
|
|
}
|
|
gst::ElementFactory::find(name).is_some() && gst::ElementFactory::make(name).build().is_ok()
|
|
}
|