mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
alpha: Add support for different color matrixes
This commit is contained in:
parent
00b3eb1dfc
commit
b64619dc4e
1 changed files with 277 additions and 76 deletions
|
@ -426,7 +426,7 @@ gst_alpha_set_caps (GstBaseTransform * btrans,
|
||||||
|
|
||||||
if (!gst_video_format_parse_caps (incaps, &alpha->in_format,
|
if (!gst_video_format_parse_caps (incaps, &alpha->in_format,
|
||||||
&alpha->width, &alpha->height) ||
|
&alpha->width, &alpha->height) ||
|
||||||
!gst_video_format_parse_caps (incaps, &alpha->out_format,
|
!gst_video_format_parse_caps (outcaps, &alpha->out_format,
|
||||||
&alpha->width, &alpha->height)) {
|
&alpha->width, &alpha->height)) {
|
||||||
GST_OBJECT_UNLOCK (alpha);
|
GST_OBJECT_UNLOCK (alpha);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -529,6 +529,8 @@ chroma_keying_yuv (gint a, gint * y, guint ny, gint * u,
|
||||||
return b_alpha;
|
return b_alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define APPLY_MATRIX(m,o,v1,v2,v3) ((m[o*4] * v1 + m[o*4+1] * v2 + m[o*4+2] * v3 + m[o*4+3]) >> 8)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_alpha_set_ayuv_ayuv (const guint8 * src, guint8 * dest, gint width,
|
gst_alpha_set_ayuv_ayuv (const guint8 * src, guint8 * dest, gint width,
|
||||||
gint height, GstAlpha * alpha)
|
gint height, GstAlpha * alpha)
|
||||||
|
@ -536,12 +538,33 @@ gst_alpha_set_ayuv_ayuv (const guint8 * src, guint8 * dest, gint width,
|
||||||
gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
|
gint s_alpha = CLAMP ((gint) (alpha->alpha * 256), 0, 256);
|
||||||
gint y, x;
|
gint y, x;
|
||||||
|
|
||||||
for (y = 0; y < height; y++) {
|
if (alpha->in_sdtv == alpha->out_sdtv) {
|
||||||
for (x = 0; x < width; x++) {
|
for (y = 0; y < height; y++) {
|
||||||
*dest++ = (*src++ * s_alpha) >> 8;
|
for (x = 0; x < width; x++) {
|
||||||
*dest++ = *src++;
|
dest[0] = (src[0] * s_alpha) >> 8;
|
||||||
*dest++ = *src++;
|
dest[1] = src[1];
|
||||||
*dest++ = *src++;
|
dest[2] = src[2];
|
||||||
|
dest[3] = src[3];
|
||||||
|
|
||||||
|
dest += 4;
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const gint *matrix =
|
||||||
|
alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
|
||||||
|
cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit;
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++) {
|
||||||
|
for (x = 0; x < width; x++) {
|
||||||
|
dest[0] = (src[0] * s_alpha) >> 8;
|
||||||
|
dest[1] = APPLY_MATRIX (matrix, 0, src[1], src[2], src[3]);
|
||||||
|
dest[2] = APPLY_MATRIX (matrix, 1, src[1], src[2], src[3]);
|
||||||
|
dest[3] = APPLY_MATRIX (matrix, 2, src[1], src[2], src[3]);
|
||||||
|
|
||||||
|
dest += 4;
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,32 +596,82 @@ gst_alpha_set_i420_ayuv (const guint8 * src, guint8 * dest, gint width,
|
||||||
|
|
||||||
odd_width = (width % 2 != 0);
|
odd_width = (width % 2 != 0);
|
||||||
|
|
||||||
for (i = 0; i < height; i++) {
|
if (alpha->in_sdtv == alpha->out_sdtv) {
|
||||||
for (j = 0; j < width / 2; j++) {
|
for (i = 0; i < height; i++) {
|
||||||
*dest++ = b_alpha;
|
for (j = 0; j < width / 2; j++) {
|
||||||
*dest++ = *srcY++;
|
dest[0] = b_alpha;
|
||||||
*dest++ = *srcU;
|
dest[1] = srcY[0];
|
||||||
*dest++ = *srcV;
|
dest[2] = srcU[0];
|
||||||
*dest++ = b_alpha;
|
dest[3] = srcV[0];
|
||||||
*dest++ = *srcY++;
|
dest[4] = b_alpha;
|
||||||
*dest++ = *srcU++;
|
dest[5] = srcY[1];
|
||||||
*dest++ = *srcV++;
|
dest[6] = srcU[0];
|
||||||
|
dest[7] = srcV[0];
|
||||||
|
|
||||||
|
dest += 8;
|
||||||
|
srcY += 2;
|
||||||
|
srcU++;
|
||||||
|
srcV++;
|
||||||
|
}
|
||||||
|
/* Might have one odd column left to do */
|
||||||
|
if (odd_width) {
|
||||||
|
dest[0] = b_alpha;
|
||||||
|
dest[1] = srcY[0];
|
||||||
|
dest[2] = srcU[0];
|
||||||
|
dest[3] = srcV[0];
|
||||||
|
|
||||||
|
dest += 4;
|
||||||
|
srcY++;
|
||||||
|
}
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
srcU -= width / 2;
|
||||||
|
srcV -= width / 2;
|
||||||
|
} else {
|
||||||
|
srcU += src_uv_wrap;
|
||||||
|
srcV += src_uv_wrap;
|
||||||
|
}
|
||||||
|
srcY += src_wrap;
|
||||||
}
|
}
|
||||||
/* Might have one odd column left to do */
|
} else {
|
||||||
if (odd_width) {
|
const gint *matrix =
|
||||||
*dest++ = b_alpha;
|
alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
|
||||||
*dest++ = *srcY++;
|
cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit;
|
||||||
*dest++ = *srcU;
|
|
||||||
*dest++ = *srcV;
|
for (i = 0; i < height; i++) {
|
||||||
|
for (j = 0; j < width / 2; j++) {
|
||||||
|
dest[0] = b_alpha;
|
||||||
|
dest[1] = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]);
|
||||||
|
dest[2] = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]);
|
||||||
|
dest[3] = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]);
|
||||||
|
dest[4] = b_alpha;
|
||||||
|
dest[5] = APPLY_MATRIX (matrix, 0, srcY[1], srcU[0], srcV[0]);
|
||||||
|
dest[6] = APPLY_MATRIX (matrix, 1, srcY[1], srcU[0], srcV[0]);
|
||||||
|
dest[7] = APPLY_MATRIX (matrix, 2, srcY[1], srcU[0], srcV[0]);
|
||||||
|
|
||||||
|
dest += 8;
|
||||||
|
srcY += 2;
|
||||||
|
srcU++;
|
||||||
|
srcV++;
|
||||||
|
}
|
||||||
|
/* Might have one odd column left to do */
|
||||||
|
if (odd_width) {
|
||||||
|
dest[0] = b_alpha;
|
||||||
|
dest[1] = APPLY_MATRIX (matrix, 0, srcY[0], srcU[0], srcV[0]);
|
||||||
|
dest[2] = APPLY_MATRIX (matrix, 1, srcY[0], srcU[0], srcV[0]);
|
||||||
|
dest[3] = APPLY_MATRIX (matrix, 2, srcY[0], srcU[0], srcV[0]);
|
||||||
|
|
||||||
|
dest += 4;
|
||||||
|
srcY++;
|
||||||
|
}
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
srcU -= width / 2;
|
||||||
|
srcV -= width / 2;
|
||||||
|
} else {
|
||||||
|
srcU += src_uv_wrap;
|
||||||
|
srcV += src_uv_wrap;
|
||||||
|
}
|
||||||
|
srcY += src_wrap;
|
||||||
}
|
}
|
||||||
if (i % 2 == 0) {
|
|
||||||
srcU -= width / 2;
|
|
||||||
srcV -= width / 2;
|
|
||||||
} else {
|
|
||||||
srcU += src_uv_wrap;
|
|
||||||
srcV += src_uv_wrap;
|
|
||||||
}
|
|
||||||
srcY += src_wrap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -619,25 +692,59 @@ gst_alpha_chroma_key_ayuv_ayuv (const guint8 * src, guint8 * dest, gint width,
|
||||||
src1 = src;
|
src1 = src;
|
||||||
dest1 = dest;
|
dest1 = dest;
|
||||||
|
|
||||||
for (i = 0; i < height; i++) {
|
if (alpha->in_sdtv == alpha->out_sdtv) {
|
||||||
for (j = 0; j < width; j++) {
|
for (i = 0; i < height; i++) {
|
||||||
a = (*src1++ * pa) >> 8;
|
for (j = 0; j < width; j++) {
|
||||||
y = *src1++;
|
a = (src1[0] * pa) >> 8;
|
||||||
u = *src1++ - 128;
|
y = src1[1];
|
||||||
v = *src1++ - 128;
|
u = src1[2] - 128;
|
||||||
|
v = src1[3] - 128;
|
||||||
|
|
||||||
a = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb,
|
a = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb,
|
||||||
smin, smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
smin, smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
alpha->noise_level2);
|
alpha->noise_level2);
|
||||||
|
|
||||||
u += 128;
|
u += 128;
|
||||||
v += 128;
|
v += 128;
|
||||||
|
|
||||||
*dest1++ = a;
|
dest1[0] = a;
|
||||||
*dest1++ = y;
|
dest1[1] = y;
|
||||||
*dest1++ = u;
|
dest1[2] = u;
|
||||||
*dest1++ = v;
|
dest1[3] = v;
|
||||||
|
|
||||||
|
src1 += 4;
|
||||||
|
dest1 += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const gint *matrix =
|
||||||
|
alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
|
||||||
|
cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit;
|
||||||
|
|
||||||
|
for (i = 0; i < height; i++) {
|
||||||
|
for (j = 0; j < width; j++) {
|
||||||
|
a = (src1[0] * pa) >> 8;
|
||||||
|
y = APPLY_MATRIX (matrix, 0, src1[1], src1[2], src1[3]);
|
||||||
|
u = APPLY_MATRIX (matrix, 1, src1[1], src1[2], src1[3]) - 128;
|
||||||
|
v = APPLY_MATRIX (matrix, 2, src1[1], src1[2], src1[3]) - 128;
|
||||||
|
|
||||||
|
a = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb,
|
||||||
|
smin, smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
|
u += 128;
|
||||||
|
v += 128;
|
||||||
|
|
||||||
|
dest1[0] = a;
|
||||||
|
dest1[1] = y;
|
||||||
|
dest1[2] = u;
|
||||||
|
dest1[3] = v;
|
||||||
|
|
||||||
|
src1 += 4;
|
||||||
|
dest1 += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,45 +755,139 @@ gst_alpha_chromakey_row_i420_ayuv (GstAlpha * alpha, guint8 * dest1,
|
||||||
const guint8 * srcU, const guint8 * srcV, gint width)
|
const guint8 * srcU, const guint8 * srcV, gint width)
|
||||||
{
|
{
|
||||||
gint xpos;
|
gint xpos;
|
||||||
gint a, a2, y[4], u, v;
|
gint a, a2, u, v;
|
||||||
gint smin, smax;
|
gint smin, smax;
|
||||||
|
|
||||||
a = 255 * alpha->alpha;
|
a = 255 * alpha->alpha;
|
||||||
smin = 128 - alpha->black_sensitivity;
|
smin = 128 - alpha->black_sensitivity;
|
||||||
smax = 128 + alpha->white_sensitivity;
|
smax = 128 + alpha->white_sensitivity;
|
||||||
|
|
||||||
for (xpos = 0; xpos < width / 2; xpos++) {
|
if (alpha->in_sdtv == alpha->out_sdtv) {
|
||||||
y[0] = *srcY1++;
|
gint y[4];
|
||||||
y[1] = *srcY1++;
|
|
||||||
y[2] = *srcY2++;
|
|
||||||
y[3] = *srcY2++;
|
|
||||||
u = *srcU++ - 128;
|
|
||||||
v = *srcV++ - 128;
|
|
||||||
|
|
||||||
a2 = chroma_keying_yuv (a, y, 4, &u, &v, alpha->cr, alpha->cb, smin,
|
for (xpos = 0; xpos < width / 2; xpos++) {
|
||||||
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
y[0] = srcY1[0];
|
||||||
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg, alpha->noise_level2);
|
y[1] = srcY1[1];
|
||||||
|
y[2] = srcY2[0];
|
||||||
|
y[3] = srcY2[1];
|
||||||
|
u = srcU[0] - 128;
|
||||||
|
v = srcV[0] - 128;
|
||||||
|
|
||||||
u += 128;
|
a2 = chroma_keying_yuv (a, y, 4, &u, &v, alpha->cr, alpha->cb, smin,
|
||||||
v += 128;
|
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
*dest1++ = a2;
|
u += 128;
|
||||||
*dest1++ = y[0];
|
v += 128;
|
||||||
*dest1++ = u;
|
|
||||||
*dest1++ = v;
|
|
||||||
*dest1++ = a2;
|
|
||||||
*dest1++ = y[1];
|
|
||||||
*dest1++ = u;
|
|
||||||
*dest1++ = v;
|
|
||||||
|
|
||||||
*dest2++ = a2;
|
dest1[0] = a2;
|
||||||
*dest2++ = y[2];
|
dest1[1] = y[0];
|
||||||
*dest2++ = u;
|
dest1[2] = u;
|
||||||
*dest2++ = v;
|
dest1[3] = v;
|
||||||
*dest2++ = a2;
|
dest1[4] = a2;
|
||||||
*dest2++ = y[3];
|
dest1[5] = y[1];
|
||||||
*dest2++ = u;
|
dest1[6] = u;
|
||||||
*dest2++ = v;
|
dest1[7] = v;
|
||||||
|
|
||||||
|
dest2[0] = a2;
|
||||||
|
dest2[1] = y[2];
|
||||||
|
dest2[2] = u;
|
||||||
|
dest2[3] = v;
|
||||||
|
dest2[4] = a2;
|
||||||
|
dest2[5] = y[3];
|
||||||
|
dest2[6] = u;
|
||||||
|
dest2[7] = v;
|
||||||
|
|
||||||
|
srcY1 += 2;
|
||||||
|
srcY2 += 2;
|
||||||
|
srcU++;
|
||||||
|
srcV++;
|
||||||
|
dest1 += 8;
|
||||||
|
dest2 += 8;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const gint *matrix =
|
||||||
|
alpha->out_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
|
||||||
|
cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit;
|
||||||
|
gint y;
|
||||||
|
|
||||||
|
for (xpos = 0; xpos < width / 2; xpos++) {
|
||||||
|
y = APPLY_MATRIX (matrix, 0, srcY1[0], srcU[0], srcV[0]);
|
||||||
|
u = APPLY_MATRIX (matrix, 1, srcY1[0], srcU[0], srcV[0]) - 128;
|
||||||
|
v = APPLY_MATRIX (matrix, 2, srcY1[0], srcU[0], srcV[0]) - 128;
|
||||||
|
|
||||||
|
a2 = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb, smin,
|
||||||
|
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
|
u += 128;
|
||||||
|
v += 128;
|
||||||
|
|
||||||
|
dest1[0] = a2;
|
||||||
|
dest1[1] = y;
|
||||||
|
dest1[2] = u;
|
||||||
|
dest1[3] = v;
|
||||||
|
|
||||||
|
y = APPLY_MATRIX (matrix, 0, srcY1[1], srcU[0], srcV[0]);
|
||||||
|
u = APPLY_MATRIX (matrix, 1, srcY1[1], srcU[0], srcV[0]) - 128;
|
||||||
|
v = APPLY_MATRIX (matrix, 2, srcY1[1], srcU[0], srcV[0]) - 128;
|
||||||
|
|
||||||
|
a2 = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb, smin,
|
||||||
|
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
|
u += 128;
|
||||||
|
v += 128;
|
||||||
|
|
||||||
|
dest1[4] = a2;
|
||||||
|
dest1[5] = y;
|
||||||
|
dest1[6] = u;
|
||||||
|
dest1[7] = v;
|
||||||
|
|
||||||
|
y = APPLY_MATRIX (matrix, 0, srcY2[0], srcU[0], srcV[0]);
|
||||||
|
u = APPLY_MATRIX (matrix, 1, srcY2[0], srcU[0], srcV[0]) - 128;
|
||||||
|
v = APPLY_MATRIX (matrix, 2, srcY2[0], srcU[0], srcV[0]) - 128;
|
||||||
|
|
||||||
|
a2 = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb, smin,
|
||||||
|
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
|
u += 128;
|
||||||
|
v += 128;
|
||||||
|
|
||||||
|
dest2[0] = a2;
|
||||||
|
dest2[1] = y;
|
||||||
|
dest2[2] = u;
|
||||||
|
dest2[3] = v;
|
||||||
|
|
||||||
|
y = APPLY_MATRIX (matrix, 0, srcY2[1], srcU[0], srcV[0]);
|
||||||
|
u = APPLY_MATRIX (matrix, 1, srcY2[1], srcU[0], srcV[0]) - 128;
|
||||||
|
v = APPLY_MATRIX (matrix, 2, srcY2[1], srcU[0], srcV[0]) - 128;
|
||||||
|
|
||||||
|
a2 = chroma_keying_yuv (a, &y, 1, &u, &v, alpha->cr, alpha->cb, smin,
|
||||||
|
smax, alpha->accept_angle_tg, alpha->accept_angle_ctg,
|
||||||
|
alpha->one_over_kc, alpha->kfgy_scale, alpha->kg,
|
||||||
|
alpha->noise_level2);
|
||||||
|
|
||||||
|
u += 128;
|
||||||
|
v += 128;
|
||||||
|
|
||||||
|
dest2[4] = a2;
|
||||||
|
dest2[5] = y;
|
||||||
|
dest2[6] = u;
|
||||||
|
dest2[7] = v;
|
||||||
|
|
||||||
|
srcY1 += 2;
|
||||||
|
srcY2 += 2;
|
||||||
|
srcU++;
|
||||||
|
srcV++;
|
||||||
|
dest1 += 8;
|
||||||
|
dest2 += 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue