use std::sync::Arc;
use crate::gpu_pool::GpuPool;
use crate::spec::{EncodePolicy, GpuFamily};
pub fn detect_gpu_pool() -> Arc<GpuPool> {
Arc::new(GpuPool::new(&codec::gpu::detect_gpus()))
}
fn policy_vendor(fam: GpuFamily) -> codec::gpu::GpuVendor {
match fam {
GpuFamily::Nvidia => codec::gpu::GpuVendor::Nvidia,
GpuFamily::Amd => codec::gpu::GpuVendor::Amd,
GpuFamily::Intel => codec::gpu::GpuVendor::Intel,
}
}
fn select_gpus_for_policy(policy: EncodePolicy) -> Vec<codec::gpu::GpuDevice> {
let gpus = codec::gpu::detect_gpus();
match policy {
EncodePolicy::AllGpus => gpus,
EncodePolicy::SingleGpu(None) => gpus.into_iter().take(1).collect(),
EncodePolicy::SingleGpu(Some(idx)) => gpus.into_iter().filter(|g| g.index == idx).collect(),
EncodePolicy::Family(fam) => {
let v = policy_vendor(fam);
gpus.into_iter().filter(|g| g.vendor == v).collect()
}
}
}
pub fn gpu_pool_for_policy(policy: EncodePolicy, codec: codec::frame::VideoCodec) -> Arc<GpuPool> {
let selected = select_gpus_for_policy(policy);
let pool_gpus = if selected.len() > 1 {
selected.into_iter().filter(|g| codec::encode::encode_capable(g, codec)).collect()
} else {
selected
};
Arc::new(GpuPool::new(&pool_gpus))
}
pub fn policy_gpu_indices(policy: EncodePolicy) -> Vec<u32> {
select_gpus_for_policy(policy).into_iter().map(|g| g.index).collect()
}
pub fn serial_gpu_for_policy(policy: EncodePolicy) -> Option<u32> {
match policy {
EncodePolicy::AllGpus => None,
EncodePolicy::SingleGpu(idx) => idx,
EncodePolicy::Family(_) => select_gpus_for_policy(policy).first().map(|g| g.index),
}
}