Beispiel #1
0
/**
 * fs_session_parse_telephony_event_started:
 * @session: a #FsSession to match against the message
 * @message: a #GstMessage to parse
 * @method: (out): Returns the #FsDTMFMethod in the message if not %NULL.
 * @event: (out): Returns the #FsDTMFEvent in the message if not %NULL.
 * @volume: (out): Returns the volume in the message if not %NULL.
 *
 * Parses a "farstream-telephony-event-started" message and checks if it matches
 * the @session parameters.
 *
 * Returns: %TRUE if the message matches the session and is valid.
 */
gboolean
fs_session_parse_telephony_event_started (FsSession *session,
    GstMessage *message,
    FsDTMFMethod *method, FsDTMFEvent *event,
    guint8 *volume)
{
  const GstStructure *s;
  const GValue *value;

  g_return_val_if_fail (session != NULL, FALSE);

  if (!check_message (message, session, "farstream-telephony-event-started"))
    return FALSE;

  s = gst_message_get_structure (message);

  if (!gst_structure_has_field_typed (s, "method", FS_TYPE_DTMF_METHOD))
    return FALSE;
  if (method)
    gst_structure_get_enum (s, "method", FS_TYPE_DTMF_METHOD, (gint*) method);

  if (!gst_structure_has_field_typed (s, "event", FS_TYPE_DTMF_EVENT))
    return FALSE;
  if (event)
    gst_structure_get_enum (s, "event", FS_TYPE_DTMF_EVENT, (gint*) event);

  value = gst_structure_get_value (s, "volume");
  if (!value || !G_VALUE_HOLDS (value, G_TYPE_UCHAR))
    return FALSE;
  if (volume)
    *volume = g_value_get_uchar (value);

  return TRUE;
}
static void
fs_rtp_conference_handle_message (
    GstBin * bin,
    GstMessage * message)
{
  FsRtpConference *self = FS_RTP_CONFERENCE (bin);

  if (!self->gstrtpbin)
    return;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ELEMENT:
    {
      const GstStructure *s = gst_message_get_structure (message);

      /* we change the structure name and add the session ID to it */
      if (gst_structure_has_name (s, "GstRTPBinSDES") &&
          gst_structure_has_field_typed (s, "session", G_TYPE_UINT) &&
          gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT) &&
          gst_structure_has_field_typed (s, "cname", G_TYPE_STRING))
      {
        guint session_id;
        guint ssrc;
        const GValue *val;
        FsRtpSession *session;
        const gchar *cname;

        val = gst_structure_get_value (s, "session");
        session_id = g_value_get_uint (val);

        val = gst_structure_get_value (s, "ssrc");
        ssrc = g_value_get_uint (val);

        cname = gst_structure_get_string (s, "cname");

        session = fs_rtp_conference_get_session_by_id (self, session_id);

        if (session) {
          fs_rtp_session_associate_ssrc_cname (session, ssrc, cname);
          g_object_unref (session);
        } else {
          GST_WARNING_OBJECT (self,"Our GstRtpBin announced a new association"
              "for non-existent session %u for ssrc: %u and cname %s",
              session_id, ssrc, cname);
        }
      }
      /* fallthrough to forward the modified message to the parent */
    }
    default:
    {
      GST_BIN_CLASS (parent_class)->handle_message (bin, message);
      break;
    }
  }
}
Beispiel #3
0
static void
test_missing_suburisource_handler (void)
{
  GstStructure *s;
  GstMessage *msg;
  GstElement *playbin;
  GError *err = NULL;
  GstBus *bus;

  playbin = create_playbin ("file:///does/not/exis.t");

  g_object_set (playbin, "suburi", "cookie://withahint.of/cinnamon", NULL);

  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
      GST_STATE_CHANGE_SUCCESS);
  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
      GST_STATE_CHANGE_FAILURE);

  /* there should be at least a missing-plugin message on the bus now and an
   * error message; the missing-plugin message should be first */
  bus = gst_element_get_bus (playbin);

  msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
  fail_unless (msg->structure != NULL);
  s = msg->structure;
  fail_unless (gst_structure_has_name (s, "missing-plugin"));
  fail_unless (gst_structure_has_field_typed (s, "detail", G_TYPE_STRING));
  fail_unless_equals_string (gst_structure_get_string (s, "detail"), "cookie");
  fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
  fail_unless_equals_string (gst_structure_get_string (s, "type"), "urisource");
  gst_message_unref (msg);

  msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);

  /* make sure the error is a CORE MISSING_PLUGIN one */
  gst_message_parse_error (msg, &err, NULL);
  fail_unless (err != NULL);
  fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
      "%s instead of core-error-quark", g_quark_to_string (err->domain));
  fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
      "code %u instead of GST_CORE_ERROR_MISSING_PLUGIN", err->code);
  g_error_free (err);
  gst_message_unref (msg);
  gst_object_unref (bus);

  gst_element_set_state (playbin, GST_STATE_NULL);
  gst_object_unref (playbin);
}
/* doesn't return a ref to the pixbuf */
static GdkPixbuf *
check_message_pixbuf (GstMessage * msg, const gchar * name, gint channels,
    gboolean has_alpha)
{
  GdkPixbuf *pixbuf;
  const GstStructure *s;

  fail_unless (gst_message_get_structure (msg) != NULL);

  s = gst_message_get_structure (msg);
  fail_unless_equals_string (gst_structure_get_name (s), name);

  fail_unless (gst_structure_has_field (s, "pixbuf"));
  fail_unless (gst_structure_has_field_typed (s, "pixel-aspect-ratio",
          GST_TYPE_FRACTION));
  pixbuf =
      GDK_PIXBUF (g_value_get_object (gst_structure_get_value (s, "pixbuf")));
  fail_unless (GDK_IS_PIXBUF (pixbuf));
  fail_unless_equals_int (gdk_pixbuf_get_n_channels (pixbuf), channels);
  fail_unless_equals_int (gdk_pixbuf_get_has_alpha (pixbuf), has_alpha);
  fail_unless_equals_int (gdk_pixbuf_get_width (pixbuf), 319);
  fail_unless_equals_int (gdk_pixbuf_get_height (pixbuf), 241);

  return pixbuf;
}
static GstCaps *
gst_vaapiencode_h265_get_caps (GstVaapiEncode * base_encode)
{
  GstVaapiEncodeH265 *const encode = GST_VAAPIENCODE_H265_CAST (base_encode);
  GstCaps *caps, *allowed_caps;

  caps = gst_caps_from_string (GST_CODEC_CAPS);

  /* Check whether "stream-format" is hvcC mode */
  allowed_caps =
      gst_pad_get_allowed_caps (GST_VAAPI_PLUGIN_BASE_SRC_PAD (encode));
  if (allowed_caps) {
    const char *stream_format = NULL;
    GstStructure *structure;
    guint i, num_structures;

    num_structures = gst_caps_get_size (allowed_caps);
    for (i = 0; !stream_format && i < num_structures; i++) {
      structure = gst_caps_get_structure (allowed_caps, i);
      if (!gst_structure_has_field_typed (structure, "stream-format",
              G_TYPE_STRING))
        continue;
      stream_format = gst_structure_get_string (structure, "stream-format");
    }
    encode->is_hvc = stream_format && strcmp (stream_format, "hvc1") == 0;
    gst_caps_unref (allowed_caps);
  }
  gst_caps_set_simple (caps, "stream-format", G_TYPE_STRING,
      encode->is_hvc ? "hvc1" : "byte-stream", NULL);

  base_encode->need_codec_data = encode->is_hvc;

  /* XXX: update profile and level information */
  return caps;
}
static gboolean
struct_field_has_line (GstStructure *s, const gchar *field, const gchar *value)
{
  const gchar *tmp = gst_structure_get_string (s, field);
  const GValue *v = NULL;
  gint i;

  if (tmp)
    return !strcmp (value, tmp);

  if (!gst_structure_has_field_typed (s, field, GST_TYPE_LIST))
    return FALSE;

  v = gst_structure_get_value (s, field);

  for (i=0; i < gst_value_list_get_size (v); i++)
  {
    const GValue *listval = gst_value_list_get_value (v, i);

    if (G_VALUE_HOLDS_STRING(listval) &&
        !strcmp (value, g_value_get_string (listval)))
      return TRUE;
  }

  return FALSE;
}
static gboolean
caps_are_rtp_caps (const GstCaps * caps, const gchar * media, gchar ** format)
{
  const GstStructure *s;
  const gchar *str;

  g_assert (media != NULL && format != NULL);

  s = gst_caps_get_structure (caps, 0);
  if (!gst_structure_has_name (s, "application/x-rtp"))
    return FALSE;
  if (!gst_structure_has_field_typed (s, "media", G_TYPE_STRING))
    return FALSE;
  str = gst_structure_get_string (s, "media");
  if (str == NULL || !g_str_equal (str, media))
    return FALSE;
  str = gst_structure_get_string (s, "encoding-name");
  if (str == NULL || *str == '\0')
    return FALSE;

  if (strcmp (str, "X-ASF-PF") == 0) {
    *format = g_strdup ("Windows Media");
  } else if (g_str_has_prefix (str, "X-")) {
    *format = g_strdup (str + 2);
  } else {
    *format = g_strdup (str);
  }

  return TRUE;
}
Beispiel #8
0
static gboolean
gst_srtp_dec_sink_setcaps (GstPad * pad, GstObject * parent,
    GstCaps * caps, gboolean is_rtcp)
{
  GstSrtpDec *filter = GST_SRTP_DEC (parent);
  GstPad *otherpad;
  GstStructure *ps;
  gboolean ret = FALSE;

  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  ps = gst_caps_get_structure (caps, 0);

  if (gst_structure_has_field_typed (ps, "ssrc", G_TYPE_UINT) &&
      gst_structure_has_field_typed (ps, "srtp-cipher", G_TYPE_STRING) &&
      gst_structure_has_field_typed (ps, "srtp-auth", G_TYPE_STRING) &&
      gst_structure_has_field_typed (ps, "srtcp-cipher", G_TYPE_STRING) &&
      gst_structure_has_field_typed (ps, "srtcp-auth", G_TYPE_STRING)) {
    guint ssrc;

    gst_structure_get_uint (ps, "ssrc", &ssrc);

    if (!update_session_stream_from_caps (filter, ssrc, caps)) {
      GST_WARNING_OBJECT (pad, "Could not create session from pad caps: %"
          GST_PTR_FORMAT, caps);
      return FALSE;
    }
  }

  caps = gst_caps_copy (caps);
  ps = gst_caps_get_structure (caps, 0);
  gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
      "srtcp-cipher", "srtcp-auth", NULL);

  if (is_rtcp)
    gst_structure_set_name (ps, "application/x-rtcp");
  else
    gst_structure_set_name (ps, "application/x-rtp");

  otherpad = gst_pad_get_element_private (pad);

  ret = gst_pad_set_caps (otherpad, caps);

  gst_caps_unref (caps);

  return ret;
}
Beispiel #9
0
static GstGLTextureTarget
_caps_get_texture_target (GstCaps * caps, GstGLTextureTarget default_target)
{
  GstGLTextureTarget ret = 0;
  GstStructure *s = gst_caps_get_structure (caps, 0);

  if (gst_structure_has_field_typed (s, "texture-target", G_TYPE_STRING)) {
    const gchar *target_str = gst_structure_get_string (s, "texture-target");
    ret = gst_gl_texture_target_from_string (target_str);
  }

  if (!ret)
    ret = default_target;

  return ret;
}
Beispiel #10
0
/**
 * fs_session_parse_telephony_event_stopped:
 * @session: a #FsSession to match against the message
 * @message: a #GstMessage to parse
 * @method: (out): Returns the #FsDTMFMethod in the message if not %NULL.
 *
 * Parses a "farstream-telephony-event-stopped" message and checks if it matches
 * the @session parameters.
 *
 * Returns: %TRUE if the message matches the session and is valid.
 */
