コード例 #1
0
static void
gst_sdlvideosink_navigation_send_event (GstNavigation * navigation,
                                        GstStructure * structure)
{
    GstSDLVideoSink *sdlvideosink = GST_SDLVIDEOSINK (navigation);
    GstEvent *event;
    GstVideoRectangle dst = { 0, };
    GstVideoRectangle src = { 0, };
    GstVideoRectangle result;
    double x, y, old_x, old_y;
    GstPad *pad = NULL;

    src.w = GST_VIDEO_SINK_WIDTH (sdlvideosink);
    src.h = GST_VIDEO_SINK_HEIGHT (sdlvideosink);
    dst.w = sdlvideosink->width;
    dst.h = sdlvideosink->height;
    gst_video_sink_center_rect (src, dst, &result, FALSE);

    event = gst_event_new_navigation (structure);

    /* Our coordinates can be wrong here if we centered the video */

    /* Converting pointer coordinates to the non scaled geometry */
    if (gst_structure_get_double (structure, "pointer_x", &old_x)) {
        x = old_x;

        if (x >= result.x && x <= (result.x + result.w)) {
            x -= result.x;
            x *= sdlvideosink->width;
            x /= result.w;
        } else {
            x = 0;
        }
        GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event x "
                          "coordinate from %f to %f", old_x, x);
        gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
    }
    if (gst_structure_get_double (structure, "pointer_y", &old_y)) {
        y = old_y;

        if (y >= result.y && y <= (result.y + result.h)) {
            y -= result.y;
            y *= sdlvideosink->height;
            y /= result.h;
        } else {
            y = 0;
        }
        GST_DEBUG_OBJECT (sdlvideosink, "translated navigation event y "
                          "coordinate from %f to %f", old_y, y);
        gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
    }

    pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sdlvideosink));

    if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
        gst_pad_send_event (pad, event);

        gst_object_unref (pad);
    }
}
コード例 #2
0
static VALUE
navigation_initialize(VALUE self, VALUE structure)
{
    GstEvent *event;

    event = gst_event_new_navigation(RVAL2GST_STRUCT(structure));

    G_INITIALIZE(self, event);
    return Qnil;
}
コード例 #3
0
static void
nav_send_event (GstNavigation * navigation, GstStructure * structure)
{
  GstEvent *event = gst_event_new_navigation (structure);
  GstNavigationEventType etype = gst_navigation_event_get_type (event);
  TestElement *self = (TestElement *) (navigation);

  fail_if (etype == GST_NAVIGATION_EVENT_INVALID,
      "Received navigation event could not be parsed");
  fail_unless (etype == self->sent_type,
      "Received navigation event did not match sent");

  switch (etype) {
    case GST_NAVIGATION_EVENT_KEY_PRESS:
    case GST_NAVIGATION_EVENT_KEY_RELEASE:{
      const gchar *key;
      fail_unless (gst_navigation_event_parse_key_event (event, &key));
      fail_unless (strcmp (key, self->sent_key) == 0);
      break;
    }
    case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS:
    case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:{
      gint button;
      gdouble x, y;
      fail_unless (gst_navigation_event_parse_mouse_button_event (event,
              &button, &x, &y));
      fail_unless (button == self->sent_button);
      fail_unless (x == self->sent_x);
      fail_unless (y == self->sent_y);
      break;
    }
    case GST_NAVIGATION_EVENT_MOUSE_MOVE:{
      gdouble x, y;
      fail_unless (gst_navigation_event_parse_mouse_move_event (event, &x, &y));
      fail_unless (x == self->sent_x);
      fail_unless (y == self->sent_y);
      break;
    }
    case GST_NAVIGATION_EVENT_COMMAND:{
      GstNavigationCommand cmd;
      fail_unless (gst_navigation_event_parse_command (event, &cmd));
      fail_unless (cmd == self->sent_command);
    }
    default:
      break;
  }

  gst_event_unref (event);
}
コード例 #4
0
ファイル: gstvdpsink.c プロジェクト: spunktsch/svtplayer
static void
gst_vdp_sink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  VdpSink *vdp_sink = GST_VDP_SINK (navigation);
  GstEvent *event;
  gint x_offset, y_offset;
  gdouble x, y;
  GstPad *pad = NULL;

  event = gst_event_new_navigation (structure);

  /* We are not converting the pointer coordinates as there's no hardware
     scaling done here. The only possible scaling is done by videoscale and
     videoscale will have to catch those events and tranform the coordinates
     to match the applied scaling. So here we just add the offset if the image
     is centered in the window.  */

  /* We take the flow_lock while we look at the window */
  g_mutex_lock (vdp_sink->flow_lock);

  if (!vdp_sink->window) {
    g_mutex_unlock (vdp_sink->flow_lock);
    return;
  }

  x_offset = vdp_sink->window->width - GST_VIDEO_SINK_WIDTH (vdp_sink);
  y_offset = vdp_sink->window->height - GST_VIDEO_SINK_HEIGHT (vdp_sink);

  g_mutex_unlock (vdp_sink->flow_lock);

  if (x_offset > 0 && gst_structure_get_double (structure, "pointer_x", &x)) {
    x -= x_offset / 2;
    gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
  }
  if (y_offset > 0 && gst_structure_get_double (structure, "pointer_y", &y)) {
    y -= y_offset / 2;
    gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
  }

  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (vdp_sink));

  if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
    gst_pad_send_event (pad, event);

    gst_object_unref (pad);
  }
}
コード例 #5
0
static gboolean
gst_video_crop_src_event (GstBaseTransform * trans, GstEvent * event)
{
  GstEvent *new_event;
  GstStructure *new_structure;
  const GstStructure *structure;
  const gchar *event_name;
  double pointer_x;
  double pointer_y;

  GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
  new_event = NULL;

  GST_OBJECT_LOCK (vcrop);
  if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION &&
      (vcrop->crop_left != 0 || vcrop->crop_top != 0)) {
    structure = gst_event_get_structure (event);
    event_name = gst_structure_get_string (structure, "event");

    if (event_name &&
        (strcmp (event_name, "mouse-move") == 0 ||
            strcmp (event_name, "mouse-button-press") == 0 ||
            strcmp (event_name, "mouse-button-release") == 0)) {

      if (gst_structure_get_double (structure, "pointer_x", &pointer_x) &&
          gst_structure_get_double (structure, "pointer_y", &pointer_y)) {

        new_structure = gst_structure_copy (structure);
        gst_structure_set (new_structure,
            "pointer_x", G_TYPE_DOUBLE, (double) (pointer_x + vcrop->crop_left),
            "pointer_y", G_TYPE_DOUBLE, (double) (pointer_y + vcrop->crop_top),
            NULL);

        new_event = gst_event_new_navigation (new_structure);
        gst_event_unref (event);
      } else {
        GST_WARNING_OBJECT (vcrop, "Failed to read navigation event");
      }
    }
  }

  GST_OBJECT_UNLOCK (vcrop);

  return GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (trans,
      (new_event ? new_event : event));
}
コード例 #6
0
static void
gst_gl_sink_bin_navigation_send_event (GstNavigation * navigation, GstStructure
    * structure)
{
  GstGLSinkBin *self = GST_GL_SINK_BIN (navigation);
  GstElement *nav =
      gst_bin_get_by_interface (GST_BIN (self), GST_TYPE_NAVIGATION);

  if (nav) {
    gst_navigation_send_event (GST_NAVIGATION (nav), structure);
    structure = NULL;
    gst_object_unref (nav);
  } else {
    GstEvent *event = gst_event_new_navigation (structure);
    structure = NULL;
    gst_element_send_event (GST_ELEMENT (self), event);
  }
}
コード例 #7
0
ファイル: gstv4l2sink.c プロジェクト: PeterXu/gst-mobile
static void
gst_v4l2sink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstV4l2Sink *v4l2sink = GST_V4L2SINK (navigation);
  GstV4l2Xv *xv = v4l2sink->v4l2object->xv;
  GstPad *peer;

  if (!xv)
    return;

  if ((peer = gst_pad_get_peer (GST_VIDEO_SINK_PAD (v4l2sink)))) {
    GstVideoRectangle rect;
    gdouble x, y, xscale = 1.0, yscale = 1.0;

    gst_v4l2_video_overlay_get_render_rect (v4l2sink->v4l2object, &rect);

    /* We calculate scaling using the original video frames geometry to
     * include pixel aspect ratio scaling.
     */
    xscale = (gdouble) v4l2sink->video_width / rect.w;
    yscale = (gdouble) v4l2sink->video_height / rect.h;

    /* Converting pointer coordinates to the non scaled geometry */
    if (gst_structure_get_double (structure, "pointer_x", &x)) {
      x = MIN (x, rect.x + rect.w);
      x = MAX (x - rect.x, 0);
      gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
          (gdouble) x * xscale, NULL);
    }
    if (gst_structure_get_double (structure, "pointer_y", &y)) {
      y = MIN (y, rect.y + rect.h);
      y = MAX (y - rect.y, 0);
      gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
          (gdouble) y * yscale, NULL);
    }

    gst_pad_send_event (peer, gst_event_new_navigation (structure));
    gst_object_unref (peer);
  }
}
コード例 #8
0
static void
gst_glimage_sink_navigation_send_event (GstNavigation * navigation, GstStructure
    * structure)
{
  GstGLImageSink *sink = GST_GLIMAGE_SINK (navigation);
  GstEvent *event = NULL;
  GstPad *pad = NULL;
  GstGLWindow *window = gst_gl_context_get_window (sink->context);
  guint width, height;
  gdouble x, y, xscale, yscale;

  g_return_if_fail (GST_GL_IS_WINDOW (window));

  width = GST_VIDEO_SINK_WIDTH (sink);
  height = GST_VIDEO_SINK_HEIGHT (sink);
  gst_gl_window_get_surface_dimensions (window, &width, &height);

  event = gst_event_new_navigation (structure);

  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));
  /* Converting pointer coordinates to the non scaled geometry */
  if (width != GST_VIDEO_SINK_WIDTH (sink) &&
      width != 0 && gst_structure_get_double (structure, "pointer_x", &x)) {
    xscale = (gdouble) GST_VIDEO_SINK_WIDTH (sink) / width;
    gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE,
        (gdouble) x * xscale, NULL);
  }
  if (height != GST_VIDEO_SINK_HEIGHT (sink) &&
      height != 0 && gst_structure_get_double (structure, "pointer_y", &y)) {
    yscale = (gdouble) GST_VIDEO_SINK_HEIGHT (sink) / height;
    gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE,
        (gdouble) y * yscale, NULL);
  }


  if (GST_IS_PAD (pad) && GST_IS_EVENT (event))
    gst_pad_send_event (pad, event);

  gst_object_unref (pad);
  gst_object_unref (window);
}
コード例 #9
0
ファイル: mmsgst.cpp プロジェクト: RomTok/disco-light
bool mmsGstSendAxisMotion(GstElement *pipeline, int posx, int posy) {
	if (!pipeline)
		return false;

	// construct event
	GstStructure *structure =
		gst_structure_new(	"application/x-gst-navigation",
							"event",	G_TYPE_STRING,	"mouse-move",
							"button",	G_TYPE_INT,		0,
							"pointer_x",G_TYPE_DOUBLE,	(double)posx,
							"pointer_y",G_TYPE_DOUBLE,	(double)posy,
							NULL);
	if (!structure)
		return false;
	GstEvent *event = gst_event_new_navigation(structure);
	if (!event)
		return false;

	// send event
	return gst_element_send_event(pipeline, event);
}
コード例 #10
0
static void
gst_d3dvideosink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstD3DVideoSink *sink = GST_D3DVIDEOSINK (navigation);
  GstEvent *e;

  if ((e = gst_event_new_navigation (structure))) {
    GstPad *pad;
    if ((pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink)))) {
      if (!gst_pad_send_event (pad, gst_event_ref (e))) {
        /* If upstream didn't handle the event we'll post a message with it
         * for the application in case it wants to do something with it */
        gst_element_post_message (GST_ELEMENT_CAST (sink),
            gst_navigation_message_new_event (GST_OBJECT_CAST (sink), e));
      }
      gst_event_unref (e);
      gst_object_unref (pad);
    }
  }
}
コード例 #11
0
ファイル: mmsgst.cpp プロジェクト: RomTok/disco-light
bool mmsGstSendKeyRelease(GstElement *pipeline, MMSKeySymbol key) {
	if (!pipeline)
		return false;

	// if keysym string is empty, do nothing but return success
	const char *ks = convertMMSKeySymbolToXKeysymString(key);
	if (!*ks)
		return true;

	// construct event
	GstStructure *structure =
		gst_structure_new(	"application/x-gst-navigation",
							"event",	G_TYPE_STRING,	"key-release",
							"key",		G_TYPE_STRING,	ks,
							NULL);
	if (!structure)
		return false;
	GstEvent *event = gst_event_new_navigation(structure);
	if (!event)
		return false;

	// send event
	return gst_element_send_event(pipeline, event);
}
コード例 #12
0
static void
gst_gtk_base_sink_navigation_send_event (GstNavigation * navigation,
    GstStructure * structure)
{
  GstGtkBaseSink *sink = GST_GTK_BASE_SINK (navigation);
  GstEvent *event;
  GstPad *pad;

  event = gst_event_new_navigation (structure);
  pad = gst_pad_get_peer (GST_VIDEO_SINK_PAD (sink));

  GST_TRACE_OBJECT (sink, "navigation event %" GST_PTR_FORMAT, structure);

  if (GST_IS_PAD (pad) && GST_IS_EVENT (event)) {
    if (!gst_pad_send_event (pad, gst_event_ref (event))) {
      /* If upstream didn't handle the event we'll post a message with it
       * for the application in case it wants to do something with it */
      gst_element_post_message (GST_ELEMENT_CAST (sink),
          gst_navigation_message_new_event (GST_OBJECT_CAST (sink), event));
    }
    gst_event_unref (event);
    gst_object_unref (pad);
  }
}