Added colorspace to SDL_CameraSpec

This commit is contained in:
Sam Lantinga
2024-06-12 11:18:26 -07:00
parent 98499d6818
commit aeea819494
10 changed files with 407 additions and 167 deletions

View File

@@ -357,55 +357,60 @@ static void param_update(struct spa_list *param_list, struct spa_list *pending_l
}
static struct sdl_video_format {
Uint32 format;
uint32_t id;
SDL_PixelFormatEnum format;
SDL_Colorspace colorspace;
uint32_t id;
} sdl_video_formats[] = {
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
{ SDL_PIXELFORMAT_RGBX8888, SPA_VIDEO_FORMAT_RGBx,},
{ SDL_PIXELFORMAT_BGRX8888, SPA_VIDEO_FORMAT_BGRx,},
{ SDL_PIXELFORMAT_RGBA8888, SPA_VIDEO_FORMAT_RGBA,},
{ SDL_PIXELFORMAT_ARGB8888, SPA_VIDEO_FORMAT_ARGB,},
{ SDL_PIXELFORMAT_BGRA8888, SPA_VIDEO_FORMAT_BGRA,},
{ SDL_PIXELFORMAT_ABGR8888, SPA_VIDEO_FORMAT_ABGR,},
{ SDL_PIXELFORMAT_RGBX8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_RGBx },
{ SDL_PIXELFORMAT_BGRX8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_BGRx },
{ SDL_PIXELFORMAT_RGBA8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_RGBA },
{ SDL_PIXELFORMAT_ARGB8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_ARGB },
{ SDL_PIXELFORMAT_BGRA8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_BGRA },
{ SDL_PIXELFORMAT_ABGR8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_ABGR },
#else
{ SDL_PIXELFORMAT_RGBX8888, SPA_VIDEO_FORMAT_xBGR,},
{ SDL_PIXELFORMAT_BGRX8888, SPA_VIDEO_FORMAT_xRGB,},
{ SDL_PIXELFORMAT_RGBA8888, SPA_VIDEO_FORMAT_ABGR,},
{ SDL_PIXELFORMAT_ARGB8888, SPA_VIDEO_FORMAT_BGRA,},
{ SDL_PIXELFORMAT_BGRA8888, SPA_VIDEO_FORMAT_ARGB,},
{ SDL_PIXELFORMAT_ABGR8888, SPA_VIDEO_FORMAT_RGBA,},
{ SDL_PIXELFORMAT_RGBX8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_xBGR },
{ SDL_PIXELFORMAT_BGRX8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_xRGB },
{ SDL_PIXELFORMAT_RGBA8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_ABGR },
{ SDL_PIXELFORMAT_ARGB8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_BGRA },
{ SDL_PIXELFORMAT_BGRA8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_ARGB },
{ SDL_PIXELFORMAT_ABGR8888, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_RGBA },
#endif
{ SDL_PIXELFORMAT_RGB24, SPA_VIDEO_FORMAT_RGB,},
{ SDL_PIXELFORMAT_BGR24, SPA_VIDEO_FORMAT_BGR,},
{ SDL_PIXELFORMAT_YV12, SPA_VIDEO_FORMAT_YV12,},
{ SDL_PIXELFORMAT_IYUV, SPA_VIDEO_FORMAT_I420,},
{ SDL_PIXELFORMAT_YUY2, SPA_VIDEO_FORMAT_YUY2,},
{ SDL_PIXELFORMAT_UYVY, SPA_VIDEO_FORMAT_UYVY,},
{ SDL_PIXELFORMAT_YVYU, SPA_VIDEO_FORMAT_YVYU,},
{ SDL_PIXELFORMAT_RGB24, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_RGB },
{ SDL_PIXELFORMAT_BGR24, SDL_COLORSPACE_SRGB, SPA_VIDEO_FORMAT_BGR },
{ SDL_PIXELFORMAT_YV12, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_YV12 },
{ SDL_PIXELFORMAT_IYUV, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_I420 },
{ SDL_PIXELFORMAT_YUY2, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_YUY2 },
{ SDL_PIXELFORMAT_UYVY, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_UYVY },
{ SDL_PIXELFORMAT_YVYU, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_YVYU },
#if SDL_VERSION_ATLEAST(2,0,4)
{ SDL_PIXELFORMAT_NV12, SPA_VIDEO_FORMAT_NV12,},
{ SDL_PIXELFORMAT_NV21, SPA_VIDEO_FORMAT_NV21,},
{ SDL_PIXELFORMAT_NV12, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_NV12 },
{ SDL_PIXELFORMAT_NV21, SDL_COLORSPACE_BT709_LIMITED, SPA_VIDEO_FORMAT_NV21 },
#endif
};
static inline uint32_t sdl_format_to_id(Uint32 format)
static uint32_t sdl_format_to_id(SDL_PixelFormatEnum format)
{
struct sdl_video_format *f;
SPA_FOR_EACH_ELEMENT(sdl_video_formats, f) {
if (f->format == format)
return f->id;
}
return SPA_VIDEO_FORMAT_UNKNOWN;
struct sdl_video_format *f;
SPA_FOR_EACH_ELEMENT(sdl_video_formats, f) {
if (f->format == format)
return f->id;
}
return SPA_VIDEO_FORMAT_UNKNOWN;
}
static inline Uint32 id_to_sdl_format(uint32_t id)
static void id_to_sdl_format(uint32_t id, SDL_PixelFormatEnum *format, SDL_Colorspace *colorspace)
{
struct sdl_video_format *f;
SPA_FOR_EACH_ELEMENT(sdl_video_formats, f) {
if (f->id == id)
return f->format;
}
return SDL_PIXELFORMAT_UNKNOWN;
struct sdl_video_format *f;
SPA_FOR_EACH_ELEMENT(sdl_video_formats, f) {
if (f->id == id) {
*format = f->format;
*colorspace = f->colorspace;
return;
}
}
*format = SDL_PIXELFORMAT_UNKNOWN;
*colorspace = SDL_COLORSPACE_UNKNOWN;
}
struct SDL_PrivateCameraData
@@ -592,14 +597,13 @@ static void PIPEWIRECAMERA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *f
pw_array_for_each(p, &device->hidden->buffers) {
if ((*p)->buffer->datas[0].data == frame->pixels) {
PIPEWIRE_pw_stream_queue_buffer(device->hidden->stream, (*p));
break;
break;
}
}
PIPEWIRE_pw_thread_loop_unlock(hotplug.loop);
}
static void collect_rates(CameraFormatAddData *data, struct param *p, const Uint32 sdlfmt,
const struct spa_rectangle *size)
static void collect_rates(CameraFormatAddData *data, struct param *p, SDL_PixelFormatEnum sdlfmt, SDL_Colorspace colorspace, const struct spa_rectangle *size)
{
const struct spa_pod_prop *prop;
struct spa_pod * values;
@@ -618,23 +622,22 @@ static void collect_rates(CameraFormatAddData *data, struct param *p, const Uint
switch (choice) {
case SPA_CHOICE_None:
n_vals = 1;
SPA_FALLTHROUGH;
SPA_FALLTHROUGH;
case SPA_CHOICE_Enum:
for (i = 0; i < n_vals; i++) {
for (i = 0; i < n_vals; i++) {
// denom and num are switched, because SDL expects an interval, while pw provides a rate
if (SDL_AddCameraFormat(data, sdlfmt, size->width, size->height,
rates[i].denom, rates[i].num) == -1) {
if (SDL_AddCameraFormat(data, sdlfmt, colorspace, size->width, size->height, rates[i].denom, rates[i].num) < 0) {
return; // Probably out of memory; we'll go with what we have, if anything.
}
}
break;
}
break;
default:
SDL_Log("CAMERA: unimplemented choice:%d", choice);
break;
break;
}
}
static void collect_size(CameraFormatAddData *data, struct param *p, const Uint32 sdlfmt)
static void collect_size(CameraFormatAddData *data, struct param *p, SDL_PixelFormatEnum sdlfmt, SDL_Colorspace colorspace)
{
const struct spa_pod_prop *prop;
struct spa_pod * values;
@@ -653,22 +656,23 @@ static void collect_size(CameraFormatAddData *data, struct param *p, const Uint3
switch (choice) {
case SPA_CHOICE_None:
n_vals = 1;
SPA_FALLTHROUGH;
SPA_FALLTHROUGH;
case SPA_CHOICE_Enum:
for (i = 0; i < n_vals; i++) {
collect_rates(data, p, sdlfmt, &rectangles[i]);
}
break;
for (i = 0; i < n_vals; i++) {
collect_rates(data, p, sdlfmt, colorspace, &rectangles[i]);
}
break;
default:
SDL_Log("CAMERA: unimplemented choice:%d", choice);
break;
break;
}
}
static void collect_format(CameraFormatAddData *data, struct param *p)
{
const struct spa_pod_prop *prop;
Uint32 sdlfmt;
SDL_PixelFormatEnum sdlfmt;
SDL_Colorspace colorspace;
struct spa_pod * values;
uint32_t i, n_vals, choice, *ids;
@@ -686,16 +690,17 @@ static void collect_format(CameraFormatAddData *data, struct param *p)
n_vals = 1;
SPA_FALLTHROUGH;
case SPA_CHOICE_Enum:
for (i = 0; i < n_vals; i++) {
sdlfmt = id_to_sdl_format(ids[i]);
if (sdlfmt == SDL_PIXELFORMAT_UNKNOWN)
for (i = 0; i < n_vals; i++) {
id_to_sdl_format(ids[i], &sdlfmt, &colorspace);
if (sdlfmt == SDL_PIXELFORMAT_UNKNOWN) {
continue;
collect_size(data, p, sdlfmt);
}
break;
}
collect_size(data, p, sdlfmt, colorspace);
}
break;
default:
SDL_Log("CAMERA: unimplemented choice:%d", choice);
break;
break;
}
}
@@ -710,7 +715,7 @@ static void add_device(struct global *g)
if (p->id != SPA_PARAM_EnumFormat)
continue;
collect_format(&data, p);
collect_format(&data, p);
}
if (data.num_specs > 0) {
SDL_AddCameraDevice(g->name, SDL_CAMERA_POSITION_UNKNOWN,