gboolean
fs_session_parse_telephony_event_stopped (FsSession *session,
    GstMessage *message,
     FsDTMFMethod *method)
{
  const GstStructure *s;

  g_return_val_if_fail (session != NULL, FALSE);

  if (!check_message (message, session, "farstream-telephony-event-stopped"))
    return FALSE;

  s = gst_message_get_structure (message);

  if (!gst_structure_has_field_typed (s, "method", FS_TYPE_DTMF_METHOD))
    return FALSE;
  if (method)
    gst_structure_get_enum (s, "method", FS_TYPE_DTMF_METHOD, (gint*) method);

  return TRUE;
}
static gboolean
gst_image_freeze_sink_setcaps (GstImageFreeze * self, GstCaps * caps)
{
    gboolean ret = FALSE;
    GstStructure *s;
    gint fps_n, fps_d;
    GstCaps *othercaps, *intersection;
    guint i, n;
    GstPad *pad;

    pad = self->sinkpad;
    caps = gst_caps_make_writable (gst_caps_ref (caps));

    GST_DEBUG_OBJECT (pad, "Setting caps: %" GST_PTR_FORMAT, caps);

    s = gst_caps_get_structure (caps, 0);

    /* 1. Remove framerate */
    gst_structure_remove_field (s, "framerate");
    gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
                       NULL);

    /* 2. Intersect with template caps */
    othercaps = (GstCaps *) gst_pad_get_pad_template_caps (pad);
    intersection = gst_caps_intersect (caps, othercaps);
    GST_DEBUG_OBJECT (pad, "Intersecting: %" GST_PTR_FORMAT, caps);
    GST_DEBUG_OBJECT (pad, "with: %" GST_PTR_FORMAT, othercaps);
    GST_DEBUG_OBJECT (pad, "gave: %" GST_PTR_FORMAT, intersection);
    gst_caps_unref (caps);
    gst_caps_unref (othercaps);
    caps = intersection;
    intersection = othercaps = NULL;

    /* 3. Intersect with downstream peer caps */
    othercaps = gst_pad_peer_query_caps (self->srcpad, caps);
    GST_DEBUG_OBJECT (pad, "Peer query resulted: %" GST_PTR_FORMAT, othercaps);
    gst_caps_unref (caps);
    caps = othercaps;
    othercaps = NULL;

    /* 4. For every candidate check if it's accepted downstream
     * and fixate framerate to nearest 25/1 */
    n = gst_caps_get_size (caps);
    for (i = 0; i < n; i++) {
        GstCaps *candidate = gst_caps_new_empty ();
        GstStructure *s = gst_structure_copy (gst_caps_get_structure (caps, i));

        gst_caps_append_structure (candidate, s);
        if (gst_structure_has_field_typed (s, "framerate", GST_TYPE_FRACTION) ||
                gst_structure_fixate_field_nearest_fraction (s, "framerate", 25, 1)) {
            if (gst_pad_peer_query_accept_caps (self->srcpad, candidate)) {
                gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d);
                if (fps_d != 0) {
                    g_mutex_lock (&self->lock);
                    self->fps_n = fps_n;
                    self->fps_d = fps_d;
                    g_mutex_unlock (&self->lock);
                    GST_DEBUG_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, candidate);
                    gst_pad_set_caps (self->srcpad, candidate);
                    gst_caps_unref (candidate);
                    ret = TRUE;
                    goto done;
                } else {
                    GST_WARNING_OBJECT (pad, "Invalid caps with framerate %d/%d", fps_n,
                                        fps_d);
                }
            }
        }
        gst_caps_unref (candidate);
    }

done:
    if (!ret)
        GST_ERROR_OBJECT (pad, "No usable caps found");

    gst_caps_unref (caps);

    return ret;
}
Beispiel #12
0
static void
test_pipeline (const char *pipeline)
{
  GstElement *bin, *sink;
  GstPad *pad, *sinkpad;
  GstBus *bus;
  GError *error = NULL;
  GMainLoop *loop;
  GstPadLinkReturn linkret;
  guint bus_watch = 0;

  bin = gst_parse_launch (pipeline, &error);
  fail_unless (bin != NULL, "Error parsing pipeline: %s",
      error ? error->message : "(invalid error)");
  pad = gst_bin_find_unlinked_pad (GST_BIN (bin), GST_PAD_SRC);
  fail_unless (pad != NULL, "Could not locate free src pad");

  /* connect the fake sink */
  sink = gst_element_factory_make ("fakesink", "fake_sink");
  fail_unless (sink != NULL, "Could create fakesink");
  fail_unless (gst_bin_add (GST_BIN (bin), sink), "Could not insert fakesink");
  sinkpad = gst_element_get_static_pad (sink, "sink");
  fail_unless (sinkpad != NULL, "Could not get fakesink src pad");

  linkret = gst_pad_link (pad, sinkpad);
  fail_unless (GST_PAD_LINK_SUCCESSFUL (linkret),
      "Could not link to fake sink");
  gst_object_unref (sinkpad);

  /* run until we receive EOS */
  loop = g_main_loop_new (NULL, FALSE);
  bus = gst_element_get_bus (bin);
  bus_watch = gst_bus_add_watch (bus, (GstBusFunc) eos_watch, loop);
  gst_object_unref (bus);

  start_pipeline (bin, pad);
  g_main_loop_run (loop);

  /* we're EOS now; make sure oggmux out caps have stream headers on them */
  {
    GstStructure *s;
    GstCaps *muxcaps;

    muxcaps = gst_pad_get_negotiated_caps (sinkpad);
    fail_unless (muxcaps != NULL);
    s = gst_caps_get_structure (muxcaps, 0);
    fail_unless (gst_structure_has_name (s, "application/ogg"));
    fail_unless (gst_structure_has_field (s, "streamheader"));
    fail_unless (gst_structure_has_field_typed (s, "streamheader",
            GST_TYPE_ARRAY));
    gst_caps_unref (muxcaps);
  }

  stop_pipeline (bin, pad);

  /* clean up */
  g_main_loop_unref (loop);
  g_source_remove (bus_watch);
  gst_object_unref (pad);
  gst_object_unref (bin);
}
static gboolean
gst_vdp_vpp_sink_setcaps (GstPad * pad, GstCaps * caps)
{
  GstVdpVideoPostProcess *vpp =
      GST_VDP_VIDEO_POST_PROCESS (gst_pad_get_parent (pad));
  GstStructure *structure;
  GstCaps *video_caps = NULL;
  gboolean res = FALSE;

  GstCaps *allowed_caps, *output_caps, *src_caps;

  /* check if the input is non native */
  structure = gst_caps_get_structure (caps, 0);
  if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
    if (!gst_structure_get_fourcc (structure, "format", &vpp->fourcc))
      goto done;
    vpp->native_input = FALSE;
    video_caps = gst_vdp_yuv_to_video_caps (caps);
    if (!video_caps)
      goto done;

    if (!vpp->vpool)
      vpp->vpool = gst_vdp_video_buffer_pool_new (vpp->device);

    gst_vdp_buffer_pool_set_caps (vpp->vpool, video_caps);

  } else {
    vpp->native_input = TRUE;
    video_caps = gst_caps_ref (caps);

    if (vpp->vpool) {
      g_object_unref (vpp->vpool);
      vpp->vpool = NULL;
    }
  }

  structure = gst_caps_get_structure (video_caps, 0);
  if (!gst_structure_get_int (structure, "width", &vpp->width) ||
      !gst_structure_get_int (structure, "height", &vpp->height) ||
      !gst_structure_get_int (structure, "chroma-type",
          (gint *) & vpp->chroma_type))
    goto done;


  /* get interlaced flag */
  gst_structure_get_boolean (structure, "interlaced", &vpp->interlaced);

  /* extract par */
  if (gst_structure_has_field_typed (structure, "pixel-aspect-ratio",
          GST_TYPE_FRACTION)) {
    gst_structure_get_fraction (structure, "pixel-aspect-ratio", &vpp->par_n,
        &vpp->par_d);
    vpp->got_par = TRUE;
  } else
    vpp->got_par = FALSE;

  allowed_caps = gst_pad_get_allowed_caps (vpp->srcpad);
  if (G_UNLIKELY (!allowed_caps))
    goto null_allowed_caps;
  if (G_UNLIKELY (gst_caps_is_empty (allowed_caps)))
    goto empty_allowed_caps;
  GST_DEBUG ("allowed_caps: %" GST_PTR_FORMAT, allowed_caps);

  output_caps = gst_vdp_video_to_output_caps (video_caps);
  src_caps = gst_caps_intersect (output_caps, allowed_caps);
  gst_caps_unref (allowed_caps);
  gst_caps_unref (output_caps);

  if (gst_caps_is_empty (src_caps))
    goto not_negotiated;

  gst_pad_fixate_caps (vpp->srcpad, src_caps);


  if (gst_vdp_vpp_is_interlaced (vpp)) {
    gint fps_n, fps_d;

    if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
      gst_fraction_double (&fps_n, &fps_d);
      gst_caps_set_simple (src_caps, "framerate", GST_TYPE_FRACTION, fps_n,
          fps_d, NULL);
      vpp->field_duration = gst_util_uint64_scale (GST_SECOND, fps_d, fps_n);
    }

    gst_caps_set_simple (src_caps, "interlaced", G_TYPE_BOOLEAN, FALSE, NULL);
  }

  GST_DEBUG ("src_caps: %" GST_PTR_FORMAT, src_caps);

  res = gst_pad_set_caps (vpp->srcpad, src_caps);
  gst_caps_unref (src_caps);

done:
  gst_object_unref (vpp);
  if (video_caps)
    gst_caps_unref (video_caps);

  return res;

null_allowed_caps:
  GST_ERROR_OBJECT (vpp, "Got null from gst_pad_get_allowed_caps");
  goto done;

empty_allowed_caps:
  GST_ERROR_OBJECT (vpp, "Got EMPTY caps from gst_pad_get_allowed_caps");

  gst_caps_unref (allowed_caps);
  goto done;

not_negotiated:
  gst_caps_unref (src_caps);
  GST_ERROR_OBJECT (vpp, "Couldn't find suitable output format");
  goto done;
}
/**
 * update_aspect_filter:
 * @self: camerasrc object
 * @new_caps: new caps of next buffers arriving to view finder sink element
 *
 * Updates aspect ratio capsfilter to maintain aspect ratio, if we need to
 * scale frames for showing them in view finder.
 */
static void
update_aspect_filter (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
{
  // XXX why not instead add a preserve-aspect-ratio property to videoscale?
#if 0
  if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
    GstCaps *sink_caps, *ar_caps;
    GstStructure *st;
    gint in_w = 0, in_h = 0, sink_w = 0, sink_h = 0, target_w = 0, target_h = 0;
    gdouble ratio_w, ratio_h;
    GstPad *sink_pad;
    const GValue *range;

    sink_pad = gst_element_get_static_pad (camera->view_sink, "sink");

    if (sink_pad) {
      sink_caps = gst_pad_get_caps (sink_pad);
      gst_object_unref (sink_pad);
      if (sink_caps) {
        if (!gst_caps_is_any (sink_caps)) {
          GST_DEBUG_OBJECT (camera, "sink element caps %" GST_PTR_FORMAT,
              sink_caps);
          /* Get maximum resolution that view finder sink accepts */
          st = gst_caps_get_structure (sink_caps, 0);
          if (gst_structure_has_field_typed (st, "width", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "width");
            sink_w = gst_value_get_int_range_max (range);
          }
          if (gst_structure_has_field_typed (st, "height", GST_TYPE_INT_RANGE)) {
            range = gst_structure_get_value (st, "height");
            sink_h = gst_value_get_int_range_max (range);
          }
          GST_DEBUG_OBJECT (camera, "sink element accepts max %dx%d", sink_w,
              sink_h);

          /* Get incoming frames' resolution */
          if (sink_h && sink_w) {
            st = gst_caps_get_structure (new_caps, 0);
            gst_structure_get_int (st, "width", &in_w);
            gst_structure_get_int (st, "height", &in_h);
            GST_DEBUG_OBJECT (camera, "new caps with %dx%d", in_w, in_h);
          }
        }
        gst_caps_unref (sink_caps);
      }
    }

    /* If we get bigger frames than view finder sink accepts, then we scale.
       If we scale we need to adjust aspect ratio capsfilter caps in order
       to maintain aspect ratio while scaling. */
    if (in_w && in_h && (in_w > sink_w || in_h > sink_h)) {
      ratio_w = (gdouble) sink_w / in_w;
      ratio_h = (gdouble) sink_h / in_h;

      if (ratio_w < ratio_h) {
        target_w = sink_w;
        target_h = (gint) (ratio_w * in_h);
      } else {
        target_w = (gint) (ratio_h * in_w);
        target_h = sink_h;
      }

      GST_DEBUG_OBJECT (camera, "setting %dx%d filter to maintain aspect ratio",
          target_w, target_h);
      ar_caps = gst_caps_copy (new_caps);
      gst_caps_set_simple (ar_caps, "width", G_TYPE_INT, target_w, "height",
          G_TYPE_INT, target_h, NULL);
    } else {
      GST_DEBUG_OBJECT (camera, "no scaling");
      ar_caps = new_caps;
    }

    GST_DEBUG_OBJECT (camera, "aspect ratio filter caps %" GST_PTR_FORMAT,
        ar_caps);
    g_object_set (G_OBJECT (camera->aspect_filter), "caps", ar_caps, NULL);
    if (ar_caps != new_caps)
      gst_caps_unref (ar_caps);
  }
#endif
}
Beispiel #15
0
static void
test_missing_primary_decoder (void)
{
  GstStructure *s;
  GstMessage *msg;
  GstElement *playbin;
  GError *err = NULL;
  GstBus *bus;
  gchar *use_decodebin2 = getenv ("USE_DECODEBIN2");
  gboolean decodebin2 = use_decodebin2 != NULL && *use_decodebin2 == '1';

  fail_unless (gst_element_register (NULL, "codecsrc", GST_RANK_PRIMARY,
          gst_codec_src_get_type ()));

  playbin = create_playbin ("codec://");

  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_READY),
      GST_STATE_CHANGE_SUCCESS);
  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
      GST_STATE_CHANGE_ASYNC);

  /* there should soon be at least a missing-plugin message on the bus and an
   * error message; the missing-plugin message should be first */
  bus = gst_element_get_bus (playbin);

  msg = gst_bus_poll (bus, GST_MESSAGE_ELEMENT | GST_MESSAGE_ERROR, -1);
  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ELEMENT);
  fail_unless (msg->structure != NULL);
  s = msg->structure;
  fail_unless (gst_structure_has_name (s, "missing-plugin"));
  fail_unless (gst_structure_has_field_typed (s, "type", G_TYPE_STRING));
  fail_unless_equals_string (gst_structure_get_string (s, "type"), "decoder");
  fail_unless (gst_structure_has_field_typed (s, "detail", GST_TYPE_CAPS));
  gst_message_unref (msg);

  msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, -1);
  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);

  /* make sure the error is a STREAM CODEC_NOT_FOUND one */
  gst_message_parse_error (msg, &err, NULL);
  fail_unless (err != NULL);
  if (decodebin2) {
    fail_unless (err->domain == GST_CORE_ERROR, "error has wrong error domain "
        "%s instead of core-error-quark", g_quark_to_string (err->domain));
    fail_unless (err->code == GST_CORE_ERROR_MISSING_PLUGIN, "error has wrong "
        "code %u instead of GST_RESOURCE_ERROR_MISSING_PLUGIN", err->code);
  } else {
    fail_unless (err->domain == GST_STREAM_ERROR,
        "error has wrong error domain " "%s instead of stream-error-quark",
        g_quark_to_string (err->domain));
    fail_unless (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND,
        "error has wrong "
        "code %u instead of GST_STREAM_ERROR_CODEC_NOT_FOUND", err->code);
  }
  g_error_free (err);
  gst_message_unref (msg);
  gst_object_unref (bus);

  gst_element_set_state (playbin, GST_STATE_NULL);
  gst_object_unref (playbin);
}
static gboolean
gst_test_http_src_start (GstBaseSrc * basesrc)
{
  GstTestHTTPSrc *src;
  GstStructure *http_headers;

  src = GST_TEST_HTTP_SRC (basesrc);
  g_mutex_lock (&src->mutex);
  gst_test_http_src_reset_input (src);
  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (("No URL set.")),
        ("Missing location property"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("Callbacks not registered.")), ("Callbacks not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
        (("src_start callback not defined.")),
        ("src_start callback not registered"));
    g_mutex_unlock (&src->mutex);
    return FALSE;
  }
  if (!gst_test_http_src_callbacks->src_start (src, src->uri, &src->input,
          gst_test_http_src_callback_user_data)) {
    if (src->input.status_code == 0) {
      src->input.status_code = 404;
    }
  } else {
    if (src->input.status_code == 0) {
      src->input.status_code = 200;
    }
    src->position = 0;
    src->segment_end = src->input.size;
    gst_base_src_set_dynamic_size (basesrc, FALSE);
    basesrc->segment.duration = src->input.size;
    src->duration_changed = TRUE;
  }
  http_headers = gst_structure_new_empty ("http-headers");
  gst_structure_set (http_headers, "uri", G_TYPE_STRING, src->uri, NULL);
  if (!src->input.request_headers) {
    src->input.request_headers = gst_structure_new_empty ("request-headers");
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "User-Agent", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "User-Agent", G_TYPE_STRING,
        src->user_agent ? src->user_agent : DEFAULT_USER_AGENT, NULL);
  }
  if (!gst_structure_has_field_typed (src->input.request_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "Keep-Alive" : "Close", NULL);
  }
  if (src->compress
      && !gst_structure_has_field_typed (src->input.request_headers,
          "Accept-Encoding", G_TYPE_STRING)) {
    gst_structure_set (src->input.request_headers, "Accept-Encoding",
        G_TYPE_STRING, "compress, gzip", NULL);
  }
  gst_structure_set (http_headers, "request-headers", GST_TYPE_STRUCTURE,
      src->input.request_headers, NULL);
  if (!src->input.response_headers) {
    src->input.response_headers = gst_structure_new_empty ("response-headers");
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Connection", G_TYPE_STRING)) {
    gst_structure_set (src->input.response_headers,
        "Connection", G_TYPE_STRING,
        src->keep_alive ? "keep-alive" : "close", NULL);
  }
  if (!gst_structure_has_field_typed (src->input.response_headers,
          "Date", G_TYPE_STRING)) {
    GDateTime *now;
    gchar *date_str;

    now = g_date_time_new_now_local ();
    fail_unless (now != NULL);
    date_str = g_date_time_format (now, "%a, %e %b %Y %T %Z");
    fail_unless (date_str != NULL);
    gst_structure_set (src->input.response_headers,
        "Date", G_TYPE_STRING, date_str, NULL);
    g_free (date_str);
    g_date_time_unref (now);
  }
  gst_structure_set (http_headers, "response-headers", GST_TYPE_STRUCTURE,
      src->input.response_headers, NULL);
  if (src->http_headers_event) {
    gst_event_unref (src->http_headers_event);
  }
  src->http_headers_event =
      gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_STICKY, http_headers);
  g_mutex_unlock (&src->mutex);
  return TRUE;
}
static gboolean
_bus_callback (GstBus *bus, GstMessage *message, gpointer user_data)
{
  struct SimpleTestConference *dat = user_data;

  switch (GST_MESSAGE_TYPE (message))
  {
    case GST_MESSAGE_ELEMENT:
      {
        const GstStructure *s = gst_message_get_structure (message);
        ts_fail_if (s==NULL, "NULL structure in element message");
        if (gst_structure_has_name (s, "farsight-error"))
        {
          const GValue *value;
          FsError errorno;
          const gchar *error, *debug;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farsight-error from non-farsight element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "debug-msg", G_TYPE_STRING),
              "farsight-error structure has no src-object field");

          value = gst_structure_get_value (s, "error-no");
          errorno = g_value_get_enum (value);
          error = gst_structure_get_string (s, "error-msg");
          debug = gst_structure_get_string (s, "debug-msg");

          ts_fail ("Error on BUS (%d) %s .. %s", errorno, error, debug);
        }
        else if (gst_structure_has_name (s, "farsight-new-local-candidate"))
        {
          FsStream *stream;
          FsCandidate *candidate;
          const GValue *value;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farsight-error from non-farsight element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM),
              "farsight-new-local-candidate structure has no stream field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "candidate", FS_TYPE_CANDIDATE),
              "farsight-new-local-candidate structure has no candidate field");

          value = gst_structure_get_value (s, "stream");
          stream = g_value_get_object (value);

          value = gst_structure_get_value (s, "candidate");
          candidate = g_value_get_boxed (value);

          ts_fail_unless (stream && candidate, "new-local-candidate with NULL"
              " stream(%p) or candidate(%p)", stream, candidate);

          _new_local_candidate (stream, candidate);
        }
        else if (gst_structure_has_name (s,
                "farsight-new-active-candidate-pair"))
        {
          FsStream *stream;
          FsCandidate *local_candidate, *remote_candidate;
          const GValue *value;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farsight-error from non-farsight element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM),
              "farsight-new-active-candidate-pair structure"
              " has no stream field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "local-candidate",
                  FS_TYPE_CANDIDATE),
              "farsight-new-active-candidate-pair structure"
              " has no local-candidate field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "remote-candidate",
                  FS_TYPE_CANDIDATE),
              "farsight-new-active-candidate-pair structure"
              " has no remote-candidate field");

          value = gst_structure_get_value (s, "stream");
          stream = g_value_get_object (value);
          value = gst_structure_get_value (s, "local-candidate");
          local_candidate = g_value_get_boxed (value);
          value = gst_structure_get_value (s, "remote-candidate");
          remote_candidate = g_value_get_boxed (value);

          ts_fail_unless (stream && local_candidate && remote_candidate,
              "new-local-candidate with NULL stream(%p)"
              " or local_candidate(%p) or remote_candidate(%p)",
              stream, local_candidate, remote_candidate);
        }
        else if (gst_structure_has_name (s,
                "farsight-current-send-codec-changed"))
        {
          FsSession *session;
          FsCodec *codec;
          const GValue *value;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farsight-error from non-farsight element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "session", FS_TYPE_SESSION),
              "farsight-current-send-codec-changed structure"
              " has no session field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "codec",
                  FS_TYPE_CODEC),
              "");

          value = gst_structure_get_value (s, "session");
          session = g_value_get_object (value);
          value = gst_structure_get_value (s, "codec");
          codec = g_value_get_boxed (value);

          ts_fail_unless (session && codec,
              "current-send-codec-changed with NULL session(%p) or codec(%p)",
              session, codec);

          _current_send_codec_changed (session, codec);
        }

       }
      break;
    case GST_MESSAGE_ERROR:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_error (message, &error, &debug);

        ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    case GST_MESSAGE_WARNING:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_warning (message, &error, &debug);

        g_debug ("%d: Got a warning on the BUS (%d): %s (%s)", dat->id,
            error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    default:
      break;
  }

  return TRUE;
}
/**
 * gst_basertppayload_set_outcaps:
 * @payload: a #GstBaseRTPPayload
 * @fieldname: the first field name or %NULL
 * @...: field values
 *
 * Configure the output caps with the optional parameters.
 *
 * Variable arguments should be in the form field name, field type
 * (as a GType), value(s).  The last variable argument should be NULL.
 *
 * Returns: %TRUE if the caps could be set.
 */
gboolean
gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload, gchar * fieldname,
    ...)
{
  GstCaps *srccaps, *peercaps;
  gboolean res;

  /* fill in the defaults, there properties cannot be negotiated. */
  srccaps = gst_caps_new_simple ("application/x-rtp",
      "media", G_TYPE_STRING, payload->media,
      "clock-rate", G_TYPE_INT, payload->clock_rate,
      "encoding-name", G_TYPE_STRING, payload->encoding_name, NULL);

  GST_DEBUG_OBJECT (payload, "defaults: %" GST_PTR_FORMAT, srccaps);

  if (fieldname) {
    va_list varargs;

    /* override with custom properties */
    va_start (varargs, fieldname);
    gst_caps_set_simple_valist (srccaps, fieldname, varargs);
    va_end (varargs);

    GST_DEBUG_OBJECT (payload, "custom added: %" GST_PTR_FORMAT, srccaps);
  }

  /* the peer caps can override some of the defaults */
  peercaps = gst_pad_peer_get_caps (payload->srcpad);
  if (peercaps == NULL) {
    /* no peer caps, just add the other properties */
    gst_caps_set_simple (srccaps,
        "payload", G_TYPE_INT, GST_BASE_RTP_PAYLOAD_PT (payload),
        "ssrc", G_TYPE_UINT, payload->current_ssrc,
        "clock-base", G_TYPE_UINT, payload->ts_base,
        "seqnum-base", G_TYPE_UINT, payload->seqnum_base, NULL);

    GST_DEBUG_OBJECT (payload, "no peer caps: %" GST_PTR_FORMAT, srccaps);
  } else {
    GstCaps *temp;
    GstStructure *s, *d;
    const GValue *value;
    gint pt;

    /* peer provides caps we can use to fixate, intersect. This always returns a
     * writable caps. */
    temp = gst_caps_intersect (srccaps, peercaps);
    gst_caps_unref (srccaps);
    gst_caps_unref (peercaps);

    /* now fixate, start by taking the first caps */
    gst_caps_truncate (temp);

    /* get first structure */
    s = gst_caps_get_structure (temp, 0);

    if (gst_structure_get_int (s, "payload", &pt)) {
      /* use peer pt */
      GST_BASE_RTP_PAYLOAD_PT (payload) = pt;
      GST_LOG_OBJECT (payload, "using peer pt %d", pt);
    } else {
      if (gst_structure_has_field (s, "payload")) {
        /* can only fixate if there is a field */
        gst_structure_fixate_field_nearest_int (s, "payload",
            GST_BASE_RTP_PAYLOAD_PT (payload));
        gst_structure_get_int (s, "payload", &pt);
        GST_LOG_OBJECT (payload, "using peer pt %d", pt);
      } else {
        /* no pt field, use the internal pt */
        pt = GST_BASE_RTP_PAYLOAD_PT (payload);
        gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
        GST_LOG_OBJECT (payload, "using internal pt %d", pt);
      }
    }

    if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ssrc");
      payload->current_ssrc = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer ssrc %08x", payload->current_ssrc);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ssrc", G_TYPE_UINT, payload->current_ssrc, NULL);
      GST_LOG_OBJECT (payload, "using internal ssrc %08x",
          payload->current_ssrc);
    }

    if (gst_structure_has_field_typed (s, "clock-base", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "clock-base");
      payload->ts_base = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer clock-base %u", payload->ts_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "clock-base", G_TYPE_UINT, payload->ts_base, NULL);
      GST_LOG_OBJECT (payload, "using internal clock-base %u",
          payload->ts_base);
    }
    if (gst_structure_has_field_typed (s, "seqnum-base", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "seqnum-base");
      payload->seqnum_base = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer seqnum-base %u",
          payload->seqnum_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "seqnum-base", G_TYPE_UINT, payload->seqnum_base,
          NULL);
      GST_LOG_OBJECT (payload, "using internal seqnum-base %u",
          payload->seqnum_base);
    }

    /* make the target caps by copying over all the fixed caps, removing the
     * unfixed caps. */
    srccaps = gst_caps_new_simple (gst_structure_get_name (s), NULL);
    d = gst_caps_get_structure (srccaps, 0);

    gst_structure_foreach (s, (GstStructureForeachFunc) copy_fixed, d);

    gst_caps_unref (temp);

    GST_DEBUG_OBJECT (payload, "with peer caps: %" GST_PTR_FORMAT, srccaps);
  }

  res = gst_pad_set_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload), srccaps);
  gst_caps_unref (srccaps);

  return res;
}
static gboolean
gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc)
{
  GstCaps *srccaps, *peercaps;
  GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
  gboolean ret;

  /* fill in the defaults, there properties cannot be negotiated. */
  srccaps = gst_caps_new_simple ("application/x-rtp",
      "media", G_TYPE_STRING, "audio",
      "encoding-name", G_TYPE_STRING, "TELEPHONE-EVENT", NULL);

  /* the peer caps can override some of the defaults */
  peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
  if (peercaps == NULL) {
    /* no peer caps, just add the other properties */
    gst_caps_set_simple (srccaps,
        "payload", G_TYPE_INT, dtmfsrc->pt,
        "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc,
        "timestamp-offset", G_TYPE_UINT, dtmfsrc->ts_base,
        "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
        "seqnum-offset", G_TYPE_UINT, dtmfsrc->seqnum_base, NULL);

    GST_DEBUG_OBJECT (dtmfsrc, "no peer caps: %" GST_PTR_FORMAT, srccaps);
  } else {
    GstCaps *temp;
    GstStructure *s;
    const GValue *value;
    gint pt;
    gint clock_rate;

    /* peer provides caps we can use to fixate, intersect. This always returns a
     * writable caps. */
    temp = gst_caps_intersect (srccaps, peercaps);
    gst_caps_unref (srccaps);
    gst_caps_unref (peercaps);

    if (!temp) {
      GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
      return FALSE;
    }

    if (gst_caps_is_empty (temp)) {
      GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
      gst_caps_unref (temp);
      return FALSE;
    }

    /* now fixate, start by taking the first caps */
    temp = gst_caps_truncate (temp);
    temp = gst_caps_make_writable (temp);
    srccaps = temp;

    /* get first structure */
    s = gst_caps_get_structure (srccaps, 0);

    if (gst_structure_get_int (s, "payload", &pt)) {
      /* use peer pt */
      dtmfsrc->pt = pt;
      GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
    } else {
      if (gst_structure_has_field (s, "payload")) {
        /* can only fixate if there is a field */
        gst_structure_fixate_field_nearest_int (s, "payload", dtmfsrc->pt);
        gst_structure_get_int (s, "payload", &pt);
        GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
      } else {
        /* no pt field, use the internal pt */
        pt = dtmfsrc->pt;
        gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
        GST_LOG_OBJECT (dtmfsrc, "using internal pt %d", pt);
      }
    }

    if (gst_structure_get_int (s, "clock-rate", &clock_rate)) {
      dtmfsrc->clock_rate = clock_rate;
      GST_LOG_OBJECT (dtmfsrc, "using clock-rate from caps %d",
          dtmfsrc->clock_rate);
    } else {
      GST_LOG_OBJECT (dtmfsrc, "using existing clock-rate %d",
          dtmfsrc->clock_rate);
    }
    gst_structure_set (s, "clock-rate", G_TYPE_INT, dtmfsrc->clock_rate, NULL);


    if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ssrc");
      dtmfsrc->current_ssrc = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer ssrc %08x", dtmfsrc->current_ssrc);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc, NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal ssrc %08x",
          dtmfsrc->current_ssrc);
    }

    if (gst_structure_has_field_typed (s, "timestamp-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "timestamp-offset");
      dtmfsrc->ts_base = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer timestamp-offset %u",
          dtmfsrc->ts_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "timestamp-offset", G_TYPE_UINT, dtmfsrc->ts_base,
          NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal timestamp-offset %u",
          dtmfsrc->ts_base);
    }
    if (gst_structure_has_field_typed (s, "seqnum-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "seqnum-offset");
      dtmfsrc->seqnum_base = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer seqnum-offset %u",
          dtmfsrc->seqnum_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "seqnum-offset", G_TYPE_UINT, dtmfsrc->seqnum_base,
          NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal seqnum-offset %u",
          dtmfsrc->seqnum_base);
    }

    if (gst_structure_has_field_typed (s, "ptime", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ptime");
      dtmfsrc->ptime = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer ptime %u", dtmfsrc->ptime);
    } else if (gst_structure_has_field_typed (s, "maxptime", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "maxptime");
      dtmfsrc->ptime = g_value_get_uint (value);
      GST_LOG_OBJECT (dtmfsrc, "using peer maxptime as ptime %u",
          dtmfsrc->ptime);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ptime", G_TYPE_UINT, dtmfsrc->ptime, NULL);
      GST_LOG_OBJECT (dtmfsrc, "using internal ptime %u", dtmfsrc->ptime);
    }


    GST_DEBUG_OBJECT (dtmfsrc, "with peer caps: %" GST_PTR_FORMAT, srccaps);
  }

  ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
  gst_caps_unref (srccaps);

  dtmfsrc->dirty = FALSE;

  return ret;

}
Beispiel #20
0
static gboolean
_bus_callback (GstBus *bus, GstMessage *message, gpointer user_data)
{
  struct SimpleTestConference *dat = user_data;

  switch (GST_MESSAGE_TYPE (message))
  {

    case GST_MESSAGE_ELEMENT:
      {
        const GstStructure *s = gst_message_get_structure (message);

        if (gst_implements_interface_check (GST_MESSAGE_SRC (message),
                FS_TYPE_CONFERENCE) &&
            gst_structure_has_name (s, "farsight-error"))
        {
          const GValue *value;
          FsError errorno;
          const gchar *error, *debug;
          GEnumClass *enumclass = NULL;
          GEnumValue *enumvalue = NULL;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farsight-error from non-farsight element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING),
              "farsight-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "debug-msg", G_TYPE_STRING),
              "farsight-error structure has no src-object field");

          value = gst_structure_get_value (s, "error-no");
          errorno = g_value_get_enum (value);
          error = gst_structure_get_string (s, "error-msg");
          debug = gst_structure_get_string (s, "debug-msg");


          enumclass = g_type_class_ref (FS_TYPE_ERROR);
          enumvalue = g_enum_get_value (enumclass, errorno);
          ts_fail ("Error on BUS %s (%d, %s) %s .. %s",
              enumvalue->value_name, errorno, enumvalue->value_nick,
              error, debug);
          g_type_class_unref (enumclass);
        }
        else if (gst_structure_has_name (s, "farsight-send-codec-changed"))
        {
          ready_to_send = TRUE;
        }

      }
      break;
    case GST_MESSAGE_ERROR:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_error (message, &error, &debug);

        ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    case GST_MESSAGE_WARNING:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_warning (message, &error, &debug);

        GST_WARNING ("%d: Got a warning on the BUS (%d): %s (%s)", dat->id,
            error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    default:
      break;
  }

  return TRUE;
}
Beispiel #21
0
static void
fs_rtp_conference_handle_message (
    GstBin * bin,
    GstMessage * message)
{
  FsRtpConference *self = FS_RTP_CONFERENCE (bin);

  if (!self->rtpbin)
    goto out;

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ELEMENT:
    {
      const GstStructure *s = gst_message_get_structure (message);

      /* we change the structure name and add the session ID to it */
      if (gst_structure_has_name (s, "application/x-rtp-source-sdes") &&
          gst_structure_has_field_typed (s, "session", G_TYPE_UINT) &&
          gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT) &&
          gst_structure_has_field_typed (s, "cname", G_TYPE_STRING))
      {
        guint session_id;
        guint ssrc;
        const GValue *val;
        FsRtpSession *session;
        const gchar *cname;

        val = gst_structure_get_value (s, "session");
        session_id = g_value_get_uint (val);

        val = gst_structure_get_value (s, "ssrc");
        ssrc = g_value_get_uint (val);

        cname = gst_structure_get_string (s, "cname");

        if (!ssrc || !cname)
        {
          GST_WARNING_OBJECT (self,
              "Got GstRTPBinSDES without a ssrc or a cname (ssrc:%u cname:%p)",
              ssrc, cname);
          break;
        }

        session = fs_rtp_conference_get_session_by_id (self, session_id);

        if (session) {
          fs_rtp_session_associate_ssrc_cname (session, ssrc, cname);
          g_object_unref (session);
        } else {
          GST_WARNING_OBJECT (self,"Our RtpBin announced a new association"
              "for non-existent session %u for ssrc: %u and cname %s",
              session_id, ssrc, cname);
        }
      }
      else if (gst_structure_has_name (s, "dtmf-event-processed") ||
          gst_structure_has_name (s, "dtmf-event-dropped"))
      {
        GList *item;
        guint cookie;


        GST_OBJECT_LOCK (self);
      restart:
        cookie = self->priv->sessions_cookie;
        for (item = self->priv->sessions; item; item = item->next)
        {
          GST_OBJECT_UNLOCK (self);
          if (fs_rtp_session_handle_dtmf_event_message (item->data, message))
          {
            gst_message_unref (message);
            message = NULL;
            goto out;
          }
          GST_OBJECT_LOCK (self);
          if (cookie != self->priv->sessions_cookie)
            goto restart;
        }
        GST_OBJECT_UNLOCK (self);

      }
    }
    break;
    case GST_MESSAGE_STREAM_STATUS:
    {
      GstStreamStatusType type;
      guint i;

      gst_message_parse_stream_status (message, &type, NULL);

      switch (type)
      {
        case GST_STREAM_STATUS_TYPE_ENTER:
          GST_OBJECT_LOCK (self);
          for (i = 0; i < self->priv->threads->len; i++)
          {
            if (g_ptr_array_index (self->priv->threads, i) ==
                g_thread_self ())
              goto done;
          }
          g_ptr_array_add (self->priv->threads, g_thread_self ());
        done:
          GST_OBJECT_UNLOCK (self);
          break;

        case GST_STREAM_STATUS_TYPE_LEAVE:
          GST_OBJECT_LOCK (self);
          while (g_ptr_array_remove_fast (self->priv->threads,
                  g_thread_self ()));
          GST_OBJECT_UNLOCK (self);
          break;

        default:
          /* Do nothing */
          break;
      }
    }
      break;
    default:
      break;
  }

 out:
  /* forward all messages to the parent */
  if (message)
    GST_BIN_CLASS (fs_rtp_conference_parent_class)->handle_message (bin,
        message);
}
Beispiel #22
0
/**
 * gst_rtp_base_payload_set_outcaps:
 * @payload: a #GstRTPBasePayload
 * @fieldname: the first field name or %NULL
 * @...: field values
 *
 * Configure the output caps with the optional parameters.
 *
 * Variable arguments should be in the form field name, field type
 * (as a GType), value(s).  The last variable argument should be NULL.
 *
 * Returns: %TRUE if the caps could be set.
 */
