examples: Make fixate examples optionally stream DMA buffers

The video-play-fixate example will downgrade the stream to MemFd one
modifier at a time. Sometimes it's useful to test with not downgrading;
to avoid having to depend on actual DRM devices (real or virtual), fake
them by using memfd and mapping them in the sink.
This commit is contained in:
Jonas Ådahl 2025-11-11 21:06:17 +01:00 committed by Wim Taymans
parent fc5b43a0b0
commit 5481a235ed
2 changed files with 29 additions and 17 deletions

View file

@ -13,6 +13,7 @@
#include <unistd.h>
#include <signal.h>
#include <libdrm/drm_fourcc.h>
#include <sys/mman.h>
#include <spa/utils/result.h>
#include <spa/param/video/format-utils.h>
@ -22,6 +23,9 @@
#include <pipewire/pipewire.h>
/* If defined, emulate failing to import DMA buffer. */
#define EMULATE_DMA_BUF_IMPORT_FAIL 1
#define WIDTH 640
#define HEIGHT 480
#define RATE 30
@ -197,10 +201,12 @@ on_process(void *_data)
struct pw_stream *stream = data->stream;
struct pw_buffer *b;
struct spa_buffer *buf;
struct spa_data *d;
void *sdata, *ddata;
int sstride, dstride, ostride;
uint32_t i;
uint8_t *src, *dst;
bool needs_unmap = false;
b = NULL;
/* dequeue and queue old buffers, use the last available
@ -219,11 +225,13 @@ on_process(void *_data)
}
buf = b->buffer;
d = buf->datas;
pw_log_info("new buffer %p", buf);
handle_events(data);
#ifdef EMULATE_DMA_BUF_IMPORT_FAIL
if (buf->datas[0].type == SPA_DATA_DmaBuf) {
// Simulate a failed import of a DmaBuf
// We should try another modifier
@ -232,8 +240,17 @@ on_process(void *_data)
pw_loop_signal_event(pw_main_loop_get_loop(data->loop), data->reneg);
goto done;
}
#endif
if ((sdata = buf->datas[0].data) == NULL)
if (buf->datas[0].type == SPA_DATA_DmaBuf) {
sdata = mmap(NULL, d[0].maxsize, PROT_READ,
MAP_SHARED, d[0].fd, d[0].mapoffset);
needs_unmap = true;
} else {
sdata = buf->datas[0].data;
}
if (sdata == NULL)
goto done;
if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
@ -263,6 +280,8 @@ on_process(void *_data)
SDL_RenderPresent(data->renderer);
done:
if (needs_unmap)
munmap(d[0].data, d[0].maxsize);
pw_stream_queue_buffer(stream, b);
}

View file

@ -304,26 +304,19 @@ static void on_stream_add_buffer(void *_data, struct pw_buffer *buffer)
#else
d[0].fd = -1;
#endif
d[0].data = NULL;
return;
}
if ((d[0].type & (1<<SPA_DATA_MemFd)) == 0) {
pw_log_error("unsupported data type %08x", d[0].type);
return;
}
printf("use memfd\n");
/* create the memfd on the buffer, set the type and flags */
d[0].type = SPA_DATA_MemFd;
d[0].flags = SPA_DATA_FLAG_READWRITE | SPA_DATA_FLAG_MAPPABLE;
} else {
printf("use memfd\n");
/* create the memfd on the buffer, set the type and flags */
d[0].type = SPA_DATA_MemFd;
d[0].flags = SPA_DATA_FLAG_READWRITE | SPA_DATA_FLAG_MAPPABLE;
#ifdef HAVE_MEMFD_CREATE
d[0].fd = memfd_create("video-src-fixate-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
d[0].fd = memfd_create("video-src-fixate-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
#else
d[0].fd = -1;
d[0].fd = -1;
#endif
}
if (d[0].fd == -1) {
pw_log_error("can't create memfd: %m");
pw_log_error("can't open file descriptor: %m");
return;
}
d[0].mapoffset = 0;