mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
SDL examples: all SDL operations in one thread
Fix video in SDL examples by invoking rendering in the same thread (pw_loop) that created the window, renderer and texture. At least on some systems, no video is shown without this patch. In those error cases, SDL_RenderPresent triggers an SDL error "The specified window has not been made current". That, in turn, has to do with how SDL uses the current thread for determing the current window. In general, the page linked to below states that the SDL API is not designed to be used from multiple threads. Reference: https://wiki.libsdl.org/CategoryRender
This commit is contained in:
parent
865f671195
commit
0b523e4334
3 changed files with 55 additions and 16 deletions
|
|
@ -441,9 +441,10 @@ static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direc
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_process_input(struct spa_node *node)
|
||||
static int do_render(struct spa_loop *loop, bool async, uint32_t seq,
|
||||
const void *_data, size_t size, void *user_data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct data *d = user_data;
|
||||
struct spa_buffer *buf;
|
||||
uint8_t *map;
|
||||
void *sdata, *ddata;
|
||||
|
|
@ -452,10 +453,10 @@ static int impl_node_process_input(struct spa_node *node)
|
|||
uint8_t *src, *dst;
|
||||
|
||||
if (d->io->status != SPA_STATUS_HAVE_BUFFER)
|
||||
goto done;
|
||||
return 0;
|
||||
|
||||
if (d->io->buffer_id > d->n_buffers)
|
||||
goto done;
|
||||
return 0;
|
||||
|
||||
buf = d->buffers[d->io->buffer_id];
|
||||
|
||||
|
|
@ -493,7 +494,18 @@ static int impl_node_process_input(struct spa_node *node)
|
|||
if (map)
|
||||
munmap(map, buf->datas[0].maxsize + buf->datas[0].mapoffset);
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_process_input(struct spa_node *node)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
int res;
|
||||
|
||||
if ((res = pw_loop_invoke(pw_main_loop_get_loop(d->loop), do_render,
|
||||
SPA_ID_INVALID, NULL, 0, true, d)) < 0)
|
||||
return res;
|
||||
|
||||
handle_events(d);
|
||||
|
||||
return d->io->status = SPA_STATUS_NEED_BUFFER;
|
||||
|
|
|
|||
|
|
@ -390,9 +390,10 @@ static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direc
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_process_input(struct spa_node *node)
|
||||
static int do_render(struct spa_loop *loop, bool async, uint32_t seq,
|
||||
const void *_data, size_t size, void *user_data)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
struct data *d = user_data;
|
||||
struct spa_buffer *buf;
|
||||
uint8_t *map;
|
||||
void *sdata, *ddata;
|
||||
|
|
@ -436,6 +437,18 @@ static int impl_node_process_input(struct spa_node *node)
|
|||
if (map)
|
||||
munmap(map, buf->datas[0].maxsize + buf->datas[0].mapoffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_process_input(struct spa_node *node)
|
||||
{
|
||||
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
|
||||
int res;
|
||||
|
||||
if ((res = pw_loop_invoke(pw_main_loop_get_loop(d->loop), do_render,
|
||||
SPA_ID_INVALID, NULL, 0, true, d)) < 0)
|
||||
return res;
|
||||
|
||||
handle_events(d);
|
||||
|
||||
d->io->status = SPA_STATUS_NEED_BUFFER;
|
||||
|
|
|
|||
|
|
@ -96,20 +96,18 @@ static void handle_events(struct data *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_new_buffer(void *_data, uint32_t id)
|
||||
static int
|
||||
do_render(struct spa_loop *loop, bool async, uint32_t seq,
|
||||
const void *_data, size_t size, void *user_data)
|
||||
{
|
||||
struct data *data = _data;
|
||||
struct pw_stream *stream = data->stream;
|
||||
struct spa_buffer *buf;
|
||||
struct data *data = user_data;
|
||||
struct spa_buffer *buf = ((struct spa_buffer **) _data)[0];
|
||||
uint8_t *map;
|
||||
void *sdata, *ddata;
|
||||
int sstride, dstride, ostride;
|
||||
int i;
|
||||
uint8_t *src, *dst;
|
||||
|
||||
buf = pw_stream_peek_buffer(stream, id);
|
||||
|
||||
if (buf->datas[0].type == data->type.data.MemFd ||
|
||||
buf->datas[0].type == data->type.data.DmaBuf) {
|
||||
map = mmap(NULL, buf->datas[0].maxsize + buf->datas[0].mapoffset, PROT_READ,
|
||||
|
|
@ -119,11 +117,11 @@ on_stream_new_buffer(void *_data, uint32_t id)
|
|||
map = NULL;
|
||||
sdata = buf->datas[0].data;
|
||||
} else
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
|
||||
fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
|
||||
return;
|
||||
return -EIO;
|
||||
}
|
||||
sstride = buf->datas[0].chunk->stride;
|
||||
ostride = SPA_MIN(sstride, dstride);
|
||||
|
|
@ -144,6 +142,22 @@ on_stream_new_buffer(void *_data, uint32_t id)
|
|||
if (map)
|
||||
munmap(map, buf->datas[0].maxsize + buf->datas[0].mapoffset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_new_buffer(void *_data, uint32_t id)
|
||||
{
|
||||
struct data *data = _data;
|
||||
struct pw_stream *stream = data->stream;
|
||||
struct spa_buffer *buf;
|
||||
|
||||
buf = pw_stream_peek_buffer(stream, id);
|
||||
|
||||
pw_loop_invoke(pw_main_loop_get_loop(data->loop), do_render,
|
||||
SPA_ID_INVALID, &buf, sizeof(struct spa_buffer *),
|
||||
true, data);
|
||||
|
||||
pw_stream_recycle_buffer(stream, id);
|
||||
|
||||
handle_events(data);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue