Beispiel #1
0
bool GstUtils::link_static_to_request(GstElement * src, GstElement *sink) {
  GstPad *srcpad = gst_element_get_static_pad(src, "src");
  GstPad *sinkpad = gst_element_get_compatible_pad(sink,
                                                   srcpad,
                                                   nullptr);  // const GstCaps *caps to use as a filter
  bool res = GstUtils::check_pad_link_return(gst_pad_link(srcpad, sinkpad));
  if (GST_IS_PAD(src))
    gst_object_unref(srcpad);

  if (GST_IS_PAD(sinkpad))
    gst_object_unref(sinkpad);

  return res;
}
Beispiel #2
0
GstPad *
gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
    GstPadTemplate * templ)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) ==
      GST_PAD_DIRECTION (target), NULL);

  GST_LOG ("name:%s, target:%s:%s, templ:%p", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target), templ);

  if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}
Beispiel #3
0
static gboolean
gst_index_gtype_resolver (GstIndex * index, GstObject * writer,
    gchar ** writer_string, gpointer data)
{
  g_return_val_if_fail (writer != NULL, FALSE);

  if (GST_IS_PAD (writer)) {
    GstObject *element = gst_object_get_parent (GST_OBJECT (writer));
    gchar *name;

    name = gst_object_get_name (writer);
    if (element) {
      *writer_string = g_strdup_printf ("%s.%s",
          G_OBJECT_TYPE_NAME (element), name);
      gst_object_unref (element);
    } else {
      *writer_string = name;
      name = NULL;
    }

    g_free (name);

  } else {
    *writer_string = g_strdup (G_OBJECT_TYPE_NAME (writer));
  }

  return TRUE;
}
Beispiel #4
0
EXPORT_C
#endif

GstPad *
gst_ghost_pad_new (const gchar * name, GstPad * target)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);

  GST_LOG ("name:%s, target:%s:%s", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target));

  if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}
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);
    }
}
Beispiel #6
0
/* FIXME, I think this function is used to work around bad behaviour
 * of elements that add pads to themselves without activating them.
 *
 * Must be called with PAD_LOCK.
 */
static void
gst_collect_pads_set_flushing_unlocked (GstCollectPads * pads,
    gboolean flushing)
{
  GSList *walk = NULL;

  GST_DEBUG ("Setting flushing (%d)", flushing);

  /* Update the pads flushing flag */
  for (walk = pads->data; walk; walk = g_slist_next (walk)) {
    GstCollectData *cdata = walk->data;

    if (GST_IS_PAD (cdata->pad)) {
      GST_OBJECT_LOCK (cdata->pad);
      if (flushing)
        GST_PAD_SET_FLUSHING (cdata->pad);
      else
        GST_PAD_UNSET_FLUSHING (cdata->pad);
      cdata->abidata.ABI.flushing = flushing;
      gst_collect_pads_clear (pads, cdata);
      GST_OBJECT_UNLOCK (cdata->pad);
    }
  }
  /* Setting the pads to flushing means that we changed the values which
   * are 'protected' by the cookie. We therefore update it to force a 
   * recalculation of the current pad status. */
  pads->abidata.ABI.pad_cookie++;
}
static void
dxr3videosink_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  Dxr3VideoSink *sink;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  sink = DXR3VIDEOSINK (gst_pad_get_parent (pad));

  if (GST_IS_EVENT (buf)) {
    dxr3videosink_handle_event (pad, GST_EVENT (buf));
    return;
  }

/*   fprintf (stderr, "^^^^^^ Video block\n"); */

  if (sink->cur_buf == NULL) {
    sink->cur_buf = buf;
  } else {
    sink->cur_buf = gst_buffer_append (sink->cur_buf, buf);
  }

  sink->last_ts = GST_BUFFER_TIMESTAMP (buf);

  dxr3videosink_parse_data (sink);
}
Beispiel #8
0
static void gst_log_android_handler(GstDebugCategory *category,
                 GstDebugLevel level,
                 const gchar *file,
                 const gchar *function,
                 gint line,
                 GObject *object,
                 GstDebugMessage *message,
                 gpointer data)
{
    gchar *obj = NULL;

    OWR_UNUSED(data);

    if (level > gst_debug_category_get_threshold(category))
      return;

    if (GST_IS_PAD(object) && GST_OBJECT_NAME(object)) {
      obj = g_strdup_printf("<%s:%s>", GST_DEBUG_PAD_NAME(object));
    } else if (GST_IS_OBJECT(object)) {
      obj = g_strdup_printf("<%s>", GST_OBJECT_NAME(object));
    }

    __android_log_print(ANDROID_LOG_INFO, "gst_log", "%p %s %s %s:%d:%s:%s %s\n",
            (void *)g_thread_self(),
            gst_debug_level_get_name(level), gst_debug_category_get_name(category),
            file, line, function, obj ? obj : "", gst_debug_message_get(message));

    g_free(obj);
}
Beispiel #9
0
/**
 * gst_proxy_pad_save_thyself:
 * @pad: a ghost #GstPad to save.
 * @parent: the parent #xmlNodePtr to save the description in.
 *
 * Saves the ghost pad into an xml representation.
 *
 * Returns: the #xmlNodePtr representation of the pad.
 */
static xmlNodePtr
gst_proxy_pad_save_thyself (GstObject * object, xmlNodePtr parent)
{
  xmlNodePtr self;
  GstProxyPad *proxypad;
  GstPad *pad;
  GstPad *peer;

  g_return_val_if_fail (GST_IS_PROXY_PAD (object), NULL);

  self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
  xmlNewChild (self, NULL, (xmlChar *) "name",
      (xmlChar *) GST_OBJECT_NAME (object));
  xmlNewChild (self, NULL, (xmlChar *) "parent",
      (xmlChar *) GST_OBJECT_NAME (GST_OBJECT_PARENT (object)));

  proxypad = GST_PROXY_PAD_CAST (object);
  pad = GST_PAD_CAST (proxypad);
  peer = GST_PAD_CAST (pad->peer);

  if (GST_IS_PAD (pad)) {
    if (GST_PAD_IS_SRC (pad))
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "source");
    else if (GST_PAD_IS_SINK (pad))
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "sink");
    else
      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
  } else {
    xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
  }
  if (GST_IS_PAD (peer)) {
    gchar *content = g_strdup_printf ("%s.%s",
        GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));

    xmlNewChild (self, NULL, (xmlChar *) "peer", (xmlChar *) content);
    g_free (content);
  } else {
    xmlNewChild (self, NULL, (xmlChar *) "peer", NULL);
  }

  return self;
}
Beispiel #10
0
/**
 * gst_collect_pads_is_active:
 * @pads: the collectspads to use
 * @pad: the pad to check
 *
 * Check if a pad is active.
 *
 * This function is currently not implemented.
 *
 * Returns: %TRUE if the pad is active.
 *
 * MT safe.
 */
gboolean
gst_collect_pads_is_active (GstCollectPads * pads, GstPad * pad)
{
  g_return_val_if_fail (pads != NULL, FALSE);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), FALSE);
  g_return_val_if_fail (pad != NULL, FALSE);
  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);

  g_warning ("gst_collect_pads_is_active() is not implemented");

  return FALSE;
}
Beispiel #11
0
static void
gst_tarkinenc_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  TarkinEnc *tarkinenc;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  tarkinenc = GST_TARKINENC (gst_pad_get_parent (pad));

  if (!tarkinenc->setup) {
    GST_ELEMENT_ERROR (tarkinenc, CORE, NEGOTIATION, (NULL),
        ("encoder not initialized (input is not tarkin?)"));
    if (GST_IS_BUFFER (buf))
      gst_buffer_unref (buf);
    else
      gst_pad_event_default (pad, GST_EVENT (buf));
    return;
  }

  if (GST_IS_EVENT (buf)) {
    switch (GST_EVENT_TYPE (buf)) {
      case GST_EVENT_EOS:
        tarkin_analysis_framein (tarkinenc->tarkin_stream, NULL, 0, NULL);      /* EOS */
        tarkin_comment_clear (&tarkinenc->tc);
        tarkin_stream_destroy (tarkinenc->tarkin_stream);
      default:
        gst_pad_event_default (pad, GST_EVENT (buf));
        break;
    }
  } else {
    gchar *data;
    gulong size;
    TarkinTime date;

    /* data to encode */
    data = GST_BUFFER_DATA (buf);
    size = GST_BUFFER_SIZE (buf);

    date.numerator = tarkinenc->frame_num;
    date.denominator = 1;
    tarkin_analysis_framein (tarkinenc->tarkin_stream, data, 0, &date);
    tarkinenc->frame_num++;

    gst_buffer_unref (buf);
  }
}
Beispiel #12
0
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);
  }
}
Beispiel #13
0
static GstCaps *
handler (GObject * object, GstCaps * caps, gpointer user_data)
{
  g_print ("in handler %p, %p, %p\n", object, caps, user_data);

  g_assert (GST_IS_PAD (object));

  g_print ("caps: %s\n", gst_caps_to_string (caps));

  if (gst_caps_is_any (caps)) {
    return gst_caps_new_simple ("application/x-foo",
        "field", GST_TYPE_INT_RANGE, 1, 10, NULL);
  }

  return NULL;
}
Beispiel #14
0
static int
gst_ffmpegdata_open (URLContext * h, const char *filename, int flags)
{
    GstProtocolInfo *info;
    GstPad *pad;

    GST_LOG ("Opening %s", filename);

    info = g_new0 (GstProtocolInfo, 1);

    info->set_streamheader = flags & GST_FFMPEG_URL_STREAMHEADER;
    flags &= ~GST_FFMPEG_URL_STREAMHEADER;
    h->flags &= ~GST_FFMPEG_URL_STREAMHEADER;

    /* we don't support R/W together */
    if (flags != URL_RDONLY && flags != URL_WRONLY) {
        GST_WARNING ("Only read-only or write-only are supported");
        return -EINVAL;
    }

    if (sscanf (&filename[12], "%p", &pad) != 1) {
        GST_WARNING ("could not decode pad from %s", filename);
        return -EIO;
    }

    /* make sure we're a pad and that we're of the right type */
    g_return_val_if_fail (GST_IS_PAD (pad), -EINVAL);

    switch (flags) {
    case URL_RDONLY:
        g_return_val_if_fail (GST_PAD_IS_SINK (pad), -EINVAL);
        break;
    case URL_WRONLY:
        g_return_val_if_fail (GST_PAD_IS_SRC (pad), -EINVAL);
        break;
    }

    info->eos = FALSE;
    info->pad = pad;
    info->offset = 0;

    h->priv_data = (void *) info;
    h->is_streamed = FALSE;
    h->max_packet_size = 0;

    return 0;
}
static void
gst_v4lmjpegsink_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  GstV4lMjpegSink *v4lmjpegsink;
  gint num;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  v4lmjpegsink = GST_V4LMJPEGSINK (gst_pad_get_parent (pad));

  if (v4lmjpegsink->clock) {
    GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT,
        GST_BUFFER_TIMESTAMP (buf));

    gst_element_wait (GST_ELEMENT (v4lmjpegsink), GST_BUFFER_TIMESTAMP (buf));
  }
#if 0
  if (GST_BUFFER_POOL (buf) == v4lmjpegsink->bufferpool) {
    num = GPOINTER_TO_INT (GST_BUFFER_POOL_PRIVATE (buf));
    gst_v4lmjpegsink_play_frame (v4lmjpegsink, num);
  } else {
#endif
    /* check size */
    if (GST_BUFFER_SIZE (buf) > v4lmjpegsink->breq.size) {
      GST_ELEMENT_ERROR (v4lmjpegsink, RESOURCE, WRITE, (NULL),
          ("Buffer too big (%d KB), max. buffersize is %ld KB",
              GST_BUFFER_SIZE (buf) / 1024, v4lmjpegsink->breq.size / 1024));
      return;
    }

    /* put JPEG data to the device */
    gst_v4lmjpegsink_wait_frame (v4lmjpegsink, &num);
    memcpy (gst_v4lmjpegsink_get_buffer (v4lmjpegsink, num),
        GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
    gst_v4lmjpegsink_play_frame (v4lmjpegsink, num);
#if 0
  }
#endif

  g_signal_emit (G_OBJECT (v4lmjpegsink),
      gst_v4lmjpegsink_signals[SIGNAL_FRAME_DISPLAYED], 0);

  gst_buffer_unref (buf);
}
Beispiel #16
0
static void pad_linked (GstPad *pad, GstPad *peer, PipelineChangeListenerContext *ctx)
{
	GST_INFO_OBJECT (pad, "");
	GstElement *elem = NULL;
	GstObject *obj = NULL;

	/* in the case of GstGhostPad (and probably other proxy pads)
	 * the parent is actually the pad we are a proxy for, so
	 * keep looping until we find the GstElement
	 */
	while (peer != NULL)
	{
		if(obj)
		{
			gst_object_unref (obj);
		}

		obj = gst_pad_get_parent (peer);

		if( GST_IS_PAD(obj) )
		{
			peer = GST_PAD (obj);
		}
		else
		{
			elem = GST_ELEMENT (obj);
			break;
		}
	}

	if (G_LIKELY (elem))
	{
		hook_element (elem, ctx);

		if (ctx->needs_cb && ctx->cb)
		{
			GST_INFO ("going to call callback");
			ctx->cb (ctx->elem);
			ctx->needs_cb = FALSE;
		}
	}

	if(obj)
	{
		gst_object_unref (obj);
	}
}
Beispiel #17
0
static void
gst_rtjpegdec_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  GstRTJpegDec *rtjpegdec;
  guchar *data;
  gulong size;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  rtjpegdec = GST_RTJPEGDEC (GST_OBJECT_PARENT (pad));
  data = GST_BUFFER_DATA (buf);
  size = GST_BUFFER_SIZE (buf);

  g_warning ("would be encoding frame here\n");

  gst_pad_push (rtjpegdec->srcpad, GST_DATA (buf));
}
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);
}
static void
gst_hermes_colorspace_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  GstHermesColorspace *space;
  GstBuffer *outbuf = NULL;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  space = GST_HERMES_COLORSPACE (gst_pad_get_parent (pad));

  g_return_if_fail (space != NULL);
  g_return_if_fail (GST_IS_COLORSPACE (space));

  if (space->passthru) {
    gst_pad_push (space->srcpad, _data);
    return;
  }

  if (GST_BUFFER_SIZE (buf) < space->sink_size) {
    g_critical ("input size is smaller than expected");
  }

  outbuf =
      gst_pad_alloc_buffer_and_set_caps (space->srcpad, GST_BUFFER_OFFSET_NONE,
      space->src_size);

  Hermes_ConverterCopy (space->h_handle,
      GST_BUFFER_DATA (buf), 0, 0, space->width, space->height,
      space->sink_stride, GST_BUFFER_DATA (outbuf), 0, 0,
      space->width, space->height, space->src_stride);

  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);

  gst_buffer_unref (buf);
  gst_pad_push (space->srcpad, GST_DATA (outbuf));
}
static void
_determine_reporting_level (GstValidateMonitor * monitor)
{
  GstValidateRunner *runner;
  GstObject *object, *parent;
  gchar *object_name;
  GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN;

  object = gst_validate_monitor_get_target (monitor);
  runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor));

  do {
    if (!GST_IS_OBJECT (object))
      break;

    /* Let's allow for singling out pads */
    if (GST_IS_PAD (object)) {
      level = _get_report_level_for_pad (runner, object);
      if (level != GST_VALIDATE_SHOW_UNKNOWN)
        break;
    }

    object_name = gst_object_get_name (object);
    level = gst_validate_runner_get_reporting_level_for_name (runner,
        object_name);
    parent = gst_object_get_parent (object);
    gst_object_unref (object);
    object = parent;
    g_free (object_name);
  } while (object && level == GST_VALIDATE_SHOW_UNKNOWN);

  if (object)
    gst_object_unref (object);

  if (runner)
    gst_object_unref (runner);

  monitor->level = level;
}
Beispiel #21
0
static gboolean
gst_index_gtype_resolver (GstIndex * index, GstObject * writer,
    gchar ** writer_string, gpointer data)
{
  if (GST_IS_PAD (writer)) {
    GstElement *element =
        (GstElement *) gst_object_get_parent (GST_OBJECT (writer));
    gchar *name;

    name = gst_object_get_name (writer);
    *writer_string = g_strdup_printf ("%s.%s",
        g_type_name (G_OBJECT_TYPE (element)), name);

    gst_object_unref (element);
    g_free (name);

  } else {
    *writer_string =
        g_strdup_printf ("%s", g_type_name (G_OBJECT_TYPE (writer)));
  }

  return TRUE;
}
GstStreamInfo *
gst_stream_info_new (GstObject * object,
    GstStreamType type, const gchar * decoder, const GstCaps * caps)
{
  GstStreamInfo *info;

  info = g_object_new (GST_TYPE_STREAM_INFO, NULL);

  gst_object_ref (object);
  if (GST_IS_PAD (object)) {
    gst_pad_add_event_probe (GST_PAD_CAST (object),
        G_CALLBACK (cb_probe), info);
  }
  info->object = object;
  info->type = type;
  info->decoder = g_strdup (decoder);
  info->origin = object;
  if (caps) {
    info->caps = gst_caps_copy (caps);
  }

  return info;
}
Beispiel #23
0
static void
dxr3spusink_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  Dxr3SpuSink *sink;
  gint bytes_written = 0;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  sink = DXR3SPUSINK (gst_pad_get_parent (pad));

  if (GST_IS_EVENT (buf)) {
    dxr3spusink_handle_event (pad, GST_EVENT (buf));
    return;
  }

  if (GST_OBJECT_FLAG_IS_SET (sink, DXR3SPUSINK_OPEN)) {
    /* If we have PTS information for the SPU unit, register it now.
       The card needs the PTS to be written *before* the actual data. */
    if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
      guint pts = (guint) GSTTIME_TO_MPEGTIME (GST_BUFFER_TIMESTAMP (buf));

      ioctl (sink->spu_fd, EM8300_IOCTL_SPU_SETPTS, &pts);
    }

    bytes_written = write (sink->spu_fd, GST_BUFFER_DATA (buf),
        GST_BUFFER_SIZE (buf));
    if (bytes_written < GST_BUFFER_SIZE (buf)) {
      fprintf (stderr, "dxr3spusink: Warning: %d bytes should be written,"
          " only %d bytes written\n", GST_BUFFER_SIZE (buf), bytes_written);
    }
  }

  gst_buffer_unref (buf);
}
Beispiel #24
0
static void
gst_artsdsink_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  GstArtsdsink *artsdsink;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  artsdsink = GST_ARTSDSINK (gst_pad_get_parent (pad));

  if (GST_BUFFER_DATA (buf) != NULL) {
    gst_trace_add_entry (NULL, 0, GPOINTER_TO_INT (buf),
        "artsdsink: writing to server");
    if (!artsdsink->mute && artsdsink->connected) {
      int bytes;
      void *bufptr = GST_BUFFER_DATA (buf);
      int bufsize = GST_BUFFER_SIZE (buf);

      GST_DEBUG ("artsdsink: stream=%p data=%p size=%d",
          artsdsink->stream, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));

      do {
        bytes = arts_write (artsdsink->stream, bufptr, bufsize);
        if (bytes < 0) {
          fprintf (stderr, "arts_write error: %s\n", arts_error_text (bytes));
          gst_buffer_unref (buf);
          return;
        }
        bufptr += bytes;
        bufsize -= bytes;
      } while (bufsize > 0);
    }
  }
  gst_buffer_unref (buf);
}
/**
 * gst_validate_monitor_factory_create:
 * @target: The #GstObject to create a #GstValidateMonitor for
 * @runner: The #GstValidateRunner to use for the new monitor
 * @parent: (nullable): The parent of the new monitor
 *
 * Create a new monitor for @target and starts monitoring it.
 *
 * Returns: (transfer full): The newly created #GstValidateMonitor
 */
