mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-11 00:05:36 +02:00
⭐ feat(runner): DMA-BUF support for Intel/AMD GPUs (#283)
## Description Adds DMA-BUF support for non-NVIDIA GPUs using GL elements as conversion workaround. Tested with QSV and VA encoders, note that H.264 seems to only work for QSV encoder, for `vah264(lp)enc` theres major CPU usage with DMA-BUF enabled. Don't mind the branch name, I was working on relay before and changed gears to runner after noticing some DMA-BUF stuff 😅 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Chores** - Added a `.dockerignore` file to exclude the `target` directory from Docker builds. - Updated `.gitignore` to ignore the `target` directory. - **New Features** - Enhanced video processing pipeline with updated handling of DMA-BUF support, including improved compatibility for different GPU vendors and refined video element configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
6e19b2e9a0
commit
d7e6da12ac
1
packages/server/.dockerignore
Normal file
1
packages/server/.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
target/
|
||||
3
packages/server/.gitignore
vendored
3
packages/server/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
*.mp4
|
||||
*.mp4
|
||||
target/
|
||||
@@ -172,7 +172,7 @@ fn handle_encoder_audio(args: &args::Args) -> String {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Parse command line arguments
|
||||
let mut args = args::Args::new();
|
||||
let args = args::Args::new();
|
||||
if args.app.verbose {
|
||||
args.debug_print();
|
||||
}
|
||||
@@ -206,10 +206,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
let gpu = gpu.unwrap();
|
||||
|
||||
// TODO: Currently DMA-BUF only works for NVIDIA
|
||||
if args.app.dma_buf && *gpu.vendor() != GPUVendor::NVIDIA {
|
||||
log::warn!("DMA-BUF is currently unsupported outside NVIDIA GPUs, force disabling..");
|
||||
args.app.dma_buf = false;
|
||||
if args.app.dma_buf {
|
||||
log::warn!(
|
||||
"DMA-BUF is experimental, it may or may not improve performance, or even work at all."
|
||||
);
|
||||
}
|
||||
|
||||
// Handle video encoder selection
|
||||
@@ -288,7 +288,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
))?;
|
||||
caps_filter.set_property("caps", &caps);
|
||||
|
||||
// GL Upload Element
|
||||
// GL Upload element
|
||||
let glupload = gst::ElementFactory::make("glupload").build()?;
|
||||
|
||||
// GL color convert element
|
||||
@@ -299,6 +299,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let gl_caps = gst::Caps::from_str("video/x-raw(memory:GLMemory),format=NV12")?;
|
||||
gl_caps_filter.set_property("caps", &gl_caps);
|
||||
|
||||
// GL download element (needed only for DMA-BUF outside NVIDIA GPUs)
|
||||
let gl_download = gst::ElementFactory::make("gldownload").build()?;
|
||||
|
||||
// Video Converter Element
|
||||
let video_converter = gst::ElementFactory::make("videoconvert").build()?;
|
||||
|
||||
@@ -372,7 +375,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// If DMA-BUF is enabled, add glupload, color conversion and caps filter
|
||||
if args.app.dma_buf {
|
||||
pipeline.add_many(&[&glupload, &glcolorconvert, &gl_caps_filter])?;
|
||||
if *gpu.vendor() == GPUVendor::NVIDIA {
|
||||
pipeline.add_many(&[&glupload, &glcolorconvert, &gl_caps_filter])?;
|
||||
} else {
|
||||
pipeline.add_many(&[&glupload, &glcolorconvert, &gl_caps_filter, &gl_download])?;
|
||||
}
|
||||
}
|
||||
|
||||
// Link main audio branch
|
||||
@@ -389,19 +396,31 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// With DMA-BUF, also link glupload and it's caps
|
||||
if args.app.dma_buf {
|
||||
// Link video source to caps_filter, glupload, gl_caps_filter, video_converter, video_encoder, webrtcsink
|
||||
gst::Element::link_many(&[
|
||||
&video_source,
|
||||
&caps_filter,
|
||||
&video_queue,
|
||||
&video_clocksync,
|
||||
&glupload,
|
||||
&glcolorconvert,
|
||||
&gl_caps_filter,
|
||||
&video_encoder,
|
||||
])?;
|
||||
if *gpu.vendor() == GPUVendor::NVIDIA {
|
||||
gst::Element::link_many(&[
|
||||
&video_source,
|
||||
&caps_filter,
|
||||
&video_queue,
|
||||
&video_clocksync,
|
||||
&glupload,
|
||||
&glcolorconvert,
|
||||
&gl_caps_filter,
|
||||
&video_encoder,
|
||||
])?;
|
||||
} else {
|
||||
gst::Element::link_many(&[
|
||||
&video_source,
|
||||
&caps_filter,
|
||||
&video_queue,
|
||||
&video_clocksync,
|
||||
&glupload,
|
||||
&glcolorconvert,
|
||||
&gl_caps_filter,
|
||||
&gl_download,
|
||||
&video_encoder,
|
||||
])?;
|
||||
}
|
||||
} else {
|
||||
// Link video source to caps_filter, video_converter, video_encoder, webrtcsink
|
||||
gst::Element::link_many(&[
|
||||
&video_source,
|
||||
&caps_filter,
|
||||
@@ -437,7 +456,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let result = run_pipeline(pipeline.clone()).await;
|
||||
|
||||
match result {
|
||||
Ok(_) => log::info!("All tasks completed successfully"),
|
||||
Ok(_) => log::info!("All tasks finished"),
|
||||
Err(e) => {
|
||||
log::error!("Error occurred in one of the tasks: {}", e);
|
||||
return Err("Error occurred in one of the tasks".into());
|
||||
|
||||
Reference in New Issue
Block a user