mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
u/sink: Add Bayer format converter
This commit is contained in:
parent
5b6e6bf6a6
commit
eec3446e5b
1
doc/changes/auxiliary/mr.665.md
Normal file
1
doc/changes/auxiliary/mr.665.md
Normal file
|
@ -0,0 +1 @@
|
|||
u/sink: Add Bayer format converter.
|
|
@ -44,6 +44,15 @@ u_sink_create_to_r8g8b8_or_l8(struct xrt_frame_context *xfctx,
|
|||
struct xrt_frame_sink *downstream,
|
||||
struct xrt_frame_sink **out_xfs);
|
||||
|
||||
/*!
|
||||
* @relatesalso xrt_frame_sink
|
||||
* @relates xrt_frame_context
|
||||
*/
|
||||
void
|
||||
u_sink_create_to_r8g8b8_bayer_or_l8(struct xrt_frame_context *xfctx,
|
||||
struct xrt_frame_sink *downstream,
|
||||
struct xrt_frame_sink **out_xfs);
|
||||
|
||||
/*!
|
||||
* @relatesalso xrt_frame_sink
|
||||
* @relates xrt_frame_context
|
||||
|
|
|
@ -341,6 +341,44 @@ from_MJPEG_to_YUV888(struct xrt_frame *dst_frame, size_t size, const uint8_t *da
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Bayer
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
from_BAYER_GR8_to_R8G8B8(struct xrt_frame *dst_frame, uint32_t w, uint32_t h, size_t stride, const uint8_t *data)
|
||||
{
|
||||
const uint8_t *src_data = data;
|
||||
uint32_t src_stride = stride;
|
||||
|
||||
uint8_t *dst_data = dst_frame->data;
|
||||
uint32_t dst_stride = dst_frame->stride;
|
||||
|
||||
for (uint32_t y = 0; y < h; y++) {
|
||||
const uint8_t *src0 = src_data + (y * 2) * src_stride;
|
||||
const uint8_t *src1 = src_data + (y * 2 + 1) * src_stride;
|
||||
uint8_t *dst = dst_data + (y * dst_stride);
|
||||
|
||||
for (uint32_t x = 0; x < w; x++) {
|
||||
uint8_t g0 = src0[0];
|
||||
uint8_t r = src0[1];
|
||||
uint8_t b = src1[0];
|
||||
uint8_t g1 = src1[1];
|
||||
|
||||
dst[0] = r;
|
||||
dst[1] = (g0 + g1) / 2;
|
||||
dst[2] = b;
|
||||
|
||||
src0 += 2;
|
||||
src1 += 2;
|
||||
dst += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Misc functions.
|
||||
|
@ -349,15 +387,16 @@ from_MJPEG_to_YUV888(struct xrt_frame *dst_frame, size_t size, const uint8_t *da
|
|||
|
||||
|
||||
/*!
|
||||
* Creates a frame that the conversion should happen to.
|
||||
* Creates a frame that the conversion should happen to, allows to set the size.
|
||||
*
|
||||
* @todo Allocate from a pool of frames.
|
||||
*/
|
||||
static bool
|
||||
create_frame_with_format(struct xrt_frame *xf, enum xrt_format format, struct xrt_frame **out_frame)
|
||||
create_frame_with_format_of_size(
|
||||
struct xrt_frame *xf, uint32_t w, uint32_t h, enum xrt_format format, struct xrt_frame **out_frame)
|
||||
{
|
||||
struct xrt_frame *frame = NULL;
|
||||
u_frame_create_one_off(format, xf->width, xf->height, &frame);
|
||||
u_frame_create_one_off(format, w, h, &frame);
|
||||
if (frame == NULL) {
|
||||
U_LOG_E("Failed to create target frame!");
|
||||
*out_frame = NULL;
|
||||
|
@ -375,6 +414,15 @@ create_frame_with_format(struct xrt_frame *xf, enum xrt_format format, struct xr
|
|||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a frame that the conversion should happen to.
|
||||
*/
|
||||
static bool
|
||||
create_frame_with_format(struct xrt_frame *xf, enum xrt_format format, struct xrt_frame **out_frame)
|
||||
{
|
||||
return create_frame_with_format_of_size(xf, xf->width, xf->height, format, out_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_frame_r8g8b8_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
||||
{
|
||||
|
@ -385,6 +433,62 @@ receive_frame_r8g8b8_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
|||
switch (xf->format) {
|
||||
case XRT_FORMAT_L8:
|
||||
case XRT_FORMAT_R8G8B8: s->downstream->push_frame(s->downstream, xf); return;
|
||||
case XRT_FORMAT_BAYER_GR8:;
|
||||
uint32_t w = xf->width / 2;
|
||||
uint32_t h = xf->height / 2;
|
||||
if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data);
|
||||
break;
|
||||
case XRT_FORMAT_YUYV422:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
from_YUYV422_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data);
|
||||
break;
|
||||
case XRT_FORMAT_UYVY422:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
from_UYVY422_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data);
|
||||
break;
|
||||
case XRT_FORMAT_YUV888:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
from_YUV888_to_R8G8B8(converted, xf->width, xf->height, xf->stride, xf->data);
|
||||
break;
|
||||
#ifdef XRT_HAVE_JPEG
|
||||
case XRT_FORMAT_MJPEG:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
if (!from_MJPEG_to_R8G8B8(converted, xf->size, xf->data)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: U_LOG_E("Can not convert from '%s' to R8G8B8 or L8!", u_format_str(xf->format)); return;
|
||||
}
|
||||
|
||||
s->downstream->push_frame(s->downstream, converted);
|
||||
|
||||
// Refcount in case it's being held downstream.
|
||||
xrt_frame_reference(&converted, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_frame_r8g8b8_bayer_or_l8(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
||||
{
|
||||
struct u_sink_converter *s = (struct u_sink_converter *)xs;
|
||||
|
||||
struct xrt_frame *converted = NULL;
|
||||
|
||||
switch (xf->format) {
|
||||
case XRT_FORMAT_L8:
|
||||
case XRT_FORMAT_R8G8B8:
|
||||
case XRT_FORMAT_BAYER_GR8:; s->downstream->push_frame(s->downstream, xf); return;
|
||||
case XRT_FORMAT_YUYV422:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
|
@ -431,6 +535,14 @@ receive_frame_r8g8b8(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
|||
|
||||
switch (xf->format) {
|
||||
case XRT_FORMAT_R8G8B8: s->downstream->push_frame(s->downstream, xf); return;
|
||||
case XRT_FORMAT_BAYER_GR8:;
|
||||
uint32_t w = xf->width / 2;
|
||||
uint32_t h = xf->height / 2;
|
||||
if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data);
|
||||
break;
|
||||
case XRT_FORMAT_YUYV422:
|
||||
if (!create_frame_with_format(xf, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
|
@ -533,6 +645,27 @@ receive_frame_yuv_or_yuyv(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
|||
xrt_frame_reference(&converted, NULL);
|
||||
}
|
||||
|
||||
XRT_MAYBE_UNUSED static void
|
||||
receive_frame_bayer(struct xrt_frame_sink *xs, struct xrt_frame *xf)
|
||||
{
|
||||
struct u_sink_converter *s = (struct u_sink_converter *)xs;
|
||||
|
||||
uint32_t w = xf->width / 2;
|
||||
uint32_t h = xf->height / 2;
|
||||
struct xrt_frame *converted = NULL;
|
||||
|
||||
if (!create_frame_with_format_of_size(xf, w, h, XRT_FORMAT_R8G8B8, &converted)) {
|
||||
return;
|
||||
}
|
||||
|
||||
from_BAYER_GR8_to_R8G8B8(converted, w, h, xf->stride, xf->data);
|
||||
|
||||
s->downstream->push_frame(s->downstream, converted);
|
||||
|
||||
// Refcount in case it's being held downstream.
|
||||
xrt_frame_reference(&converted, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
break_apart(struct xrt_frame_node *node)
|
||||
{}
|
||||
|
@ -598,6 +731,23 @@ u_sink_create_to_r8g8b8_or_l8(struct xrt_frame_context *xfctx,
|
|||
*out_xfs = &s->base;
|
||||
}
|
||||
|
||||
void
|
||||
u_sink_create_to_r8g8b8_bayer_or_l8(struct xrt_frame_context *xfctx,
|
||||
struct xrt_frame_sink *downstream,
|
||||
struct xrt_frame_sink **out_xfs)
|
||||
{
|
||||
struct u_sink_converter *s = U_TYPED_CALLOC(struct u_sink_converter);
|
||||
s->base.push_frame = receive_frame_r8g8b8_bayer_or_l8;
|
||||
s->node.break_apart = break_apart;
|
||||
s->node.destroy = destroy;
|
||||
s->downstream = downstream;
|
||||
|
||||
xrt_frame_context_add(xfctx, &s->node);
|
||||
|
||||
*out_xfs = &s->base;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
u_sink_create_to_yuv_yuyv_uyvy_or_l8(struct xrt_frame_context *xfctx,
|
||||
struct xrt_frame_sink *downstream,
|
||||
|
|
Loading…
Reference in a new issue