GstValidateMonitor *
gst_validate_monitor_factory_create (GstObject * target,
    GstValidateRunner * runner, GstValidateMonitor * parent)
{
  GstValidateMonitor *monitor = NULL;
  g_return_val_if_fail (target != NULL, NULL);

  monitor = g_object_get_data ((GObject *) target, "validate-monitor");
  if (monitor) {
    GST_INFO_OBJECT (target, "Is already monitored by %" GST_PTR_FORMAT,
        monitor);

    return g_object_ref (monitor);
  }

  if (GST_IS_PAD (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pad_monitor_new (GST_PAD_CAST
            (target), runner, GST_VALIDATE_ELEMENT_MONITOR_CAST (parent)));
  } else if (GST_IS_PIPELINE (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pipeline_monitor_new
        (GST_PIPELINE_CAST (target), runner, parent));
  } else if (GST_IS_BIN (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_bin_monitor_new (GST_BIN_CAST
            (target), runner, parent));
  } else if (GST_IS_ELEMENT (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_element_monitor_new
        (GST_ELEMENT_CAST (target), runner, parent));
  } else {
    g_assert_not_reached ();
  }

  return monitor;
}
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);
  }
}
Beispiel #27
0
int
main (int argc, gchar * argv[])
{
  GstElement *element;
  GstElement *element2;
  GstPad *pad;
  long usage1;
  gint i, iters;

  gst_init (&argc, &argv);

  if (argc == 2)
    iters = atoi (argv[1]);
  else
    iters = ITERS;

  g_print ("starting element with pad test with %d iterations\n", iters);
  usage1 = vmsize ();

  element = gst_element_factory_make ("fakesink", NULL);;
  g_assert (GST_IS_ELEMENT (element));
  pad = gst_element_get_pad (element, "sink");
  g_assert (GST_IS_PAD (pad));
  g_assert (GST_OBJECT_IS_FLOATING (element));
  g_assert (!GST_OBJECT_IS_FLOATING (pad));
  g_assert (gst_pad_get_parent (pad) == element);
  gst_object_unref (element);
  g_print ("create/addpad/unref 1 new element: %ld\n", vmsize () - usage1);

  for (i = 0; i < iters; i++) {
    element = gst_element_factory_make ("fakesink", NULL);;
    g_assert (GST_IS_ELEMENT (element));
    gst_object_unref (element);
  }
  g_print ("create/unref %d elements: %ld\n", iters, vmsize () - usage1);

  for (i = 0; i < iters / 2; i++) {
    element = gst_element_factory_make ("fakesink", NULL);
    g_assert (GST_IS_ELEMENT (element));
    element2 = gst_element_factory_make ("fakesrc", NULL);
    g_assert (GST_IS_ELEMENT (element2));
    gst_element_link_pads (element2, "src", element, "sink");
    g_assert (GST_PAD_IS_LINKED (gst_element_get_pad (element2, "src")));
    g_assert (GST_PAD_IS_LINKED (gst_element_get_pad (element, "sink")));
    gst_object_unref (element);
    g_assert (!GST_PAD_IS_LINKED (gst_element_get_pad (element2, "src")));
    gst_object_unref (element2);
  }
  g_print ("create/link/unref %d element duos: %ld\n", iters / 2,
      vmsize () - usage1);

  element = gst_element_factory_make ("fakesink", NULL);;
  g_assert (GST_IS_ELEMENT (element));
  pad = gst_element_get_pad (element, "sink");
  g_assert (GST_IS_PAD (pad));
  gst_element_remove_pad (element, pad);
  g_assert (gst_element_get_pad (element, "sink") == NULL);
  gst_object_unref (element);

  g_print ("pad removal on one element: %ld\n", vmsize () - usage1);

  for (i = 0; i < iters / 2; i++) {
    element = gst_element_factory_make ("fakesink", NULL);;
    g_assert (GST_IS_ELEMENT (element));
    pad = gst_element_get_pad (element, "sink");
    g_assert (GST_IS_PAD (pad));
    gst_element_remove_pad (element, pad);
    g_assert (gst_element_get_pad (element, "sink") == NULL);
    gst_object_unref (element);
  }
  g_print ("pad removal loop on %d elements: %ld\n", iters / 2,
      vmsize () - usage1);

  for (i = 0; i < iters / 2; i++) {
    element = gst_element_factory_make ("fakesink", NULL);;
    g_assert (GST_IS_ELEMENT (element));
    pad = gst_element_get_pad (element, "sink");
    g_assert (GST_IS_PAD (pad));
    gst_object_ref (pad);
    gst_element_remove_pad (element, pad);
    g_assert (gst_pad_get_parent (pad) == NULL);
    gst_object_unref (pad);
    gst_object_unref (element);
  }
  g_print ("pad ref/removal/test loop on %d elements: %ld\n", iters / 2,
      vmsize () - usage1);

  element = gst_element_factory_make ("fakesink", NULL);;
  g_assert (GST_IS_ELEMENT (element));
  pad = gst_element_get_pad (element, "sink");
  g_assert (GST_IS_PAD (pad));
  gst_object_unref (element);

  g_print ("pad unref on one element: %ld\n", vmsize () - usage1);

  for (i = 0; i < iters / 2; i++) {
    element = gst_element_factory_make ("fakesink", NULL);
    g_assert (GST_IS_ELEMENT (element));
    pad = gst_element_get_pad (element, "sink");
    g_assert (GST_IS_PAD (pad));
    gst_object_unref (element);
  }
  g_print ("pad unref loop on %d elements: %ld\n", iters / 2,
      vmsize () - usage1);

  g_print ("leaked: %ld\n", vmsize () - usage1);

  return 0;
}
Beispiel #28
0
void test_parse_bin_from_description()
{
  struct
  {
    const gchar *bin_desc;
    const gchar *pad_names;
  } bin_tests[] = {
    {
    "identity", "identity0/sink,identity0/src"}, {
    "identity ! identity ! identity", "identity1/sink,identity3/src"}, {
    "identity ! fakesink", "identity4/sink"}, {
    "fakesrc ! identity", "identity5/src"}, {
    "fakesrc ! fakesink", ""}
  };
  gint i;
  
  xmlfile = "gstutils_test_parse_bin_from_description";
  std_log(LOG_FILENAME_LINE, "Test Started gstutils_test_parse_bin_from_description");

  for (i = 0; i < G_N_ELEMENTS (bin_tests); ++i) {
    GstElement *bin, *parent;
    GString *s;
    GstPad *ghost_pad, *target_pad;
    GError *err = NULL;

    bin = gst_parse_bin_from_description (bin_tests[i].bin_desc, TRUE, &err);
    if (err) {
      g_error ("ERROR in gst_parse_bin_from_description (%s): %s",
          bin_tests[i].bin_desc, err->message);
    }
    g_assert (bin != NULL);

    s = g_string_new ("");
    if ((ghost_pad = gst_element_get_pad (bin, "sink"))) {
      g_assert (GST_IS_GHOST_PAD (ghost_pad));

      target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (ghost_pad));
      g_assert (target_pad != NULL);
      g_assert (GST_IS_PAD (target_pad));

      parent = gst_pad_get_parent_element (target_pad);
      g_assert (parent != NULL);

      g_string_append_printf (s, "%s/sink", GST_ELEMENT_NAME (parent));

      gst_object_unref (parent);
      gst_object_unref (target_pad);
      gst_object_unref (ghost_pad);
    }

    if ((ghost_pad = gst_element_get_pad (bin, "src"))) {
      g_assert (GST_IS_GHOST_PAD (ghost_pad));

      target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (ghost_pad));
      g_assert (target_pad != NULL);
      g_assert (GST_IS_PAD (target_pad));

      parent = gst_pad_get_parent_element (target_pad);
      g_assert (parent != NULL);

      if (s->len > 0) {
        g_string_append (s, ",");
      }

      g_string_append_printf (s, "%s/src", GST_ELEMENT_NAME (parent));

      gst_object_unref (parent);
      gst_object_unref (target_pad);
      gst_object_unref (ghost_pad);
    }

    if (strcmp (s->str, bin_tests[i].pad_names) != 0) {
      g_error ("FAILED: expted '%s', got '%s' for bin '%s'",
          bin_tests[i].pad_names, s->str, bin_tests[i].bin_desc);
    }
    g_string_free (s, TRUE);

    gst_object_unref (bin);
  }
  std_log(LOG_FILENAME_LINE, "Test Successful");
  create_xml(0);
}
Beispiel #29
0
static void
gst_median_chain (GstPad * pad, GstData * _data)
{
  GstBuffer *buf = GST_BUFFER (_data);
  GstMedian *median;
  guchar *data;
  gulong size;
  GstBuffer *outbuf;

/*  GstMeta *meta; */
  int lumsize, chromsize;

  g_return_if_fail (pad != NULL);
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (buf != NULL);

  median = GST_MEDIAN (GST_OBJECT_PARENT (pad));

  if (!median->active) {
    gst_pad_push (median->srcpad, GST_DATA (buf));
    return;
  }

  data = GST_BUFFER_DATA (buf);
  size = GST_BUFFER_SIZE (buf);

  GST_DEBUG ("median: have buffer of %d", GST_BUFFER_SIZE (buf));

  outbuf = gst_buffer_new ();
  GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (buf));
  GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf);

  lumsize = median->width * median->height;
  chromsize = lumsize / 4;

  if (median->filtersize == 5) {
    median_5 (data, GST_BUFFER_DATA (outbuf), median->width, median->height);
    if (!median->lum_only) {
      median_5 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize,
          median->width / 2, median->height / 2);
      median_5 (data + lumsize + chromsize,
          GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2,
          median->height / 2);
    } else {
      memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize,
          chromsize * 2);
    }
  } else {
    median_9 (data, GST_BUFFER_DATA (outbuf), median->width, median->height);
    if (!median->lum_only) {
      median_9 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize,
          median->width / 2, median->height / 2);
      median_9 (data + lumsize + chromsize,
          GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2,
          median->height / 2);
    } else {
      memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize,
          chromsize * 2);
    }
  }
  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);

  gst_buffer_unref (buf);

  gst_pad_push (median->srcpad, GST_DATA (outbuf));
}
Beispiel #30
0
static void
do_element_stats (GstStatsTracer * self, GstPad * pad, GstClockTime elapsed1,
    GstClockTime elapsed2)
{
  GstClockTimeDiff elapsed = GST_CLOCK_DIFF (elapsed1, elapsed2);
  GstObject *parent = GST_OBJECT_PARENT (pad);
  GstElement *this =
      GST_ELEMENT_CAST (GST_IS_PAD (parent) ? GST_OBJECT_PARENT (parent) :
      parent);
  GstElementStats *this_stats = get_element_stats (self, this);
  GstPad *peer_pad = GST_PAD_PEER (pad);
  GstElementStats *peer_stats;

  if (!peer_pad)
    return;

  /* walk the ghost pad chain downstream to get the real pad */
  /* if parent of peer_pad is a ghost-pad, then peer_pad is a proxy_pad */
  parent = GST_OBJECT_PARENT (peer_pad);
  if (parent && GST_IS_GHOST_PAD (parent)) {
    peer_pad = GST_PAD_CAST (parent);
    /* if this is now the ghost pad, get the peer of this */
    get_pad_stats (self, peer_pad);
    if ((parent = GST_OBJECT_PARENT (peer_pad))) {
      get_element_stats (self, GST_ELEMENT_CAST (parent));
    }
    peer_pad = GST_PAD_PEER (GST_GHOST_PAD_CAST (peer_pad));
    parent = peer_pad ? GST_OBJECT_PARENT (peer_pad) : NULL;
  }
  /* walk the ghost pad chain upstream to get the real pad */
  /* if peer_pad is a ghost-pad, then parent is a bin and it is the parent of
   * a proxy_pad */
  while (peer_pad && GST_IS_GHOST_PAD (peer_pad)) {
    get_pad_stats (self, peer_pad);
    get_element_stats (self, GST_ELEMENT_CAST (parent));
    peer_pad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (peer_pad));
    parent = peer_pad ? GST_OBJECT_PARENT (peer_pad) : NULL;
  }

  if (!parent) {
    printf ("%" GST_TIME_FORMAT
        " transmission on unparented target pad %s_%s -> %s_%s\n",
        GST_TIME_ARGS (elapsed), GST_DEBUG_PAD_NAME (pad),
        GST_DEBUG_PAD_NAME (peer_pad));
    return;
  }
  peer_stats = get_element_stats (self, GST_ELEMENT_CAST (parent));

  /* we'd like to gather time spend in each element, but this does not make too
   * much sense yet
   * pure push/pull-based:
   *   - the time spend in the push/pull_range is accounted for the peer and
   *     removed from the current element
   *   - this works for chains
   *   - drawback is sink elements that block to sync have a high time usage
   *     - we could rerun the ests with sync=false
   * both:
   *   - a.g. demuxers both push and pull. thus we subtract time for the pull
   *     and the push operations, but never add anything.
   *   - can we start a counter after push/pull in such elements and add then
   *     time to the element upon next pad activity?
   */
#if 1
  /* this does not make sense for demuxers */
  this_stats->treal -= elapsed;
  peer_stats->treal += elapsed;
#else
  /* this creates several >100% figures */
  this_stats->treal += GST_CLOCK_DIFF (this_stats->last_ts, elapsed2) - elapsed;
  peer_stats->treal += elapsed;
  this_stats->last_ts = elapsed2;
  peer_stats->last_ts = elapsed2;
#endif
}