summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2017-11-17 09:51:58 +0100
committerWim Taymans <wtaymans@redhat.com>2017-11-17 09:51:58 +0100
commite774339ffe91cf2af74a9385e0c5b69466abd639 (patch)
treee2327d2d196ac068489dc7a2aa08ac34aea242e2
parentd040747d4b39a75c2169b1f65e75041f6013442a (diff)
v4l2: handle expbuf case
-rw-r--r--spa/tests/test-v4l2.c123
1 files changed, 74 insertions, 49 deletions
diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c
index f6682cce..e8a66ded 100644
--- a/spa/tests/test-v4l2.c
+++ b/spa/tests/test-v4l2.c
@@ -25,6 +25,7 @@
#include <poll.h>
#include <pthread.h>
#include <errno.h>
+#include <sys/mman.h>
#include <SDL2/SDL.h>
@@ -81,11 +82,11 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
struct buffer {
struct spa_buffer buffer;
- struct spa_meta metas[2];
+ struct spa_meta metas[1];
struct spa_meta_header header;
- struct spa_meta_pointer ptr;
struct spa_data datas[1];
struct spa_chunk chunks[1];
+ SDL_Texture *texture;
};
struct data {
@@ -198,26 +199,22 @@ static void on_source_have_output(void *_data)
{
struct data *data = _data;
int res;
- struct spa_buffer *b;
+ struct buffer *b;
void *sdata, *ddata;
int sstride, dstride;
int i;
uint8_t *src, *dst;
- struct spa_meta *metas;
struct spa_data *datas;
struct spa_port_io *io = &data->source_output[0];
handle_events(data);
- b = data->bp[io->buffer_id];
+ b = &data->buffers[io->buffer_id];
- metas = b->metas;
- datas = b->datas;
+ datas = b->buffer.datas;
- if (metas[1].type == data->type.meta.Pointer &&
- ((struct spa_meta_pointer *) metas[1].data)->type == data->type.SDL_Texture) {
- SDL_Texture *texture;
- texture = ((struct spa_meta_pointer *) metas[1].data)->ptr;
+ if (b->texture) {
+ SDL_Texture *texture = b->texture;
SDL_UnlockTexture(texture);
@@ -238,11 +235,24 @@ static void on_source_have_output(void *_data)
spa_ringbuffer_set_avail(&datas[0].chunk->area, sstride * 240);
datas[0].chunk->stride = sstride;
} else {
+ uint8_t *map;
+
if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) {
fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
return;
}
sdata = datas[0].data;
+ if (datas[0].type == data->type.data.MemFd ||
+ datas[0].type == data->type.data.DmaBuf) {
+ map = mmap(NULL, datas[0].maxsize + datas[0].mapoffset, PROT_READ,
+ MAP_PRIVATE, datas[0].fd, 0);
+ sdata = SPA_MEMBER(map, datas[0].mapoffset, uint8_t);
+ } else if (datas[0].type == data->type.data.MemPtr) {
+ map = NULL;
+ sdata = datas[0].data;
+ } else
+ return;
+
sstride = datas[0].chunk->stride;
for (i = 0; i < 240; i++) {
@@ -255,6 +265,9 @@ static void on_source_have_output(void *_data)
SDL_RenderClear(data->renderer);
SDL_RenderCopy(data->renderer, data->texture, NULL, NULL);
SDL_RenderPresent(data->renderer);
+
+ if (map)
+ munmap(map, datas[0].maxsize + datas[0].mapoffset);
}
io->status = SPA_STATUS_NEED_BUFFER;
@@ -324,32 +337,19 @@ static int make_nodes(struct data *data, const char *device)
return res;
}
-static int alloc_buffers(struct data *data)
+static int setup_buffers(struct data *data)
{
int i;
for (i = 0; i < MAX_BUFFERS; i++) {
struct buffer *b = &data->buffers[i];
- SDL_Texture *texture;
- void *ptr;
- int stride;
data->bp[i] = &b->buffer;
- texture = SDL_CreateTexture(data->renderer,
- SDL_PIXELFORMAT_YUY2,
- SDL_TEXTUREACCESS_STREAMING, 320, 240);
- if (!texture) {
- printf("can't create texture: %s\n", SDL_GetError());
- return -ENOMEM;
- }
- if (SDL_LockTexture(texture, NULL, &ptr, &stride) < 0) {
- fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
- return -EIO;
- }
+ b->texture = NULL;
b->buffer.id = i;
- b->buffer.n_metas = 2;
+ b->buffer.n_metas = 1;
b->buffer.metas = b->metas;
b->buffer.n_datas = 1;
b->buffer.datas = b->datas;
@@ -362,26 +362,50 @@ static int alloc_buffers(struct data *data)
b->metas[0].data = &b->header;
b->metas[0].size = sizeof(b->header);
- b->ptr.type = data->type.SDL_Texture;
- b->ptr.ptr = texture;
- b->metas[1].type = data->type.meta.Pointer;
- b->metas[1].data = &b->ptr;
- b->metas[1].size = sizeof(b->ptr);
-
- b->datas[0].type = data->type.data.MemPtr;
+ b->datas[0].type = 0;
b->datas[0].flags = 0;
b->datas[0].fd = -1;
b->datas[0].mapoffset = 0;
+ b->datas[0].maxsize = 0;
+ b->datas[0].data = NULL;
+ b->datas[0].chunk = &b->chunks[0];
+ spa_ringbuffer_set_avail(&b->datas[0].chunk->area, 0);
+ b->datas[0].chunk->stride = 0;
+ }
+ data->n_buffers = MAX_BUFFERS;
+ return 0;
+}
+
+static int sdl_alloc_buffers(struct data *data)
+{
+ int i;
+
+ for (i = 0; i < MAX_BUFFERS; i++) {
+ struct buffer *b = &data->buffers[i];
+ SDL_Texture *texture;
+ void *ptr;
+ int stride;
+
+ texture = SDL_CreateTexture(data->renderer,
+ SDL_PIXELFORMAT_YUY2,
+ SDL_TEXTUREACCESS_STREAMING, 320, 240);
+ if (!texture) {
+ printf("can't create texture: %s\n", SDL_GetError());
+ return -ENOMEM;
+ }
+ if (SDL_LockTexture(texture, NULL, &ptr, &stride) < 0) {
+ fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError());
+ return -EIO;
+ }
+ b->texture = texture;
+
+ b->datas[0].type = data->type.data.MemPtr;
b->datas[0].maxsize = stride * 240;
b->datas[0].data = ptr;
- b->datas[0].chunk = &b->chunks[0];
spa_ringbuffer_set_avail(&b->datas[0].chunk->area, stride * 240);
b->datas[0].chunk->stride = stride;
}
- data->n_buffers = MAX_BUFFERS;
-
- return spa_node_port_use_buffers(data->source, SPA_DIRECTION_OUTPUT, 0, data->bp,
- data->n_buffers);
+ return 0;
}
static int negotiate_formats(struct data *data)
@@ -399,13 +423,6 @@ static int negotiate_formats(struct data *data)
&data->source_output[0])) < 0)
return res;
-#if 0
- void *state = NULL;
-
- if ((res = spa_node_port_enum_formats(data->source, 0, &format, NULL, &state)) <= 0)
- return -EBADF;
-#else
-
format = spa_pod_builder_object(&b,
0, data->type.format,
"I", data->type.media_type.video,
@@ -413,7 +430,6 @@ static int negotiate_formats(struct data *data)
":", data->type.format_video.format, "I", data->type.video_format.YUY2,
":", data->type.format_video.size, "R", &SPA_RECTANGLE(320, 240),
":", data->type.format_video.framerate, "F", &SPA_FRACTION(25,1));
-#endif
if ((res = spa_node_port_set_param(data->source,
SPA_DIRECTION_OUTPUT, 0,
@@ -424,9 +440,18 @@ static int negotiate_formats(struct data *data)
if ((res = spa_node_port_get_info(data->source, SPA_DIRECTION_OUTPUT, 0, &info)) < 0)
return res;
+
+ setup_buffers(data);
+
if (data->use_buffer) {
- if ((res = alloc_buffers(data)) < 0)
+ if ((res = sdl_alloc_buffers(data)) < 0)
return res;
+
+ if ((res = spa_node_port_use_buffers(data->source, SPA_DIRECTION_OUTPUT, 0, data->bp,
+ data->n_buffers)) < 0) {
+ printf("can't allocate buffers: %s\n", spa_strerror(res));
+ return -1;
+ }
} else {
unsigned int n_buffers;
@@ -441,7 +466,7 @@ static int negotiate_formats(struct data *data)
if ((res =
spa_node_port_alloc_buffers(data->source, SPA_DIRECTION_OUTPUT, 0, NULL, 0,
data->bp, &n_buffers)) < 0) {
- printf("can't allocate buffers: %s\n", SDL_GetError());
+ printf("can't allocate buffers: %s\n", spa_strerror(res));
return -1;
}
data->n_buffers = n_buffers;