summaryrefslogtreecommitdiff
path: root/gst-libs/gst/video/video-overlay-composition.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/video/video-overlay-composition.c')
-rw-r--r--gst-libs/gst/video/video-overlay-composition.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c
index 9b984dff1..abe16f8e8 100644
--- a/gst-libs/gst/video/video-overlay-composition.c
+++ b/gst-libs/gst/video/video-overlay-composition.c
@@ -849,6 +849,19 @@ gst_video_overlay_rectangle_set_render_rectangle (GstVideoOverlayRectangle *
rectangle->render_height = render_height;
}
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+# define ARGB_A 3
+# define ARGB_R 2
+# define ARGB_G 1
+# define ARGB_B 0
+#else
+# define ARGB_A 0
+# define ARGB_R 1
+# define ARGB_G 2
+# define ARGB_B 3
+#endif
+
+/* FIXME: orc-ify */
static void
gst_video_overlay_rectangle_premultiply (GstBlendVideoFormatInfo * info)
{
@@ -856,15 +869,16 @@ gst_video_overlay_rectangle_premultiply (GstBlendVideoFormatInfo * info)
for (j = 0; j < info->height; ++j) {
guint8 *line = info->pixels + info->stride[0] * j;
for (i = 0; i < info->width; ++i) {
- int a = line[0];
- line[1] = line[1] * a / 255;
- line[2] = line[2] * a / 255;
- line[3] = line[3] * a / 255;
+ int a = line[ARGB_A];
+ line[ARGB_R] = line[ARGB_R] * a / 255;
+ line[ARGB_G] = line[ARGB_G] * a / 255;
+ line[ARGB_B] = line[ARGB_B] * a / 255;
line += 4;
}
}
}
+/* FIXME: orc-ify */
static void
gst_video_overlay_rectangle_unpremultiply (GstBlendVideoFormatInfo * info)
{
@@ -872,11 +886,11 @@ gst_video_overlay_rectangle_unpremultiply (GstBlendVideoFormatInfo * info)
for (j = 0; j < info->height; ++j) {
guint8 *line = info->pixels + info->stride[0] * j;
for (i = 0; i < info->width; ++i) {
- int a = line[0];
+ int a = line[ARGB_A];
if (a) {
- line[1] = MIN ((line[1] * 255 + a / 2) / a, 255);
- line[2] = MIN ((line[2] * 255 + a / 2) / a, 255);
- line[3] = MIN ((line[3] * 255 + a / 2) / a, 255);
+ line[ARGB_R] = MIN ((line[ARGB_R] * 255 + a / 2) / a, 255);
+ line[ARGB_G] = MIN ((line[ARGB_G] * 255 + a / 2) / a, 255);
+ line[ARGB_B] = MIN ((line[ARGB_B] * 255 + a / 2) / a, 255);
}
line += 4;
}
@@ -888,6 +902,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle *
rectangle, guint * stride, GstVideoOverlayFormatFlags flags,
gboolean unscaled)
{
+ GstVideoOverlayFormatFlags new_flags;
GstVideoOverlayRectangle *scaled_rect = NULL;
GstBlendVideoFormatInfo info;
GstBuffer *buf;
@@ -915,8 +930,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle *
if (r->width == wanted_width &&
r->height == wanted_height &&
- gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags,
- flags)) {
+ gst_video_overlay_rectangle_is_same_alpha_type (r->flags, flags)) {
/* we'll keep these rectangles around until finalize, so it's ok not
* to take our own ref here */
scaled_rect = r;
@@ -936,13 +950,20 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle *
if (wanted_width != rectangle->width || wanted_height != rectangle->height) {
video_blend_scale_linear_RGBA (&info, wanted_height, wanted_width);
+ } else {
+ /* if we don't have to scale, we have to modify the alpha values, so we
+ * need to make a copy of the pixel memory (and we take ownership below) */
+ info.pixels = g_memdup (info.pixels, info.size);
}
+ new_flags = rectangle->flags;
if (!gst_video_overlay_rectangle_is_same_alpha_type (rectangle->flags, flags)) {
if (rectangle->flags & GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA) {
gst_video_overlay_rectangle_unpremultiply (&info);
+ new_flags &= ~GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
} else {
gst_video_overlay_rectangle_premultiply (&info);
+ new_flags |= GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA;
}
}
@@ -953,7 +974,7 @@ gst_video_overlay_rectangle_get_pixels_argb_internal (GstVideoOverlayRectangle *
scaled_rect = gst_video_overlay_rectangle_new_argb (buf,
wanted_width, wanted_height, info.stride[0],
- 0, 0, wanted_width, wanted_height, rectangle->flags);
+ 0, 0, wanted_width, wanted_height, new_flags);
gst_buffer_unref (buf);