video: add support for RGBA with 16 and 32 bit float

This commit is contained in:
Wim Taymans 2019-08-19 16:22:12 +02:00
parent 09eb121099
commit edbd9eb077
5 changed files with 38 additions and 7 deletions

View file

@ -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,
};
/**

View file

@ -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 },
};

View file

@ -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',

View file

@ -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,

View file

@ -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;