diff options
Diffstat (limited to 'gst-libs/gst/video/video-overlay-composition.c')
-rw-r--r-- | gst-libs/gst/video/video-overlay-composition.c | 43 |
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); |