From edbd9eb0776c263ee0888a1b4e1e47b319666387 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 19 Aug 2019 16:22:12 +0200 Subject: [PATCH] video: add support for RGBA with 16 and 32 bit float --- spa/include/spa/param/video/raw.h | 4 +++ spa/include/spa/param/video/type-info.h | 2 ++ src/examples/meson.build | 2 +- src/examples/sdl.h | 1 + src/examples/video-play.c | 36 ++++++++++++++++++++----- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/spa/include/spa/param/video/raw.h b/spa/include/spa/param/video/raw.h index 096737df9..6da244f93 100644 --- a/spa/include/spa/param/video/raw.h +++ b/spa/include/spa/param/video/raw.h @@ -40,6 +40,7 @@ extern "C" { enum spa_video_format { SPA_VIDEO_FORMAT_UNKNOWN, SPA_VIDEO_FORMAT_ENCODED, + SPA_VIDEO_FORMAT_I420, SPA_VIDEO_FORMAT_YV12, SPA_VIDEO_FORMAT_YUY2, @@ -116,6 +117,9 @@ enum spa_video_format { SPA_VIDEO_FORMAT_I422_12LE, SPA_VIDEO_FORMAT_Y444_12BE, SPA_VIDEO_FORMAT_Y444_12LE, + + SPA_VIDEO_FORMAT_RGBA_F16, + SPA_VIDEO_FORMAT_RGBA_F32, }; /** diff --git a/spa/include/spa/param/video/type-info.h b/spa/include/spa/param/video/type-info.h index 22a4e2313..f0648a9bd 100644 --- a/spa/include/spa/param/video/type-info.h +++ b/spa/include/spa/param/video/type-info.h @@ -112,6 +112,8 @@ static const struct spa_type_info spa_type_video_format[] = { { SPA_VIDEO_FORMAT_I422_12LE, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "I422_12LE", NULL }, { SPA_VIDEO_FORMAT_Y444_12BE, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "Y444_12BE", NULL }, { SPA_VIDEO_FORMAT_Y444_12LE, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "Y444_12LE", NULL }, + { SPA_VIDEO_FORMAT_RGBA_F16, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "RGBA_F16", NULL }, + { SPA_VIDEO_FORMAT_RGBA_F32, SPA_TYPE_Int, SPA_TYPE_INFO_VIDEO_FORMAT_BASE "RGBA_F32", NULL }, { 0, 0, NULL, NULL }, }; diff --git a/src/examples/meson.build b/src/examples/meson.build index 1786e1c7d..ad34274d9 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -56,7 +56,7 @@ if sdl_dep.found() 'video-play.c', c_args : [ '-D_GNU_SOURCE' ], install: false, - dependencies : [pipewire_dep, sdl_dep], + dependencies : [pipewire_dep, sdl_dep, mathlib], ) executable('local-v4l2', 'local-v4l2.c', diff --git a/src/examples/sdl.h b/src/examples/sdl.h index 39c0e7f1f..c4cdb0dfa 100644 --- a/src/examples/sdl.h +++ b/src/examples/sdl.h @@ -132,6 +132,7 @@ static struct spa_pod *sdl_build_formats(SDL_RendererInfo *info, struct spa_pod_ if (id != SPA_VIDEO_FORMAT_UNKNOWN) spa_pod_builder_id(b, id); } + spa_pod_builder_id(b, SPA_VIDEO_FORMAT_RGBA_F32); spa_pod_builder_pop(b, &f[1]); /* add size and framerate ranges */ spa_pod_builder_add(b, diff --git a/src/examples/video-play.c b/src/examples/video-play.c index 7708ab61c..a5fb1f43a 100644 --- a/src/examples/video-play.c +++ b/src/examples/video-play.c @@ -40,6 +40,10 @@ #include "sdl.h" +struct pixel { + float r, g, b, a; +}; + struct data { const char *path; @@ -93,7 +97,7 @@ on_process(void *_data) int sstride, dstride, ostride; struct spa_meta_region *mc; struct spa_meta_cursor *mcs; - uint32_t i; + uint32_t i, j; uint8_t *src, *dst; bool render_cursor = false; @@ -172,10 +176,26 @@ on_process(void *_data) src = sdata; dst = ddata; - for (i = 0; i < data->format.size.height; i++) { - memcpy(dst, src, ostride); - src += sstride; - dst += dstride; + + if (data->format.format == SPA_VIDEO_FORMAT_RGBA_F32) { + for (i = 0; i < data->format.size.height; i++) { + struct pixel *p = (struct pixel *) src; + for (j = 0; j < data->format.size.width; j++) { + dst[j * 4 + 0] = SPA_CLAMP(lrintf(p[j].r * 255.0f), 0, 255); + dst[j * 4 + 1] = SPA_CLAMP(lrintf(p[j].g * 255.0f), 0, 255); + dst[j * 4 + 2] = SPA_CLAMP(lrintf(p[j].b * 255.0f), 0, 255); + dst[j * 4 + 3] = SPA_CLAMP(lrintf(p[j].a * 255.0f), 0, 255); + } + src += sstride; + dst += dstride; + } + } + else { + for (i = 0; i < data->format.size.height; i++) { + memcpy(dst, src, ostride); + src += sstride; + dst += dstride; + } } SDL_UnlockTexture(data->texture); @@ -242,7 +262,11 @@ on_stream_format_changed(void *_data, const struct spa_pod *format) /* call a helper function to parse the format for us. */ spa_format_video_raw_parse(format, &data->format); - sdl_format = id_to_sdl_format(data->format.format); + if (data->format.format == SPA_VIDEO_FORMAT_RGBA_F32) + sdl_format = SDL_PIXELFORMAT_RGBA32; + else + sdl_format = id_to_sdl_format(data->format.format); + if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) { pw_stream_finish_format(stream, -EINVAL, NULL, 0); return;