pw_utils: Fill dmabuf strides and offsets at add_buffer()

As far as I understand, these don't change.
This commit is contained in:
Ivan Molodetskikh
2025-08-03 13:29:48 +03:00
parent 43577f4d97
commit 15b4acc17e
+37 -55
View File
@@ -611,11 +611,15 @@ impl PipeWire {
let plane_count = dmabuf.num_planes();
assert_eq!((*spa_buffer).n_datas as usize, plane_count);
for (i, fd) in dmabuf.handles().enumerate() {
for (i, (fd, (stride, offset))) in
zip(dmabuf.handles(), zip(dmabuf.strides(), dmabuf.offsets()))
.enumerate()
{
let spa_data = (*spa_buffer).datas.add(i);
assert!((*spa_data).type_ & (1 << DataType::DmaBuf.as_raw()) > 0);
(*spa_data).type_ = DataType::DmaBuf.as_raw();
// With DMA-BUFs, consumers should ignore the maxsize field, and
// producers are allowed to set it to 0.
//
@@ -623,6 +627,15 @@ impl PipeWire {
(*spa_data).maxsize = 1;
(*spa_data).fd = fd.as_raw_fd() as i64;
(*spa_data).flags = SPA_DATA_FLAG_READWRITE;
let chunk = (*spa_data).chunk;
(*chunk).stride = stride as i32;
(*chunk).offset = offset;
trace!(
"pw buffer plane: fd={}, stride={stride}, offset={offset}",
(*spa_data).fd
);
}
let fd = (*(*spa_buffer).datas).fd;
@@ -881,16 +894,15 @@ impl Cast {
};
let buffer = pw_buffer.as_ptr();
let inner = self.inner.borrow_mut();
unsafe {
let spa_buffer = (*buffer).buffer;
let fd = (*(*spa_buffer).datas).fd;
let dmabuf = &inner.dmabufs[&fd];
let dmabuf = self.inner.borrow().dmabufs[&fd].clone();
match render_to_dmabuf(
renderer,
dmabuf.clone(),
dmabuf,
size,
scale,
Transform::Normal,
@@ -912,30 +924,7 @@ impl Cast {
}
}
for (i, (stride, offset)) in zip(dmabuf.strides(), dmabuf.offsets()).enumerate() {
let spa_data = (*spa_buffer).datas.add(i);
let chunk = (*spa_data).chunk;
// With DMA-BUFs, consumers should ignore the size field, and producers are allowed
// to set it to 0.
//
// https://docs.pipewire.org/page_dma_buf.html
//
// However, OBS checks for size != 0 as a workaround for old compositor versions,
// so we set it to 1.
(*chunk).size = 1;
// Clear the corrupted flag we may have set before.
(*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
(*chunk).stride = stride as i32;
(*chunk).offset = offset;
trace!(
"pw buffer: fd = {}, stride = {stride}, offset = {offset}",
(*spa_data).fd
);
}
mark_buffer_as_good(pw_buffer);
pw_stream_queue_buffer(self.stream.as_raw_ptr(), buffer);
}
@@ -961,14 +950,13 @@ impl Cast {
};
let buffer = pw_buffer.as_ptr();
let inner = self.inner.borrow_mut();
unsafe {
let spa_buffer = (*buffer).buffer;
let fd = (*(*spa_buffer).datas).fd;
let dmabuf = &inner.dmabufs[&fd];
let dmabuf = self.inner.borrow().dmabufs[&fd].clone();
match clear_dmabuf(renderer, dmabuf.clone()) {
match clear_dmabuf(renderer, dmabuf) {
Ok(sync_point) => {
// FIXME: implement PipeWire explicit sync, and at the very least async wait.
if wait_for_sync {
@@ -985,30 +973,7 @@ impl Cast {
}
}
for (i, (stride, offset)) in zip(dmabuf.strides(), dmabuf.offsets()).enumerate() {
let spa_data = (*spa_buffer).datas.add(i);
let chunk = (*spa_data).chunk;
// With DMA-BUFs, consumers should ignore the size field, and producers are allowed
// to set it to 0.
//
// https://docs.pipewire.org/page_dma_buf.html
//
// However, OBS checks for size != 0 as a workaround for old compositor versions,
// so we set it to 1.
(*chunk).size = 1;
// Clear the corrupted flag we may have set before.
(*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
(*chunk).stride = stride as i32;
(*chunk).offset = offset;
trace!(
"pw buffer: fd = {}, stride = {stride}, offset = {offset}",
(*spa_data).fd
);
}
mark_buffer_as_good(pw_buffer);
pw_stream_queue_buffer(self.stream.as_raw_ptr(), buffer);
}
@@ -1194,3 +1159,20 @@ unsafe fn return_unused_buffer(stream: &Stream, pw_buffer: NonNull<pw_buffer>) {
(*chunk).flags = SPA_CHUNK_FLAG_CORRUPTED as i32;
pw_stream_queue_buffer(stream.as_raw_ptr(), pw_buffer);
}
unsafe fn mark_buffer_as_good(pw_buffer: NonNull<pw_buffer>) {
let pw_buffer = pw_buffer.as_ptr();
let spa_buffer = (*pw_buffer).buffer;
let chunk = (*(*spa_buffer).datas).chunk;
// With DMA-BUFs, consumers should ignore the size field, and producers are allowed
// to set it to 0.
//
// https://docs.pipewire.org/page_dma_buf.html
//
// However, OBS checks for size != 0 as a workaround for old compositor versions,
// so we set it to 1.
(*chunk).size = 1;
// Clear the corrupted flag we may have set before.
(*chunk).flags = SPA_CHUNK_FLAG_NONE as i32;
}