mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
compositor: Calculate background color only once
... instead of do that per fill_color() call in case of RGB format. Moreover, respect selected GstVideoColorRange Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1486>
This commit is contained in:
parent
8fee6bf785
commit
64eb4b8d62
3 changed files with 54 additions and 56 deletions
|
@ -219,15 +219,10 @@ A32_CHECKER_C (bgra, TRUE, 3, 2, 1, 0);
|
|||
A32_CHECKER_C (ayuv, FALSE, 0, 1, 2, 3);
|
||||
A32_CHECKER_C (vuya, FALSE, 3, 2, 1, 0);
|
||||
|
||||
#define YUV_TO_R(Y,U,V) (CLAMP (1.164 * (Y - 16) + 1.596 * (V - 128), 0, 255))
|
||||
#define YUV_TO_G(Y,U,V) (CLAMP (1.164 * (Y - 16) - 0.813 * (V - 128) - 0.391 * (U - 128), 0, 255))
|
||||
#define YUV_TO_B(Y,U,V) (CLAMP (1.164 * (Y - 16) + 2.018 * (U - 128), 0, 255))
|
||||
|
||||
#define A32_COLOR(name, RGB, A, C1, C2, C3) \
|
||||
#define A32_COLOR(name, A, C1, C2, C3) \
|
||||
static void \
|
||||
fill_color_##name (GstVideoFrame * frame, guint y_start, guint y_end, gint Y, gint U, gint V) \
|
||||
fill_color_##name (GstVideoFrame * frame, guint y_start, guint y_end, gint c1, gint c2, gint c3) \
|
||||
{ \
|
||||
gint c1, c2, c3; \
|
||||
guint32 val; \
|
||||
gint stride; \
|
||||
guint8 *dest; \
|
||||
|
@ -236,26 +231,17 @@ fill_color_##name (GstVideoFrame * frame, guint y_start, guint y_end, gint Y, gi
|
|||
stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
|
||||
\
|
||||
dest += y_start * stride; \
|
||||
if (RGB) { \
|
||||
c1 = YUV_TO_R (Y, U, V); \
|
||||
c2 = YUV_TO_G (Y, U, V); \
|
||||
c3 = YUV_TO_B (Y, U, V); \
|
||||
} else { \
|
||||
c1 = Y; \
|
||||
c2 = U; \
|
||||
c3 = V; \
|
||||
} \
|
||||
val = GUINT32_FROM_BE ((0xff << A) | (c1 << C1) | (c2 << C2) | (c3 << C3)); \
|
||||
\
|
||||
compositor_orc_splat_u32 ((guint32 *) dest, val, (y_end - y_start) * (stride / 4)); \
|
||||
}
|
||||
|
||||
A32_COLOR (argb, TRUE, 24, 16, 8, 0);
|
||||
A32_COLOR (bgra, TRUE, 0, 8, 16, 24);
|
||||
A32_COLOR (abgr, TRUE, 24, 0, 8, 16);
|
||||
A32_COLOR (rgba, TRUE, 0, 24, 16, 8);
|
||||
A32_COLOR (ayuv, FALSE, 24, 16, 8, 0);
|
||||
A32_COLOR (vuya, FALSE, 0, 8, 16, 24);
|
||||
A32_COLOR (argb, 24, 16, 8, 0);
|
||||
A32_COLOR (bgra, 0, 8, 16, 24);
|
||||
A32_COLOR (abgr, 24, 0, 8, 16);
|
||||
A32_COLOR (rgba, 0, 24, 16, 8);
|
||||
A32_COLOR (ayuv, 24, 16, 8, 0);
|
||||
A32_COLOR (vuya, 0, 8, 16, 24);
|
||||
|
||||
/* Y444, Y42B, I420, YV12, Y41B */
|
||||
#define PLANAR_YUV_BLEND(format_name,format_enum,x_round,y_round,MEMCPY,BLENDLOOP) \
|
||||
|
@ -857,9 +843,8 @@ fill_checker_##name##_c (GstVideoFrame * frame, guint y_start, guint y_end) \
|
|||
#define RGB_FILL_COLOR(name, bpp, MEMSET_RGB) \
|
||||
static void \
|
||||
fill_color_##name (GstVideoFrame * frame, \
|
||||
guint y_start, guint y_end, gint colY, gint colU, gint colV) \
|
||||
guint y_start, guint y_end, gint colR, gint colG, gint colB) \
|
||||
{ \
|
||||
gint red, green, blue; \
|
||||
gint i; \
|
||||
gint dest_stride; \
|
||||
gint width, height; \
|
||||
|
@ -870,13 +855,9 @@ fill_color_##name (GstVideoFrame * frame, \
|
|||
dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0); \
|
||||
dest_stride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0); \
|
||||
\
|
||||
red = YUV_TO_R (colY, colU, colV); \
|
||||
green = YUV_TO_G (colY, colU, colV); \
|
||||
blue = YUV_TO_B (colY, colU, colV); \
|
||||
\
|
||||
dest += y_start * dest_stride; \
|
||||
for (i = 0; i < height; i++) { \
|
||||
MEMSET_RGB (dest, red, green, blue, width); \
|
||||
MEMSET_RGB (dest, colR, colG, colB, width); \
|
||||
dest += dest_stride; \
|
||||
} \
|
||||
}
|
||||
|
|
|
@ -800,7 +800,9 @@ GST_ELEMENT_REGISTER_DEFINE (compositor, "compositor", GST_RANK_PRIMARY + 1,
|
|||
static gboolean
|
||||
set_functions (GstCompositor * self, const GstVideoInfo * info)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gint offset[GST_VIDEO_MAX_COMPONENTS] = { 0, };
|
||||
gint scale[GST_VIDEO_MAX_COMPONENTS] = { 0, };
|
||||
gint i;
|
||||
|
||||
self->blend = NULL;
|
||||
self->overlay = NULL;
|
||||
|
@ -813,160 +815,164 @@ set_functions (GstCompositor * self, const GstVideoInfo * info)
|
|||
self->overlay = gst_compositor_overlay_ayuv;
|
||||
self->fill_checker = gst_compositor_fill_checker_ayuv;
|
||||
self->fill_color = gst_compositor_fill_color_ayuv;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_VUYA:
|
||||
self->blend = gst_compositor_blend_vuya;
|
||||
self->overlay = gst_compositor_overlay_vuya;
|
||||
self->fill_checker = gst_compositor_fill_checker_vuya;
|
||||
self->fill_color = gst_compositor_fill_color_vuya;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_ARGB:
|
||||
self->blend = gst_compositor_blend_argb;
|
||||
self->overlay = gst_compositor_overlay_argb;
|
||||
self->fill_checker = gst_compositor_fill_checker_argb;
|
||||
self->fill_color = gst_compositor_fill_color_argb;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_BGRA:
|
||||
self->blend = gst_compositor_blend_bgra;
|
||||
self->overlay = gst_compositor_overlay_bgra;
|
||||
self->fill_checker = gst_compositor_fill_checker_bgra;
|
||||
self->fill_color = gst_compositor_fill_color_bgra;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_ABGR:
|
||||
self->blend = gst_compositor_blend_abgr;
|
||||
self->overlay = gst_compositor_overlay_abgr;
|
||||
self->fill_checker = gst_compositor_fill_checker_abgr;
|
||||
self->fill_color = gst_compositor_fill_color_abgr;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_RGBA:
|
||||
self->blend = gst_compositor_blend_rgba;
|
||||
self->overlay = gst_compositor_overlay_rgba;
|
||||
self->fill_checker = gst_compositor_fill_checker_rgba;
|
||||
self->fill_color = gst_compositor_fill_color_rgba;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y444:
|
||||
self->blend = gst_compositor_blend_y444;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_y444;
|
||||
self->fill_color = gst_compositor_fill_color_y444;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y42B:
|
||||
self->blend = gst_compositor_blend_y42b;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_y42b;
|
||||
self->fill_color = gst_compositor_fill_color_y42b;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
self->blend = gst_compositor_blend_yuy2;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_yuy2;
|
||||
self->fill_color = gst_compositor_fill_color_yuy2;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
self->blend = gst_compositor_blend_uyvy;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_uyvy;
|
||||
self->fill_color = gst_compositor_fill_color_uyvy;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YVYU:
|
||||
self->blend = gst_compositor_blend_yvyu;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_yvyu;
|
||||
self->fill_color = gst_compositor_fill_color_yvyu;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
self->blend = gst_compositor_blend_i420;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_i420;
|
||||
self->fill_color = gst_compositor_fill_color_i420;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YV12:
|
||||
self->blend = gst_compositor_blend_yv12;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_yv12;
|
||||
self->fill_color = gst_compositor_fill_color_yv12;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV12:
|
||||
self->blend = gst_compositor_blend_nv12;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_nv12;
|
||||
self->fill_color = gst_compositor_fill_color_nv12;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_NV21:
|
||||
self->blend = gst_compositor_blend_nv21;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_nv21;
|
||||
self->fill_color = gst_compositor_fill_color_nv21;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y41B:
|
||||
self->blend = gst_compositor_blend_y41b;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_y41b;
|
||||
self->fill_color = gst_compositor_fill_color_y41b;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_RGB:
|
||||
self->blend = gst_compositor_blend_rgb;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_rgb;
|
||||
self->fill_color = gst_compositor_fill_color_rgb;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_BGR:
|
||||
self->blend = gst_compositor_blend_bgr;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_bgr;
|
||||
self->fill_color = gst_compositor_fill_color_bgr;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_xRGB:
|
||||
self->blend = gst_compositor_blend_xrgb;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_xrgb;
|
||||
self->fill_color = gst_compositor_fill_color_xrgb;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_xBGR:
|
||||
self->blend = gst_compositor_blend_xbgr;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_xbgr;
|
||||
self->fill_color = gst_compositor_fill_color_xbgr;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_RGBx:
|
||||
self->blend = gst_compositor_blend_rgbx;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_rgbx;
|
||||
self->fill_color = gst_compositor_fill_color_rgbx;
|
||||
ret = TRUE;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_BGRx:
|
||||
self->blend = gst_compositor_blend_bgrx;
|
||||
self->overlay = self->blend;
|
||||
self->fill_checker = gst_compositor_fill_checker_bgrx;
|
||||
self->fill_color = gst_compositor_fill_color_bgrx;
|
||||
ret = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
GST_ERROR_OBJECT (self, "Unhandled format %s",
|
||||
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* calculate black and white colors */
|
||||
gst_video_color_range_offsets (info->colorimetry.range, info->finfo,
|
||||
offset, scale);
|
||||
if (GST_VIDEO_INFO_IS_YUV (info)) {
|
||||
/* black color [0.0, 0.0, 0.0] */
|
||||
self->black_color[0] = offset[0];
|
||||
|
||||
/* white color [1.0, 0.0, 0.0] */
|
||||
self->white_color[0] = scale[0] + offset[0];
|
||||
|
||||
for (i = 1; i < 3; i++)
|
||||
self->black_color[i] = self->white_color[i] = offset[i];
|
||||
} else {
|
||||
for (i = 0; i < 3; i++) {
|
||||
self->black_color[i] = offset[i];
|
||||
self->white_color[i] = scale[i] + offset[i];
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self,
|
||||
"Calculated background color block: [%d %d %d], white: [%d %d %d]",
|
||||
self->black_color[0], self->black_color[1], self->black_color[2],
|
||||
self->white_color[0], self->white_color[1], self->white_color[2]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
|
@ -1311,10 +1317,16 @@ _draw_background (GstCompositor * comp, GstVideoFrame * outframe,
|
|||
comp->fill_checker (outframe, y_start, y_end);
|
||||
break;
|
||||
case COMPOSITOR_BACKGROUND_BLACK:
|
||||
comp->fill_color (outframe, y_start, y_end, 16, 128, 128);
|
||||
comp->fill_color (outframe, y_start, y_end,
|
||||
comp->black_color[GST_VIDEO_COMP_Y],
|
||||
comp->black_color[GST_VIDEO_COMP_U],
|
||||
comp->black_color[GST_VIDEO_COMP_V]);
|
||||
break;
|
||||
case COMPOSITOR_BACKGROUND_WHITE:
|
||||
comp->fill_color (outframe, y_start, y_end, 240, 128, 128);
|
||||
comp->fill_color (outframe, y_start, y_end,
|
||||
comp->white_color[GST_VIDEO_COMP_Y],
|
||||
comp->white_color[GST_VIDEO_COMP_U],
|
||||
comp->white_color[GST_VIDEO_COMP_V]);
|
||||
break;
|
||||
case COMPOSITOR_BACKGROUND_TRANSPARENT:
|
||||
{
|
||||
|
|
|
@ -144,6 +144,11 @@ struct _GstCompositor
|
|||
FillCheckerFunction fill_checker;
|
||||
FillColorFunction fill_color;
|
||||
|
||||
/* pre-calculated white/black level values, YUV or RGB order depending on
|
||||
* selected output format */
|
||||
gint white_color[GST_VIDEO_MAX_COMPONENTS];
|
||||
gint black_color[GST_VIDEO_MAX_COMPONENTS];
|
||||
|
||||
GstParallelizedTaskRunner *blend_runner;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue