static void gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay) { GstVideoOverlayComposition *comp; GstVideoOverlayRectangle *rect; GstVideoMeta *overlay_meta; gint x, y, width, height; gint video_width = GST_VIDEO_INFO_WIDTH (&GST_VIDEO_FILTER (overlay)->in_info); gint video_height = GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_FILTER (overlay)->in_info); if (overlay->comp) { gst_video_overlay_composition_unref (overlay->comp); overlay->comp = NULL; } if (overlay->alpha == 0.0 || overlay->pixels == NULL) return; overlay_meta = gst_buffer_get_video_meta (overlay->pixels); x = overlay->offset_x < 0 ? video_width + overlay->offset_x - overlay_meta->width + (overlay->relative_x * overlay_meta->width) : overlay->offset_x + (overlay->relative_x * overlay_meta->width); y = overlay->offset_y < 0 ? video_height + overlay->offset_y - overlay_meta->height + (overlay->relative_y * overlay_meta->height) : overlay->offset_y + (overlay->relative_y * overlay_meta->height); width = overlay->overlay_width; if (width == 0) width = overlay_meta->width; height = overlay->overlay_height; if (height == 0) height = overlay_meta->height; GST_DEBUG_OBJECT (overlay, "overlay image dimensions: %d x %d, alpha=%.2f", overlay_meta->width, overlay_meta->height, overlay->alpha); GST_DEBUG_OBJECT (overlay, "properties: x,y: %d,%d (%g%%,%g%%) - WxH: %dx%d", overlay->offset_x, overlay->offset_y, overlay->relative_x * 100.0, overlay->relative_y * 100.0, overlay->overlay_height, overlay->overlay_width); GST_DEBUG_OBJECT (overlay, "overlay rendered: %d x %d @ %d,%d (onto %d x %d)", width, height, x, y, video_width, video_height); rect = gst_video_overlay_rectangle_new_raw (overlay->pixels, x, y, width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); if (overlay->alpha != 1.0) gst_video_overlay_rectangle_set_global_alpha (rect, overlay->alpha); comp = gst_video_overlay_composition_new (rect); gst_video_overlay_rectangle_unref (rect); overlay->comp = comp; }
static void gst_gdk_pixbuf_overlay_update_composition (GstGdkPixbufOverlay * overlay) { GstVideoOverlayComposition *comp; GstVideoOverlayRectangle *rect; gint x, y, width, height; if (overlay->comp) { gst_video_overlay_composition_unref (overlay->comp); overlay->comp = NULL; } if (overlay->alpha == 0.0) return; x = overlay->offset_x + (overlay->relative_x * overlay->pixels_width); y = overlay->offset_y + (overlay->relative_y * overlay->pixels_height); /* FIXME: this should work, but seems to crash */ if (x < 0) x = 0; if (y < 0) y = 0; width = overlay->overlay_width; if (width == 0) width = overlay->pixels_width; height = overlay->overlay_height; if (height == 0) height = overlay->pixels_height; GST_DEBUG_OBJECT (overlay, "overlay image dimensions: %d x %d, alpha=%.2f", overlay->pixels_width, overlay->pixels_height, overlay->alpha); GST_DEBUG_OBJECT (overlay, "properties: x,y: %d,%d (%g%%,%g%%) - WxH: %dx%d", overlay->offset_x, overlay->offset_y, overlay->relative_x * 100.0, overlay->relative_y * 100.0, overlay->overlay_height, overlay->overlay_width); GST_DEBUG_OBJECT (overlay, "overlay rendered: %d x %d @ %d,%d (onto %d x %d)", width, height, x, y, overlay->width, overlay->height); rect = gst_video_overlay_rectangle_new_argb (overlay->pixels, overlay->pixels_width, overlay->pixels_height, overlay->pixels_stride, x, y, width, height, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); if (overlay->alpha != 1.0) gst_video_overlay_rectangle_set_global_alpha (rect, overlay->alpha); comp = gst_video_overlay_composition_new (rect); gst_video_overlay_rectangle_unref (rect); overlay->comp = comp; }
static GstPadProbeReturn buffer_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GstVideoOverlayRectangle *rect; GstVideoOverlayComposition *comp; GstVideoFrame frame; GstVideoMeta *vmeta; GstVideoInfo vinfo; GstCaps *caps; gint x, y; caps = gst_pad_get_current_caps (pad); gst_video_info_from_caps (&vinfo, caps); gst_caps_unref (caps); info->data = gst_buffer_make_writable (info->data); vmeta = gst_buffer_get_video_meta (logo_buf); calculate_position (&x, &y, vmeta->width, vmeta->height, ++count); GST_LOG ("%3d, %3d", x, y); rect = gst_video_overlay_rectangle_new_raw (logo_buf, x, y, vmeta->width, vmeta->height, GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE); comp = gst_video_overlay_composition_new (rect); gst_video_overlay_rectangle_unref (rect); gst_video_frame_map (&frame, &vinfo, info->data, GST_MAP_READWRITE); if (!gst_video_overlay_composition_blend (comp, &frame)) g_warning ("Error blending overlay at position (%d,%d)", x, y); gst_video_frame_unmap (&frame); gst_video_overlay_composition_unref (comp); return GST_PAD_PROBE_OK; }
static GstVideoOverlayComposition * gst_dvbsub_overlay_subs_to_comp (GstDVBSubOverlay * overlay, DVBSubtitles * subs) { GstVideoOverlayComposition *comp = NULL; GstVideoOverlayRectangle *rect; gint width, height, dw, dh, wx, wy; gint i; g_return_val_if_fail (subs != NULL && subs->num_rects > 0, NULL); width = GST_VIDEO_INFO_WIDTH (&overlay->info); height = GST_VIDEO_INFO_HEIGHT (&overlay->info); dw = subs->display_def.display_width; dh = subs->display_def.display_height; GST_LOG_OBJECT (overlay, "converting %d rectangles for display %dx%d -> video %dx%d", subs->num_rects, dw, dh, width, height); if (subs->display_def.window_flag) { wx = subs->display_def.window_x; wy = subs->display_def.window_y; GST_LOG_OBJECT (overlay, "display window %dx%d @ (%d, %d)", subs->display_def.window_width, subs->display_def.window_height, wx, wy); } else { wx = 0; wy = 0; } for (i = 0; i < subs->num_rects; i++) { DVBSubtitleRect *srect = &subs->rects[i]; GstBuffer *buf; gint w, h; guint8 *in_data; guint32 *palette, *data; gint rx, ry, rw, rh, stride; gint k, l; GstMapInfo map; GST_LOG_OBJECT (overlay, "rectangle %d: %dx%d @ (%d, %d)", i, srect->w, srect->h, srect->x, srect->y); w = srect->w; h = srect->h; buf = gst_buffer_new_and_alloc (w * h * 4); gst_buffer_map (buf, &map, GST_MAP_WRITE); data = (guint32 *) map.data; in_data = srect->pict.data; palette = srect->pict.palette; stride = srect->pict.rowstride; for (k = 0; k < h; k++) { for (l = 0; l < w; l++) { guint32 ayuv; ayuv = palette[*in_data]; GST_WRITE_UINT32_BE (data, ayuv); in_data++; data++; } in_data += stride - w; } gst_buffer_unmap (buf, &map); /* this is assuming the subtitle rectangle coordinates are relative * to the window (if there is one) within a display of specified dimension. * Coordinate wrt the latter is then scaled to the actual dimension of * the video we are dealing with here. */ rx = gst_util_uint64_scale (wx + srect->x, width, dw); ry = gst_util_uint64_scale (wy + srect->y, height, dh); rw = gst_util_uint64_scale (srect->w, width, dw); rh = gst_util_uint64_scale (srect->h, height, dh); GST_LOG_OBJECT (overlay, "rectangle %d rendered: %dx%d @ (%d, %d)", i, rw, rh, rx, ry); gst_buffer_add_video_meta (buf, GST_VIDEO_FRAME_FLAG_NONE, GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV, w, h); rect = gst_video_overlay_rectangle_new_raw (buf, rx, ry, rw, rh, 0); g_assert (rect); if (comp) { gst_video_overlay_composition_add_rectangle (comp, rect); } else { comp = gst_video_overlay_composition_new (rect); } gst_video_overlay_rectangle_unref (rect); gst_buffer_unref (buf); } return comp; }