gboolean
gst_rtp_base_payload_set_outcaps (GstRTPBasePayload * payload,
    const gchar * fieldname, ...)
{
  GstCaps *srccaps, *peercaps;
  gboolean res;

  /* fill in the defaults, their properties cannot be negotiated. */
  srccaps = gst_caps_new_simple ("application/x-rtp",
      "media", G_TYPE_STRING, payload->media,
      "clock-rate", G_TYPE_INT, payload->clock_rate,
      "encoding-name", G_TYPE_STRING, payload->encoding_name, NULL);

  GST_DEBUG_OBJECT (payload, "defaults: %" GST_PTR_FORMAT, srccaps);

  if (fieldname) {
    va_list varargs;

    /* override with custom properties */
    va_start (varargs, fieldname);
    gst_caps_set_simple_valist (srccaps, fieldname, varargs);
    va_end (varargs);

    GST_DEBUG_OBJECT (payload, "custom added: %" GST_PTR_FORMAT, srccaps);
  }

  payload->priv->caps_max_ptime = DEFAULT_MAX_PTIME;
  payload->ptime = 0;

  /* the peer caps can override some of the defaults */
  peercaps = gst_pad_peer_query_caps (payload->srcpad, srccaps);
  if (peercaps == NULL) {
    /* no peer caps, just add the other properties */
    gst_caps_set_simple (srccaps,
        "payload", G_TYPE_INT, GST_RTP_BASE_PAYLOAD_PT (payload),
        "ssrc", G_TYPE_UINT, payload->current_ssrc,
        "timestamp-offset", G_TYPE_UINT, payload->ts_base,
        "seqnum-offset", G_TYPE_UINT, payload->seqnum_base, NULL);

    GST_DEBUG_OBJECT (payload, "no peer caps: %" GST_PTR_FORMAT, srccaps);
  } else {
    GstCaps *temp;
    GstStructure *s, *d;
    const GValue *value;
    gint pt;
    guint max_ptime, ptime;

    /* peer provides caps we can use to fixate. They are already intersected
     * with our srccaps, just make them writable */
    temp = gst_caps_make_writable (peercaps);
    gst_caps_unref (srccaps);

    if (gst_caps_is_empty (temp)) {
      gst_caps_unref (temp);
      return FALSE;
    }

    /* now fixate, start by taking the first caps */
    temp = gst_caps_truncate (temp);

    /* get first structure */
    s = gst_caps_get_structure (temp, 0);

    if (gst_structure_get_uint (s, "maxptime", &max_ptime))
      payload->priv->caps_max_ptime = max_ptime * GST_MSECOND;

    if (gst_structure_get_uint (s, "ptime", &ptime))
      payload->ptime = ptime * GST_MSECOND;

    if (gst_structure_get_int (s, "payload", &pt)) {
      /* use peer pt */
      GST_RTP_BASE_PAYLOAD_PT (payload) = pt;
      GST_LOG_OBJECT (payload, "using peer pt %d", pt);
    } else {
      if (gst_structure_has_field (s, "payload")) {
        /* can only fixate if there is a field */
        gst_structure_fixate_field_nearest_int (s, "payload",
            GST_RTP_BASE_PAYLOAD_PT (payload));
        gst_structure_get_int (s, "payload", &pt);
        GST_LOG_OBJECT (payload, "using peer pt %d", pt);
      } else {
        /* no pt field, use the internal pt */
        pt = GST_RTP_BASE_PAYLOAD_PT (payload);
        gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
        GST_LOG_OBJECT (payload, "using internal pt %d", pt);
      }
    }

    if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "ssrc");
      payload->current_ssrc = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer ssrc %08x", payload->current_ssrc);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "ssrc", G_TYPE_UINT, payload->current_ssrc, NULL);
      GST_LOG_OBJECT (payload, "using internal ssrc %08x",
          payload->current_ssrc);
    }

    if (gst_structure_has_field_typed (s, "timestamp-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "timestamp-offset");
      payload->ts_base = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer timestamp-offset %u",
          payload->ts_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "timestamp-offset", G_TYPE_UINT, payload->ts_base,
          NULL);
      GST_LOG_OBJECT (payload, "using internal timestamp-offset %u",
          payload->ts_base);
    }
    if (gst_structure_has_field_typed (s, "seqnum-offset", G_TYPE_UINT)) {
      value = gst_structure_get_value (s, "seqnum-offset");
      payload->seqnum_base = g_value_get_uint (value);
      GST_LOG_OBJECT (payload, "using peer seqnum-offset %u",
          payload->seqnum_base);
    } else {
      /* FIXME, fixate_nearest_uint would be even better */
      gst_structure_set (s, "seqnum-offset", G_TYPE_UINT, payload->seqnum_base,
          NULL);
      GST_LOG_OBJECT (payload, "using internal seqnum-offset %u",
          payload->seqnum_base);
    }

    /* make the target caps by copying over all the fixed caps, removing the
     * unfixed caps. */
    srccaps = gst_caps_new_empty_simple (gst_structure_get_name (s));
    d = gst_caps_get_structure (srccaps, 0);

    gst_structure_foreach (s, (GstStructureForeachFunc) copy_fixed, d);

    gst_caps_unref (temp);

    GST_DEBUG_OBJECT (payload, "with peer caps: %" GST_PTR_FORMAT, srccaps);
  }

  update_max_ptime (payload);

  res = gst_pad_set_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), srccaps);
  gst_caps_unref (srccaps);

  return res;
}
Beispiel #23
0
static gboolean
bus_watch (GstBus *bus, GstMessage *message, gpointer user_data)
{
  struct SimpleMsnConference *dat = user_data;

  switch (GST_MESSAGE_TYPE (message))
  {
    case GST_MESSAGE_ELEMENT:
      {
        const GstStructure *s = gst_message_get_structure (message);
        ts_fail_if (s==NULL, "NULL structure in element message");
        if (gst_structure_has_name (s, "farstream-error"))
        {
          const GValue *value;
          FsError errorno;
          const gchar *error;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farstream-error from non-farstream element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "src-object", G_TYPE_OBJECT),
              "farstream-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-no", FS_TYPE_ERROR),
              "farstream-error structure has no src-object field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "error-msg", G_TYPE_STRING),
              "farstream-error structure has no src-object field");

          value = gst_structure_get_value (s, "error-no");
          errorno = g_value_get_enum (value);
          error = gst_structure_get_string (s, "error-msg");

          ts_fail ("Error on BUS (%d) %s", errorno, error);
        }
        else if (gst_structure_has_name (s, "farstream-new-local-candidate"))
        {
          FsStream *stream;
          FsCandidate *candidate;
          const GValue *value;

          ts_fail_unless (
              gst_implements_interface_check (GST_MESSAGE_SRC (message),
                  FS_TYPE_CONFERENCE),
              "Received farstream-error from non-farstream element");

          ts_fail_unless (
              gst_structure_has_field_typed (s, "stream", FS_TYPE_STREAM),
              "farstream-new-local-candidate structure has no stream field");
          ts_fail_unless (
              gst_structure_has_field_typed (s, "candidate", FS_TYPE_CANDIDATE),
              "farstream-new-local-candidate structure has no candidate field");

          value = gst_structure_get_value (s, "stream");
          stream = g_value_get_object (value);

          value = gst_structure_get_value (s, "candidate");
          candidate = g_value_get_boxed (value);

          ts_fail_unless (stream && candidate, "new-local-candidate with NULL"
              " stream(%p) or candidate(%p)", stream, candidate);

          if (dat->target)
          {
            GError *error = NULL;
            GList *list = g_list_append (NULL, candidate);
            gboolean add_remote_candidates_res;

            GST_DEBUG ("Setting candidate: %s %d",
                candidate->ip, candidate->port);
            add_remote_candidates_res = fs_stream_add_remote_candidates (
                dat->target->stream, list, &error);
            ts_fail_unless (add_remote_candidates_res,
                "Could not set remote candidate: %s",
                error ? error->message : "No GError");
            ts_fail_unless (error == NULL);
            g_list_free (list);
          }
        }
      }
      break;
    case GST_MESSAGE_ERROR:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_error (message, &error, &debug);

        ts_fail ("Got an error on the BUS (%d): %s (%s)", error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    case GST_MESSAGE_WARNING:
      {
        GError *error = NULL;
        gchar *debug = NULL;
        gst_message_parse_warning (message, &error, &debug);

        GST_DEBUG ("%d: Got a warning on the BUS: %s (%s)",
            error->code,
            error->message, debug);
        g_error_free (error);
        g_free (debug);
      }
      break;
    default:
      break;
  }

  return TRUE;
}