コード例 #1
0
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;
}
コード例 #2
0
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;
}
コード例 #4
0
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;
}