refactor: decompose oversized modules into directory form (avhw + state + cap_portal + state_portal + webrtc + bench bins) #26
+1
-1
@@ -173,7 +173,7 @@ impl SwEncEncode {
|
|||||||
0,
|
0,
|
||||||
self.enc_height as i32,
|
self.enc_height as i32,
|
||||||
(*self.yuv_frame).data.as_ptr() as *mut *mut u8,
|
(*self.yuv_frame).data.as_ptr() as *mut *mut u8,
|
||||||
(*self.yuv_frame).linesize.as_ptr() as *const i32,
|
(*self.yuv_frame).linesize.as_ptr(),
|
||||||
);
|
);
|
||||||
if scaled < 0 {
|
if scaled < 0 {
|
||||||
bail!("sws_scale failed for software encoder: {scaled}");
|
bail!("sws_scale failed for software encoder: {scaled}");
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ pub struct EncState {
|
|||||||
enc_video: ff::codec::encoder::video::Video,
|
enc_video: ff::codec::encoder::video::Video,
|
||||||
frames_rgb: AvHwFrameCtx,
|
frames_rgb: AvHwFrameCtx,
|
||||||
video_filter: ff::filter::Graph,
|
video_filter: ff::filter::Graph,
|
||||||
|
// Root AVHWDeviceContext, kept for ownership. Each consumer (encoder,
|
||||||
|
// filter graph, frames ctx) already holds its own ref_clone(); this
|
||||||
|
// field is never read after `new()` but must outlive those clones.
|
||||||
|
#[allow(dead_code)]
|
||||||
hw_device_ctx: AvHwDevCtx,
|
hw_device_ctx: AvHwDevCtx,
|
||||||
octx: ff::format::context::Output,
|
octx: ff::format::context::Output,
|
||||||
starting_timestamp: Option<i64>,
|
starting_timestamp: Option<i64>,
|
||||||
|
|||||||
@@ -587,11 +587,11 @@ fn run_cpu_pipeline(
|
|||||||
ffi::sws_scale(
|
ffi::sws_scale(
|
||||||
sws_ctx.0,
|
sws_ctx.0,
|
||||||
(*sw_frame).data.as_ptr() as *const *const u8,
|
(*sw_frame).data.as_ptr() as *const *const u8,
|
||||||
(*sw_frame).linesize.as_ptr() as *const i32,
|
(*sw_frame).linesize.as_ptr(),
|
||||||
0,
|
0,
|
||||||
(*sw_frame).height,
|
(*sw_frame).height,
|
||||||
(*encoder.yuv_frame).data.as_ptr() as *mut *mut u8,
|
(*encoder.yuv_frame).data.as_ptr() as *mut *mut u8,
|
||||||
(*encoder.yuv_frame).linesize.as_ptr() as *const i32,
|
(*encoder.yuv_frame).linesize.as_ptr(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let scale_us = t_scale.elapsed().as_micros() as u64;
|
let scale_us = t_scale.elapsed().as_micros() as u64;
|
||||||
@@ -744,11 +744,11 @@ fn run_gpu_pipeline(
|
|||||||
ffi::sws_scale(
|
ffi::sws_scale(
|
||||||
format_ctx.0,
|
format_ctx.0,
|
||||||
(*sw_nv12).data.as_ptr() as *const *const u8,
|
(*sw_nv12).data.as_ptr() as *const *const u8,
|
||||||
(*sw_nv12).linesize.as_ptr() as *const i32,
|
(*sw_nv12).linesize.as_ptr(),
|
||||||
0,
|
0,
|
||||||
(*sw_nv12).height,
|
(*sw_nv12).height,
|
||||||
(*encoder.yuv_frame).data.as_ptr() as *mut *mut u8,
|
(*encoder.yuv_frame).data.as_ptr() as *mut *mut u8,
|
||||||
(*encoder.yuv_frame).linesize.as_ptr() as *const i32,
|
(*encoder.yuv_frame).linesize.as_ptr(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let format_us = t_format.elapsed().as_micros() as u64;
|
let format_us = t_format.elapsed().as_micros() as u64;
|
||||||
|
|||||||
+4
-12
@@ -139,6 +139,10 @@ pub struct CapPortal {
|
|||||||
frame_rx: Receiver<PwDmaBufFrame>,
|
frame_rx: Receiver<PwDmaBufFrame>,
|
||||||
event_rx: Receiver<PwCtrlEvent>,
|
event_rx: Receiver<PwCtrlEvent>,
|
||||||
pw_thread: Option<JoinHandle<()>>,
|
pw_thread: Option<JoinHandle<()>>,
|
||||||
|
// Kept alive for CapPortal's whole lifetime: ashpd caches a zbus::Connection
|
||||||
|
// in a process-global OnceCell and hangs if the owning runtime drops first
|
||||||
|
// (see AGENTS.md). Never read after `new()`; only its Drop ordering matters.
|
||||||
|
#[allow(dead_code)]
|
||||||
rt: Runtime,
|
rt: Runtime,
|
||||||
pw_dropped: Arc<AtomicU64>,
|
pw_dropped: Arc<AtomicU64>,
|
||||||
}
|
}
|
||||||
@@ -154,7 +158,6 @@ struct PwThreadCtx {
|
|||||||
shutdown_read: OwnedFd,
|
shutdown_read: OwnedFd,
|
||||||
pw_fd: OwnedFd,
|
pw_fd: OwnedFd,
|
||||||
node_id: u32,
|
node_id: u32,
|
||||||
fps: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CapPortal {
|
impl CapPortal {
|
||||||
@@ -209,7 +212,6 @@ impl CapPortal {
|
|||||||
shutdown_read: unsafe { OwnedFd::from_raw_fd(efd) },
|
shutdown_read: unsafe { OwnedFd::from_raw_fd(efd) },
|
||||||
pw_fd,
|
pw_fd,
|
||||||
node_id,
|
node_id,
|
||||||
fps: args.fps,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let pw_thread = thread::Builder::new()
|
let pw_thread = thread::Builder::new()
|
||||||
@@ -697,7 +699,6 @@ fn pipewire_thread(ctx: PwThreadCtx) {
|
|||||||
shutdown_read,
|
shutdown_read,
|
||||||
pw_fd,
|
pw_fd,
|
||||||
node_id,
|
node_id,
|
||||||
fps: _,
|
|
||||||
} = ctx;
|
} = ctx;
|
||||||
|
|
||||||
let mainloop = match pw::main_loop::MainLoopBox::new(None) {
|
let mainloop = match pw::main_loop::MainLoopBox::new(None) {
|
||||||
@@ -1070,15 +1071,6 @@ fn pipewire_thread(ctx: PwThreadCtx) {
|
|||||||
// PipeWire global state is intentionally not deinitialized here — see pw::init() comment above.
|
// PipeWire global state is intentionally not deinitialized here — see pw::init() comment above.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 将四个 ASCII 字符编码为 32 位 FourCC (Four Character Code) 标识符
|
|
||||||
///
|
|
||||||
/// FourCC 是多媒体领域中广泛使用的像素格式标识方式。
|
|
||||||
/// 编码规则: 第一个字符在最低 8 位,依次向高位排列。
|
|
||||||
/// 例如: "BGRA" → 0x41524742 (小端序存储为 'B','G','R','A')
|
|
||||||
const fn fourcc(a: u8, b: u8, c: u8, d: u8) -> u32 {
|
|
||||||
(a as u32) | ((b as u32) << 8) | ((c as u32) << 16) | ((d as u32) << 24)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 将 PipeWire SPA 视频格式转换为 DRM FourCC 格式
|
/// 将 PipeWire SPA 视频格式转换为 DRM FourCC 格式
|
||||||
///
|
///
|
||||||
/// PipeWire 使用自己的 VideoFormat 枚举,而 DRM/KMS 使用 FourCC 格式标识。
|
/// PipeWire 使用自己的 VideoFormat 枚举,而 DRM/KMS 使用 FourCC 格式标识。
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ pub trait CaptureSource: Sized + 'static {
|
|||||||
pub struct OutputInfo {
|
pub struct OutputInfo {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
pub physical_size: (i32, i32),
|
|
||||||
pub logical_position: (i32, i32),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -174,7 +172,6 @@ pub(crate) enum EncConstructionStage<S: CaptureSource> {
|
|||||||
dmabuf: ZwpLinuxDmabufV1,
|
dmabuf: ZwpLinuxDmabufV1,
|
||||||
},
|
},
|
||||||
Streaming {
|
Streaming {
|
||||||
output_info: OutputInfo,
|
|
||||||
output: WlOutput,
|
output: WlOutput,
|
||||||
enc: StreamingEncoder,
|
enc: StreamingEncoder,
|
||||||
cap: S,
|
cap: S,
|
||||||
@@ -209,7 +206,6 @@ pub enum InFlightSurface<S: CaptureSource> {
|
|||||||
pub struct State<S: CaptureSource> {
|
pub struct State<S: CaptureSource> {
|
||||||
pub(crate) stage: EncConstructionStage<S>,
|
pub(crate) stage: EncConstructionStage<S>,
|
||||||
pub in_flight_surface: InFlightSurface<S>,
|
pub in_flight_surface: InFlightSurface<S>,
|
||||||
pub starting_timestamp: Option<i64>,
|
|
||||||
pub stats_start_time: Option<Instant>,
|
pub stats_start_time: Option<Instant>,
|
||||||
pub stats_last_time: Option<Instant>,
|
pub stats_last_time: Option<Instant>,
|
||||||
pub stats_frames: u64,
|
pub stats_frames: u64,
|
||||||
@@ -302,7 +298,6 @@ impl<S: CaptureSource> State<S> {
|
|||||||
wlr_head_proxy_to_name: HashMap::new(),
|
wlr_head_proxy_to_name: HashMap::new(),
|
||||||
},
|
},
|
||||||
in_flight_surface: InFlightSurface::None,
|
in_flight_surface: InFlightSurface::None,
|
||||||
starting_timestamp: None,
|
|
||||||
stats_start_time: None,
|
stats_start_time: None,
|
||||||
stats_last_time: None,
|
stats_last_time: None,
|
||||||
stats_frames: 0,
|
stats_frames: 0,
|
||||||
@@ -479,7 +474,6 @@ impl<S: CaptureSource> State<S> {
|
|||||||
pub fn on_frame_allocd(&mut self, frame: S::Frame, format: u32, width: u32, height: u32) {
|
pub fn on_frame_allocd(&mut self, frame: S::Frame, format: u32, width: u32, height: u32) {
|
||||||
let (frames_rgb_ctx, dmabuf, cap) = match &mut self.stage {
|
let (frames_rgb_ctx, dmabuf, cap) = match &mut self.stage {
|
||||||
EncConstructionStage::Streaming {
|
EncConstructionStage::Streaming {
|
||||||
output_info: _,
|
|
||||||
output: _,
|
output: _,
|
||||||
enc,
|
enc,
|
||||||
dmabuf,
|
dmabuf,
|
||||||
@@ -829,7 +823,6 @@ impl<S: CaptureSource> State<S> {
|
|||||||
bitrate
|
bitrate
|
||||||
);
|
);
|
||||||
self.stage = EncConstructionStage::Streaming {
|
self.stage = EncConstructionStage::Streaming {
|
||||||
output_info,
|
|
||||||
output,
|
output,
|
||||||
enc,
|
enc,
|
||||||
cap,
|
cap,
|
||||||
@@ -985,8 +978,6 @@ impl<S: CaptureSource> State<S> {
|
|||||||
.or(info.wl_name.clone())
|
.or(info.wl_name.clone())
|
||||||
.unwrap_or_else(|| format!("output-{}", output_names[target_idx])),
|
.unwrap_or_else(|| format!("output-{}", output_names[target_idx])),
|
||||||
transform: info.transform.unwrap(),
|
transform: info.transform.unwrap(),
|
||||||
physical_size: info.physical_size.unwrap(),
|
|
||||||
logical_position: info.logical_position.unwrap_or((0, 0)),
|
|
||||||
};
|
};
|
||||||
let output = bound_outputs[target_idx].clone();
|
let output = bound_outputs[target_idx].clone();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// AsRawFd is required by frame.fd.as_raw_fd() in build_drm_descriptor below
|
// AsRawFd is required by frame.fd.as_raw_fd() in build_drm_descriptor below
|
||||||
// but rustc emits a false "unused_imports" warning because OwnedFd also has
|
// but rustc emits a false "unused_imports" warning because OwnedFd also has
|
||||||
// an inherent as_raw_fd — same quirk as avhw.rs. E0599 if removed → keep it.
|
// an inherent as_raw_fd — same quirk as avhw.rs. E0599 if removed → keep it.
|
||||||
|
#[allow(unused_imports)]
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|||||||
Reference in New Issue
Block a user