Skip to content

Commit c3a4ff1

Browse files
committed
recreate filter & encoder on resize instead of choking
cleanup
1 parent 38b3b28 commit c3a4ff1

File tree

5 files changed

+477
-274
lines changed

5 files changed

+477
-274
lines changed

src/avhw.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use ffmpeg::{
99
format::Pixel,
1010
frame,
1111
};
12+
use log::error;
13+
14+
use crate::DrmModifier;
1215

1316
pub struct AvHwDevCtx {
1417
ptr: *mut ffmpeg::sys::AVBufferRef,
@@ -45,6 +48,7 @@ impl AvHwDevCtx {
4548
pixfmt: Pixel,
4649
width: i32,
4750
height: i32,
51+
modifier: DrmModifier,
4852
) -> Result<AvHwFrameCtx, ffmpeg::Error> {
4953
unsafe {
5054
let mut hwframe = av_hwframe_ctx_alloc(self.ptr as *mut _);
@@ -57,6 +61,10 @@ impl AvHwDevCtx {
5761
(*hwframe_casted).height = height;
5862
(*hwframe_casted).initial_pool_size = 5;
5963

64+
if modifier != DrmModifier::LINEAR {
65+
error!("unknown how to request non-linear frames in vaapi");
66+
}
67+
6068
let sts = av_hwframe_ctx_init(hwframe);
6169
if sts != 0 {
6270
return Err(ffmpeg::Error::from(sts));

src/cap_ext_image_copy.rs

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::PathBuf;
33
use anyhow::Context;
44
use drm::{buffer::DrmFourcc, node::DrmNode};
55
use libc::dev_t;
6-
use log::warn;
6+
use log::{debug, warn};
77
use log_once::warn_once;
88
use wayland_client::{
99
globals::GlobalList, protocol::wl_output::WlOutput, Dispatch, Proxy, QueueHandle,
@@ -20,7 +20,7 @@ use wayland_protocols::ext::{
2020
},
2121
};
2222

23-
use crate::{CaptureSource, DmabufFormat, DmabufPotentialFormat, DrmModifier, State};
23+
use crate::{CaptureSource, DmabufPotentialFormat, DrmModifier, State};
2424

2525
impl Dispatch<ExtImageCopyCaptureManagerV1, ()> for State<CapExtImageCopy> {
2626
fn event(
@@ -99,11 +99,7 @@ impl Dispatch<ExtImageCopyCaptureSessionV1, ()> for State<CapExtImageCopy> {
9999
}
100100
}
101101
ext_image_copy_capture_session_v1::Event::Done => {
102-
let mut constraints = BufferConstraints {
103-
dmabuf_formats: Vec::new(),
104-
buffer_size: None,
105-
dmabuf_device: None,
106-
};
102+
let mut constraints = BufferConstraints::default();
107103
// All buffer constraint events will be resent on every change, so reset
108104
// accumulated state
109105
std::mem::swap(
@@ -114,28 +110,17 @@ impl Dispatch<ExtImageCopyCaptureSessionV1, ()> for State<CapExtImageCopy> {
114110
let size = constraints
115111
.buffer_size
116112
.expect("Done received before BufferSize...");
117-
let fmt = state.negotiate_format(
113+
state.negotiate_format(
118114
&constraints.dmabuf_formats,
119115
size,
120116
constraints.dmabuf_device.as_deref(),
117+
qhandle,
121118
);
122-
let Some(fmt) = fmt else {
123-
// error, it's already reported so we just have to cleanup & exit
124-
return;
125-
};
126-
127-
let cap = state.enc.unwrap_cap();
128-
cap.current_config = Some((fmt, size));
129-
130-
let (width, height, format, frame) = cap
131-
.queue_capture_frame(qhandle)
132-
.expect("Done without size/format!");
133-
state.on_copy_src_ready(width, height, format, qhandle, &frame);
134119
}
135120
ext_image_copy_capture_session_v1::Event::Stopped => {
136121
state.on_copy_fail(qhandle); // untested if this actually works
137122
}
138-
_ => todo!(),
123+
_ => {}
139124
}
140125
}
141126
}
@@ -151,8 +136,8 @@ impl Dispatch<ExtImageCopyCaptureFrameV1, ()> for State<CapExtImageCopy> {
151136
) {
152137
use wayland_protocols::ext::image_copy_capture::v1::client::ext_image_copy_capture_frame_v1::Event::*;
153138
match event {
154-
Transform { .. } => {}
155-
Damage { .. } => {} // TODO: maybe this is how you implement damage
139+
Transform { .. } => {} // TODO: use this
140+
Damage { .. } => {} // TODO: maybe this is how you implement damage
156141
PresentationTime {
157142
tv_sec_hi,
158143
tv_sec_lo,
@@ -162,15 +147,17 @@ impl Dispatch<ExtImageCopyCaptureFrameV1, ()> for State<CapExtImageCopy> {
162147
let (hi, lo, n) = state.enc.unwrap().cap.time.take().unwrap();
163148
state.on_copy_complete(qhandle, hi, lo, n);
164149
}
165-
Failed { .. } => {
150+
Failed { reason } => {
151+
debug!("frame copy failed: {reason:?}");
166152
state.on_copy_fail(qhandle);
167153
}
168-
_ => {}
154+
_ => todo!(),
169155
}
170156
}
171157
}
172158

173159
/** Struct to collect buffer constraint information as the events arrive */
160+
#[derive(Default)]
174161
struct BufferConstraints {
175162
dmabuf_formats: Vec<DmabufPotentialFormat>,
176163
buffer_size: Option<(u32, u32)>,
@@ -181,7 +168,6 @@ pub struct CapExtImageCopy {
181168
output_capture_session: ExtImageCopyCaptureSessionV1,
182169
time: Option<(u32, u32, u32)>,
183170
in_progress_constraints: BufferConstraints,
184-
current_config: Option<(DmabufFormat, (u32, u32))>,
185171
}
186172

187173
impl CaptureSource for CapExtImageCopy {
@@ -218,28 +204,17 @@ impl CaptureSource for CapExtImageCopy {
218204
Ok(Self {
219205
output_capture_session,
220206
time: None,
221-
in_progress_constraints: BufferConstraints {
222-
dmabuf_formats: Vec::new(),
223-
buffer_size: None,
224-
dmabuf_device: None,
225-
},
226-
current_config: None,
207+
in_progress_constraints: BufferConstraints::default(),
227208
})
228209
}
229210

230-
fn queue_capture_frame(
231-
&self,
232-
eq: &QueueHandle<crate::State<Self>>,
233-
) -> Option<(u32, u32, DrmFourcc, Self::Frame)> {
234-
if let Some((fmt, (w, h))) = &self.current_config {
235-
let frame = self.output_capture_session.create_frame(eq, ());
236-
Some((*w, *h, fmt.fourcc, frame))
237-
} else {
238-
None
239-
}
211+
fn alloc_frame(&self, eq: &QueueHandle<crate::State<Self>>) -> Option<Self::Frame> {
212+
debug!("ext_image_copy_capture_session_v1::create_frame");
213+
let frame = self.output_capture_session.create_frame(eq, ());
214+
Some(frame)
240215
}
241216

242-
fn queue_copy_frame(
217+
fn queue_copy(
243218
&self,
244219
damage: bool,
245220
buf: &wayland_client::protocol::wl_buffer::WlBuffer,
@@ -253,6 +228,7 @@ impl CaptureSource for CapExtImageCopy {
253228
}
254229

255230
fn on_done_with_frame(&self, f: Self::Frame) {
231+
debug!("ext_image_copy_capture_frame_v1::destroy");
256232
f.destroy();
257233
}
258234
}

src/cap_wlr_screencopy.rs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,18 @@ impl Dispatch<ZwlrScreencopyFrameV1, ()> for State<CapWlrScreencopy> {
5757
} => {
5858
let fourcc = DrmFourcc::try_from(format).unwrap();
5959
let cap = state.enc.unwrap_cap();
60-
if !cap.sent_format {
61-
cap.sent_format = true;
62-
let device = cap.drm_device.clone();
63-
if state
64-
.negotiate_format(
65-
&[DmabufPotentialFormat {
66-
fourcc,
67-
modifiers: vec![DrmModifier::LINEAR],
68-
}],
69-
(dmabuf_width, dmabuf_height),
70-
device.as_deref(),
71-
)
72-
.is_none()
73-
{
74-
return; // error, which has already been reported
75-
}
76-
}
77-
state.on_copy_src_ready(dmabuf_width, dmabuf_height, fourcc, qhandle, capture);
60+
61+
let device = cap.drm_device.clone();
62+
state.negotiate_format(
63+
&[DmabufPotentialFormat {
64+
fourcc,
65+
modifiers: vec![DrmModifier::LINEAR],
66+
}],
67+
(dmabuf_width, dmabuf_height),
68+
device.as_deref(),
69+
qhandle,
70+
);
71+
state.on_frame_allocd(qhandle, capture);
7872
}
7973
zwlr_screencopy_frame_v1::Event::Damage { .. } => {}
8074
zwlr_screencopy_frame_v1::Event::Buffer { .. } => {}
@@ -114,7 +108,6 @@ impl Dispatch<ZwpLinuxDmabufFeedbackV1, ()> for State<CapWlrScreencopy> {
114108
pub struct CapWlrScreencopy {
115109
screencopy_manager: ZwlrScreencopyManagerV1,
116110
output: WlOutput,
117-
sent_format: bool,
118111
drm_device: Option<PathBuf>,
119112
}
120113
impl CaptureSource for CapWlrScreencopy {
@@ -134,23 +127,19 @@ impl CaptureSource for CapWlrScreencopy {
134127
Ok(Self {
135128
screencopy_manager: man,
136129
output,
137-
sent_format: false,
138130
drm_device: None,
139131
})
140132
}
141133

142-
fn queue_copy_frame(&self, damage: bool, buf: &WlBuffer, capture: &Self::Frame) {
134+
fn queue_copy(&self, damage: bool, buf: &WlBuffer, capture: &Self::Frame) {
143135
if damage {
144136
capture.copy_with_damage(buf);
145137
} else {
146138
capture.copy(buf);
147139
}
148140
}
149141

150-
fn queue_capture_frame(
151-
&self,
152-
eq: &QueueHandle<State<Self>>,
153-
) -> Option<(u32, u32, DrmFourcc, Self::Frame)> {
142+
fn alloc_frame(&self, eq: &QueueHandle<State<Self>>) -> Option<Self::Frame> {
154143
// creating this triggers the linux_dmabuf event, which is where we allocate etc
155144

156145
let _capture = self

0 commit comments

Comments
 (0)