static GstCaps *
gst_video_test_src_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstStructure *structure;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
  if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
    gst_structure_fixate_field_nearest_fraction (structure,
        "pixel-aspect-ratio", 1, 1);
  if (gst_structure_has_field (structure, "colorimetry"))
    gst_structure_fixate_field_string (structure, "colorimetry", "bt601");
  if (gst_structure_has_field (structure, "chroma-site"))
    gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");

  if (gst_structure_has_field (structure, "interlace-mode"))
    gst_structure_fixate_field_string (structure, "interlace-mode",
        "progressive");

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);

  return caps;
}
static GstCaps *
gst_inter_video_src_fixate (GstBaseSrc * src, GstCaps * caps)
{
  GstInterVideoSrc *intervideosrc = GST_INTER_VIDEO_SRC (src);
  GstStructure *structure;

  GST_DEBUG_OBJECT (intervideosrc, "fixate");

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
  if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
    gst_structure_fixate_field_nearest_fraction (structure,
        "pixel-aspect-ratio", 1, 1);
  if (gst_structure_has_field (structure, "color-matrix"))
    gst_structure_fixate_field_string (structure, "color-matrix", "sdtv");
  if (gst_structure_has_field (structure, "chroma-site"))
    gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");

  if (gst_structure_has_field (structure, "interlaced"))
    gst_structure_fixate_field_boolean (structure, "interlaced", FALSE);

  return caps;
}
Example #3
0
/* this function is a bit of a last resort */
static GstCaps *
gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure;
  gint i;

  GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);

  caps = gst_caps_make_writable (caps);

  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    structure = gst_caps_get_structure (caps, i);

    /* We are fixating to a reasonable 320x200 resolution
       and the maximum framerate resolution for that size */
    if (gst_structure_has_field (structure, "width"))
      gst_structure_fixate_field_nearest_int (structure, "width", 320);

    if (gst_structure_has_field (structure, "height"))
      gst_structure_fixate_field_nearest_int (structure, "height", 200);

    if (gst_structure_has_field (structure, "framerate"))
      gst_structure_fixate_field_nearest_fraction (structure, "framerate",
          G_MAXINT, 1);

    if (gst_structure_has_field (structure, "format"))
      gst_structure_fixate_field (structure, "format");
  }

  GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (basesrc, caps);

  return caps;
}
bool tcam_gst_fixate_caps (GstCaps* caps)
{
    if (caps == nullptr
        || gst_caps_is_empty(caps)
        || gst_caps_is_any(caps))
    {
        return FALSE;
    }

    GstStructure* structure = gst_caps_get_structure(caps, 0);

    if (gst_structure_has_field(structure, "width"))
    {
        gst_structure_fixate_field_nearest_int(structure, "width", G_MAXINT);
    }
    if (gst_structure_has_field(structure, "height"))
    {
        gst_structure_fixate_field_nearest_int(structure, "height", G_MAXINT);
    }
    if (gst_structure_has_field(structure, "framerate"))
    {
        gst_structure_fixate_field_nearest_fraction(structure, "framerate", G_MAXINT, 1);
    }

    return TRUE;
}
static GstCaps *
gst_dshowvideosrc_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
    /* If there is no desired video size, set default video size to device preffered video size */

    GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc);
    GstStructure *structure = gst_caps_get_structure (caps, 0);
    guint i = 0;
    gint res = -1;

    for (; i < gst_caps_get_size (src->caps) && res == -1; i++) {
        GstCaps *capstmp = gst_caps_copy_nth (src->caps, i);

        if (gst_caps_is_subset (caps, capstmp)) {
            res = i;
        }
        gst_caps_unref (capstmp);
    }

    if (res != -1) {
        GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res);
        if (type_pin_mediatype) {
            GstCapturePinMediaType *pin_mediatype =
                (GstCapturePinMediaType *) type_pin_mediatype->data;
            gst_structure_fixate_field_nearest_int (structure, "width",
                                                    pin_mediatype->defaultWidth);
            gst_structure_fixate_field_nearest_int (structure, "height",
                                                    pin_mediatype->defaultHeight);
            gst_structure_fixate_field_nearest_fraction (structure, "framerate",
                    pin_mediatype->defaultFPS, 1);
        }
    }

    return GST_BASE_SRC_CLASS (gst_dshowvideosrc_parent_class)->fixate (bsrc, caps);
}
Example #6
0
static void
gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", G_MAXINT);
  gst_structure_fixate_field_nearest_int (structure, "height", G_MAXINT);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate",
      G_MAXINT, 1);
}
Example #7
0
static void
gst_video_test_src_src_fixate (GstPad * pad, GstCaps * caps)
{
  GstStructure *structure;

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
}
Example #8
0
static GstCaps *
gst_video_rate_fixate_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
  GstStructure *s;
  gint num, denom;
  const GValue *par;

  s = gst_caps_get_structure (caps, 0);
  if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
    return othercaps;

  othercaps = gst_caps_truncate (othercaps);
  othercaps = gst_caps_make_writable (othercaps);
  s = gst_caps_get_structure (othercaps, 0);
  gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);

  if ((par = gst_structure_get_value (s, "pixel-aspect-ratio")))
    gst_structure_fixate_field_nearest_fraction (s, "pixel-aspect-ratio", 1, 1);

  return othercaps;
}
Example #9
0
static void
gst_video_rate_fixate_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
  GstStructure *s;
  gint num, denom;

  s = gst_caps_get_structure (caps, 0);
  if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
    return;

  s = gst_caps_get_structure (othercaps, 0);
  gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);
}
Example #10
0
static gboolean
gst_vis_src_negotiate (GstVisual * visual)
{
  GstCaps *othercaps, *target, *intersect;
  GstStructure *structure;
  GstCaps *caps;

  caps = gst_pad_get_caps (visual->srcpad);

  /* see what the peer can do */
  othercaps = gst_pad_peer_get_caps (visual->srcpad);
  if (othercaps) {
    intersect = gst_caps_intersect (othercaps, caps);
    gst_caps_unref (othercaps);
    gst_caps_unref (caps);

    if (gst_caps_is_empty (intersect))
      goto no_format;

    target = gst_caps_copy_nth (intersect, 0);
    gst_caps_unref (intersect);
  } else {
    /* need a copy, we'll be modifying it when fixating */
    target = gst_caps_copy (caps);
    gst_caps_unref (caps);
  }

  /* fixate in case something is not fixed. This does nothing if the value is
   * already fixed. For video we always try to fixate to something like
   * 320x240x30 by convention. */
  structure = gst_caps_get_structure (target, 0);
  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);

  gst_pad_set_caps (visual->srcpad, target);
  gst_caps_unref (target);

  return TRUE;

  /* ERRORS */
no_format:
  {
    GST_ELEMENT_ERROR (visual, STREAM, FORMAT, (NULL),
        ("could not negotiate output format"));
    gst_caps_unref (intersect);
    return FALSE;
  }
}
Example #11
0
/* this function is a bit of a last resort */
static void
gst_v4lsrc_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
    GstStructure *structure;
    int i;
    int targetwidth, targetheight;
    GstV4lSrc *v4lsrc = GST_V4LSRC (bsrc);
    struct video_capability *vcap = &GST_V4LELEMENT (v4lsrc)->vcap;
    struct video_window *vwin = &GST_V4LELEMENT (v4lsrc)->vwin;

    if (GST_V4L_IS_OPEN (GST_V4LELEMENT (v4lsrc))) {
        GST_DEBUG_OBJECT (v4lsrc, "device reported w: %d-%d, h: %d-%d",
                          vcap->minwidth, vcap->maxwidth, vcap->minheight, vcap->maxheight);
        targetwidth = vcap->minwidth;
        targetheight = vcap->minheight;
        /* if we can get the current vwin settings, we use those to fixate */
        if (!gst_v4l_get_capabilities (GST_V4LELEMENT (v4lsrc)))
            GST_DEBUG_OBJECT (v4lsrc, "failed getting capabilities");
        else {
            targetwidth = vwin->width;
            targetheight = vwin->height;
        }
    } else {
        GST_DEBUG_OBJECT (v4lsrc, "device closed, guessing");
        targetwidth = 320;
        targetheight = 200;
    }

    GST_DEBUG_OBJECT (v4lsrc, "targetting %dx%d", targetwidth, targetheight);

    for (i = 0; i < gst_caps_get_size (caps); ++i) {
        const GValue *v;

        structure = gst_caps_get_structure (caps, i);
        gst_structure_fixate_field_nearest_int (structure, "width", targetwidth);
        gst_structure_fixate_field_nearest_int (structure, "height", targetheight);
        gst_structure_fixate_field_nearest_fraction (structure, "framerate", 15, 2);

        v = gst_structure_get_value (structure, "format");
        if (v && G_VALUE_TYPE (v) != GST_TYPE_FOURCC) {
            guint32 fourcc;

            g_return_if_fail (G_VALUE_TYPE (v) == GST_TYPE_LIST);

            fourcc = gst_value_get_fourcc (gst_value_list_get_value (v, 0));
            gst_structure_set (structure, "format", GST_TYPE_FOURCC, fourcc, NULL);
        }
    }
}
Example #12
0
static GstCaps *
gst_aasink_fixate (GstBaseSink * bsink, GstCaps * caps)
{
  GstStructure *structure;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);

  caps = GST_BASE_SINK_CLASS (parent_class)->fixate (bsink, caps);

  return caps;
}
Example #13
0
static void
fixate_vis_caps (RBVisualizerPlugin *plugin)
{
	GstPad *pad;
	GstCaps *caps = NULL;
	const GstCaps *template_caps;

	pad = gst_element_get_static_pad (plugin->vis_plugin, "src");
	template_caps = gst_pad_get_pad_template_caps (pad);
	gst_object_unref (pad);

	if (template_caps == NULL) {
		rb_debug ("vis element has no template caps?");
		return;
	}

	caps = gst_caps_copy (template_caps);

	if (gst_caps_is_fixed (caps) == FALSE) {
		guint i;
		char *dbg;
		const VisualizerQuality *q = &rb_visualizer_quality[g_settings_get_enum (plugin->settings, "quality")];

		rb_debug ("fixating caps towards %dx%d, %d/%d", q->width, q->height, q->fps_n, q->fps_d);
		caps = gst_caps_make_writable (caps);
		for (i = 0; i < gst_caps_get_size (caps); i++) {
			GstStructure *s = gst_caps_get_structure (caps, i);

			gst_structure_fixate_field_nearest_int (s, "width", q->width);
			gst_structure_fixate_field_nearest_int (s, "height", q->height);
			gst_structure_fixate_field_nearest_fraction (s, "framerate", q->fps_n, q->fps_d);
		}

		dbg = gst_caps_to_string (caps);
		rb_debug ("setting fixed caps on capsfilter: %s", dbg);
		g_free (dbg);

		g_object_set (plugin->capsfilter, "caps", caps, NULL);
	} else {
		char *dbg = gst_caps_to_string (caps);
		rb_debug ("vis element caps already fixed: %s", dbg);
		g_free (dbg);
	}

	gst_caps_unref (caps);
}
static GstCaps *
gst_gdiscreencapsrc_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstStructure *structure;

  caps = gst_caps_make_writable (caps);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (structure, "width", 640);
  gst_structure_fixate_field_nearest_int (structure, "height", 480);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);

  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (bsrc, caps);

  return caps;
}
Example #15
0
static void
gst_droid_cam_src_vfsrc_fixatecaps (GstPad * pad, GstCaps * caps)
{
  GstDroidCamSrc *src = GST_DROID_CAM_SRC (GST_OBJECT_PARENT (pad));
  GstStructure *s;

  GST_LOG_OBJECT (src, "fixatecaps %" GST_PTR_FORMAT, caps);

  gst_caps_truncate (caps);

  s = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (s, "width", DEFAULT_VF_WIDTH);
  gst_structure_fixate_field_nearest_int (s, "height", DEFAULT_VF_HEIGHT);
  gst_structure_fixate_field_nearest_fraction (s, "framerate", DEFAULT_FPS, 1);

  GST_DEBUG_OBJECT (src, "caps now is %" GST_PTR_FORMAT, caps);
}
Example #16
0
static GstCaps *
gst_ks_video_src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
    GstStructure *structure;
    GstCaps *fixated_caps;
    gint i;

    fixated_caps = gst_caps_make_writable (caps);

    for (i = 0; i < gst_caps_get_size (fixated_caps); ++i) {
        structure = gst_caps_get_structure (fixated_caps, i);
        gst_structure_fixate_field_nearest_int (structure, "width", G_MAXINT);
        gst_structure_fixate_field_nearest_int (structure, "height", G_MAXINT);
        gst_structure_fixate_field_nearest_fraction (structure, "framerate",
                G_MAXINT, 1);
    }

    return gst_caps_fixate (fixated_caps);
}
Example #17
0
static void
gst_dc1394_src_fixate (GstPad * pad, GstCaps * caps)
{

    GstDc1394 *src = GST_DC1394 (gst_pad_get_parent (pad));
    GstStructure *structure;
    int i;

    GST_LOG_OBJECT (src, " fixating caps to closest to 320x240 , 30 fps");

    for (i = 0; i < gst_caps_get_size (caps); ++i) {
        structure = gst_caps_get_structure (caps, i);

        gst_structure_fixate_field_nearest_int (structure, "width", 320);
        gst_structure_fixate_field_nearest_int (structure, "height", 240);
        gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
    }
    gst_object_unref (GST_OBJECT (src));
}
Example #18
0
static gboolean
gst_goom_src_negotiate (GstGoom * goom)
{
  GstCaps *othercaps, *target;
  GstStructure *structure;
  const GstCaps *templ;

  templ = gst_pad_get_pad_template_caps (goom->srcpad);

  GST_DEBUG_OBJECT (goom, "performing negotiation");

  /* see what the peer can do */
  othercaps = gst_pad_peer_get_caps (goom->srcpad);
  if (othercaps) {
    target = gst_caps_intersect (othercaps, templ);
    gst_caps_unref (othercaps);

    if (gst_caps_is_empty (target))
      goto no_format;

    gst_caps_truncate (target);
  } else {
    target = gst_caps_ref ((GstCaps *) templ);
  }

  structure = gst_caps_get_structure (target, 0);
  gst_structure_fixate_field_nearest_int (structure, "width", DEFAULT_WIDTH);
  gst_structure_fixate_field_nearest_int (structure, "height", DEFAULT_HEIGHT);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate",
      DEFAULT_FPS_N, DEFAULT_FPS_D);

  gst_pad_set_caps (goom->srcpad, target);
  gst_caps_unref (target);

  return TRUE;

no_format:
  {
    gst_caps_unref (target);
    return FALSE;
  }
}
Example #19
0
static gboolean
gst_monoscope_src_negotiate (GstMonoscope * monoscope)
{
  GstCaps *othercaps, *target, *intersect;
  GstStructure *structure;
  const GstCaps *templ;

  templ = gst_pad_get_pad_template_caps (monoscope->srcpad);

  GST_DEBUG_OBJECT (monoscope, "performing negotiation");

  /* see what the peer can do */
  othercaps = gst_pad_peer_get_caps (monoscope->srcpad);
  if (othercaps) {
    intersect = gst_caps_intersect (othercaps, templ);
    gst_caps_unref (othercaps);

    if (gst_caps_is_empty (intersect))
      goto no_format;

    target = gst_caps_copy_nth (intersect, 0);
    gst_caps_unref (intersect);
  } else {
    target = gst_caps_ref ((GstCaps *) templ);
  }

  structure = gst_caps_get_structure (target, 0);
  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 25, 1);

  gst_pad_set_caps (monoscope->srcpad, target);
  gst_caps_unref (target);

  return TRUE;

no_format:
  {
    gst_caps_unref (intersect);
    return FALSE;
  }
}
Example #20
0
static GstCaps *
gst_rpi_cam_src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure;
  gint i;
  GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);
  caps = gst_caps_make_writable (caps);
  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    structure = gst_caps_get_structure (caps, i);
    /* Fixate to 1920x1080 resolution if possible */
    gst_structure_fixate_field_nearest_int (structure, "width", 1920);
    gst_structure_fixate_field_nearest_int (structure, "height", 1080);
    gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
    gst_structure_fixate_field (structure, "format");
  }

  GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);
  caps = GST_BASE_SRC_CLASS (parent_class)->fixate (basesrc, caps);
  return caps;
}
Example #21
0
static GstCaps *
fs_videoanyrate_fixate_caps (GstBaseTransform * base,
                             GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
    GstStructure *ins, *outs;

    const GValue *from_fr, *to_fr;

    g_return_val_if_fail (gst_caps_is_fixed (caps), othercaps);

    othercaps = gst_caps_make_writable (othercaps);

    GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT
                      " based on caps %" GST_PTR_FORMAT, othercaps, caps);

    ins = gst_caps_get_structure (caps, 0);
    outs = gst_caps_get_structure (othercaps, 0);

    from_fr = gst_structure_get_value (ins, "framerate");
    to_fr = gst_structure_get_value (outs, "framerate");

    /* we have both PAR but they might not be fixated */
    if (from_fr && to_fr && !gst_value_is_fixed (to_fr)) {
        gint from_fr_n, from_fr_d;

        /* from_fr should be fixed */
        g_return_val_if_fail (gst_value_is_fixed (from_fr), othercaps);

        from_fr_n = gst_value_get_fraction_numerator (from_fr);
        from_fr_d = gst_value_get_fraction_denominator (from_fr);

        GST_DEBUG_OBJECT (base, "fixating to_fr nearest to %d/%d",
                          from_fr_n, from_fr_d);
        gst_structure_fixate_field_nearest_fraction (outs, "framerate",
                from_fr_n, from_fr_d);
    }

    return gst_caps_fixate (othercaps);
}
Example #22
0
static GstCaps *
gst_aravis_fixate_caps (GstBaseSrc * bsrc, GstCaps * caps)
{
	GstAravis *gst_aravis = GST_ARAVIS (bsrc);
	GstStructure *structure;
	gint width;
	gint height;
	double frame_rate;

	arv_camera_get_region (gst_aravis->camera, NULL, NULL, &width, &height);
	frame_rate = arv_camera_get_frame_rate (gst_aravis->camera);

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_fixate_field_nearest_int (structure, "width", width);
	gst_structure_fixate_field_nearest_int (structure, "height", height);
	gst_structure_fixate_field_nearest_fraction (structure, "framerate", (double) (0.5 + frame_rate), 1);

	GST_LOG_OBJECT (gst_aravis, "Fixate caps");

	return GST_BASE_SRC_CLASS(gst_aravis_parent_class)->fixate(bsrc, caps);
}
Example #23
0
static void
gst_aravis_fixate_caps (GstPad * pad, GstCaps * caps)
{
	GstAravis *gst_aravis = GST_ARAVIS (gst_pad_get_parent_element (pad));
	GstStructure *structure;
	gint width;
	gint height;
	double frame_rate;

	arv_camera_get_region (gst_aravis->camera, NULL, NULL, &width, &height);
	frame_rate = arv_camera_get_frame_rate (gst_aravis->camera);

	structure = gst_caps_get_structure (caps, 0);

	gst_structure_fixate_field_nearest_int (structure, "width", width);
	gst_structure_fixate_field_nearest_int (structure, "height", height);
	gst_structure_fixate_field_nearest_fraction (structure, "framerate", (double) (0.5 + frame_rate), 1);

	GST_LOG_OBJECT (gst_aravis, "Fixate caps");

	g_object_unref (gst_aravis);
}
Example #24
0
/* this function is a bit of a last resort */
static void
gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps)
{
  GstStructure *structure;

  gint i;

  GST_DEBUG_OBJECT (basesrc, "fixating caps %" GST_PTR_FORMAT, caps);

  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    const GValue *v;

    structure = gst_caps_get_structure (caps, i);

    /* FIXME such sizes? we usually fixate to something in the 320x200
     * range... */
    /* We are fixating to greater possble size (limited to GST_V4L2_MAX_SIZE)
       and the maximum framerate resolution for that size */
    gst_structure_fixate_field_nearest_int (structure, "width",
        GST_V4L2_MAX_SIZE);
    gst_structure_fixate_field_nearest_int (structure, "height",
        GST_V4L2_MAX_SIZE);
    gst_structure_fixate_field_nearest_fraction (structure, "framerate",
        G_MAXINT, 1);

    v = gst_structure_get_value (structure, "format");
    if (v && G_VALUE_TYPE (v) != GST_TYPE_FOURCC) {
      guint32 fourcc;

      g_return_if_fail (G_VALUE_TYPE (v) == GST_TYPE_LIST);

      fourcc = gst_value_get_fourcc (gst_value_list_get_value (v, 0));
      gst_structure_set (structure, "format", GST_TYPE_FOURCC, fourcc, NULL);
    }
  }

  GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);
}
Example #25
0
static gboolean
gst_video_rate_setcaps (GstPad * pad, GstCaps * caps)
{
  GstVideoRate *videorate;
  GstStructure *structure;
  gboolean ret = TRUE;
  GstPad *otherpad, *opeer;
  gint rate_numerator, rate_denominator;

  videorate = GST_VIDEO_RATE (gst_pad_get_parent (pad));

  GST_DEBUG_OBJECT (pad, "setcaps called %" GST_PTR_FORMAT, caps);

  structure = gst_caps_get_structure (caps, 0);
  if (!gst_structure_get_fraction (structure, "framerate",
          &rate_numerator, &rate_denominator))
    goto no_framerate;

  if (pad == videorate->srcpad) {
    /* out_frame_count is scaled by the frame rate caps when calculating next_ts.
     * when the frame rate caps change, we must update base_ts and reset
     * out_frame_count */
    if (videorate->to_rate_numerator) {
      videorate->base_ts +=
          gst_util_uint64_scale (videorate->out_frame_count,
          videorate->to_rate_denominator * GST_SECOND,
          videorate->to_rate_numerator);
    }
    videorate->out_frame_count = 0;
    videorate->to_rate_numerator = rate_numerator;
    videorate->to_rate_denominator = rate_denominator;
    otherpad = videorate->sinkpad;
  } else {
    videorate->from_rate_numerator = rate_numerator;
    videorate->from_rate_denominator = rate_denominator;
    otherpad = videorate->srcpad;
  }

  /* now try to find something for the peer */
  opeer = gst_pad_get_peer (otherpad);
  if (opeer) {
    if (gst_pad_accept_caps (opeer, caps)) {
      /* the peer accepts the caps as they are */
      gst_pad_set_caps (otherpad, caps);

      ret = TRUE;
    } else {
      GstCaps *peercaps;
      GstCaps *transform = NULL;

      ret = FALSE;

      /* see how we can transform the input caps */
      if (!gst_video_rate_transformcaps (pad, caps, otherpad, &transform))
        goto no_transform;

      /* see what the peer can do */
      peercaps = gst_pad_get_caps (opeer);

      GST_DEBUG_OBJECT (opeer, "icaps %" GST_PTR_FORMAT, peercaps);
      GST_DEBUG_OBJECT (videorate, "transform %" GST_PTR_FORMAT, transform);

      /* filter against our possibilities */
      caps = gst_caps_intersect (peercaps, transform);
      gst_caps_unref (peercaps);
      gst_caps_unref (transform);

      GST_DEBUG_OBJECT (videorate, "intersect %" GST_PTR_FORMAT, caps);

      /* could turn up empty, due to e.g. colorspace etc */
      if (gst_caps_get_size (caps) == 0) {
        gst_caps_unref (caps);
        goto no_transform;
      }

      /* take first possibility */
      gst_caps_truncate (caps);
      structure = gst_caps_get_structure (caps, 0);

      /* and fixate */
      gst_structure_fixate_field_nearest_fraction (structure, "framerate",
          rate_numerator, rate_denominator);

      gst_structure_get_fraction (structure, "framerate",
          &rate_numerator, &rate_denominator);

      if (otherpad == videorate->srcpad) {
        videorate->to_rate_numerator = rate_numerator;
        videorate->to_rate_denominator = rate_denominator;
      } else {
        videorate->from_rate_numerator = rate_numerator;
        videorate->from_rate_denominator = rate_denominator;
      }

      if (gst_structure_has_field (structure, "interlaced"))
        gst_structure_fixate_field_boolean (structure, "interlaced", FALSE);
      if (gst_structure_has_field (structure, "color-matrix"))
        gst_structure_fixate_field_string (structure, "color-matrix", "sdtv");
      if (gst_structure_has_field (structure, "chroma-site"))
        gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");
      if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
        gst_structure_fixate_field_nearest_fraction (structure,
            "pixel-aspect-ratio", 1, 1);

      gst_pad_set_caps (otherpad, caps);
      gst_caps_unref (caps);
      ret = TRUE;
    }
    gst_object_unref (opeer);
  }
done:
  /* After a setcaps, our caps may have changed. In that case, we can't use
   * the old buffer, if there was one (it might have different dimensions) */
  GST_DEBUG_OBJECT (videorate, "swapping old buffers");
  gst_video_rate_swap_prev (videorate, NULL, GST_CLOCK_TIME_NONE);

  gst_object_unref (videorate);
  return ret;

no_framerate:
  {
    GST_DEBUG_OBJECT (videorate, "no framerate specified");
    goto done;
  }
no_transform:
  {
    GST_DEBUG_OBJECT (videorate, "no framerate transform possible");
    ret = FALSE;
    goto done;
  }
}
static GstCaps *
gst_video_scale_fixate_caps (GstBaseTransform * base, GstPadDirection direction,
                             GstCaps * caps, GstCaps * othercaps)
{
    GstStructure *ins, *outs;
    const GValue *from_par, *to_par;
    GValue fpar = { 0, }, tpar = {
        0,
    };

    othercaps = gst_caps_truncate (othercaps);
    othercaps = gst_caps_make_writable (othercaps);

    GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT
                      " based on caps %" GST_PTR_FORMAT, othercaps, caps);

    ins = gst_caps_get_structure (caps, 0);
    outs = gst_caps_get_structure (othercaps, 0);

    from_par = gst_structure_get_value (ins, "pixel-aspect-ratio");
    to_par = gst_structure_get_value (outs, "pixel-aspect-ratio");

    /* If we're fixating from the sinkpad we always set the PAR and
     * assume that missing PAR on the sinkpad means 1/1 and
     * missing PAR on the srcpad means undefined
     */
    if (direction == GST_PAD_SINK) {
        if (!from_par) {
            g_value_init (&fpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&fpar, 1, 1);
            from_par = &fpar;
        }
        if (!to_par) {
            g_value_init (&tpar, GST_TYPE_FRACTION_RANGE);
            gst_value_set_fraction_range_full (&tpar, 1, G_MAXINT, G_MAXINT, 1);
            to_par = &tpar;
        }
    } else {
        if (!to_par) {
            g_value_init (&tpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&tpar, 1, 1);
            to_par = &tpar;

            gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
                               NULL);
        }
        if (!from_par) {
            g_value_init (&fpar, GST_TYPE_FRACTION);
            gst_value_set_fraction (&fpar, 1, 1);
            from_par = &fpar;
        }
    }

    /* we have both PAR but they might not be fixated */
    {
        gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
        gint w = 0, h = 0;
        gint from_dar_n, from_dar_d;
        gint num, den;

        /* from_par should be fixed */
        g_return_val_if_fail (gst_value_is_fixed (from_par), othercaps);

        from_par_n = gst_value_get_fraction_numerator (from_par);
        from_par_d = gst_value_get_fraction_denominator (from_par);

        gst_structure_get_int (ins, "width", &from_w);
        gst_structure_get_int (ins, "height", &from_h);

        gst_structure_get_int (outs, "width", &w);
        gst_structure_get_int (outs, "height", &h);

        /* if both width and height are already fixed, we can't do anything
         * about it anymore */
        if (w && h) {
            guint n, d;

            GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating",
                              w, h);
            if (!gst_value_is_fixed (to_par)) {
                if (gst_video_calculate_display_ratio (&n, &d, from_w, from_h,
                                                       from_par_n, from_par_d, w, h)) {
                    GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", n, d);
                    if (gst_structure_has_field (outs, "pixel-aspect-ratio"))
                        gst_structure_fixate_field_nearest_fraction (outs,
                                "pixel-aspect-ratio", n, d);
                    else if (n != d)
                        gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                           n, d, NULL);
                }
            }
            goto done;
        }

        /* Calculate input DAR */
        if (!gst_util_fraction_multiply (from_w, from_h, from_par_n, from_par_d,
                                         &from_dar_n, &from_dar_d)) {
            GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                               ("Error calculating the output scaled size - integer overflow"));
            goto done;
        }

        GST_DEBUG_OBJECT (base, "Input DAR is %d/%d", from_dar_n, from_dar_d);

        /* If either width or height are fixed there's not much we
         * can do either except choosing a height or width and PAR
         * that matches the DAR as good as possible
         */
        if (h) {
            GstStructure *tmp;
            gint set_w, set_par_n, set_par_d;

            GST_DEBUG_OBJECT (base, "height is fixed (%d)", h);

            /* If the PAR is fixed too, there's not much to do
             * except choosing the width that is nearest to the
             * width with the same DAR */
            if (gst_value_is_fixed (to_par)) {
                to_par_n = gst_value_get_fraction_numerator (to_par);
                to_par_d = gst_value_get_fraction_denominator (to_par);

                GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d);

                if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d,
                                                 to_par_n, &num, &den)) {
                    GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                       ("Error calculating the output scaled size - integer overflow"));
                    goto done;
                }

                w = (guint) gst_util_uint64_scale_int (h, num, den);
                gst_structure_fixate_field_nearest_int (outs, "width", w);

                goto done;
            }

            /* The PAR is not fixed and it's quite likely that we can set
             * an arbitrary PAR. */

            /* Check if we can keep the input width */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            /* Might have failed but try to keep the DAR nonetheless by
             * adjusting the PAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }

            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            /* Check if the adjusted PAR is accepted */
            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "width", G_TYPE_INT, set_w,
                                       "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d,
                                       NULL);
                goto done;
            }

            /* Otherwise scale the width to the new PAR and check if the
             * adjusted with is accepted. If all that fails we can't keep
             * the DAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            w = (guint) gst_util_uint64_scale_int (h, num, den);
            gst_structure_fixate_field_nearest_int (outs, "width", w);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);

            goto done;
        } else if (w) {
            GstStructure *tmp;
            gint set_h, set_par_n, set_par_d;

            GST_DEBUG_OBJECT (base, "width is fixed (%d)", w);

            /* If the PAR is fixed too, there's not much to do
             * except choosing the height that is nearest to the
             * height with the same DAR */
            if (gst_value_is_fixed (to_par)) {
                to_par_n = gst_value_get_fraction_numerator (to_par);
                to_par_d = gst_value_get_fraction_denominator (to_par);

                GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d);

                if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d,
                                                 to_par_n, &num, &den)) {
                    GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                       ("Error calculating the output scaled size - integer overflow"));
                    goto done;
                }

                h = (guint) gst_util_uint64_scale_int (w, den, num);
                gst_structure_fixate_field_nearest_int (outs, "height", h);

                goto done;
            }

            /* The PAR is not fixed and it's quite likely that we can set
             * an arbitrary PAR. */

            /* Check if we can keep the input height */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);

            /* Might have failed but try to keep the DAR nonetheless by
             * adjusting the PAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }
            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            /* Check if the adjusted PAR is accepted */
            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "height", G_TYPE_INT, set_h,
                                       "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d,
                                       NULL);
                goto done;
            }

            /* Otherwise scale the height to the new PAR and check if the
             * adjusted with is accepted. If all that fails we can't keep
             * the DAR */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            h = (guint) gst_util_uint64_scale_int (w, den, num);
            gst_structure_fixate_field_nearest_int (outs, "height", h);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);

            goto done;
        } else if (gst_value_is_fixed (to_par)) {
            GstStructure *tmp;
            gint set_h, set_w, f_h, f_w;

            to_par_n = gst_value_get_fraction_numerator (to_par);
            to_par_d = gst_value_get_fraction_denominator (to_par);

            /* Calculate scale factor for the PAR change */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_n,
                                             to_par_d, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            /* Try to keep the input height (because of interlacing) */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);

            /* This might have failed but try to scale the width
             * to keep the DAR nonetheless */
            w = (guint) gst_util_uint64_scale_int (set_h, num, den);
            gst_structure_fixate_field_nearest_int (tmp, "width", w);
            gst_structure_get_int (tmp, "width", &set_w);
            gst_structure_free (tmp);

            /* We kept the DAR and the height is nearest to the original height */
            if (set_w == w) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);
                goto done;
            }

            f_h = set_h;
            f_w = set_w;

            /* If the former failed, try to keep the input width at least */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            /* This might have failed but try to scale the width
             * to keep the DAR nonetheless */
            h = (guint) gst_util_uint64_scale_int (set_w, den, num);
            gst_structure_fixate_field_nearest_int (tmp, "height", h);
            gst_structure_get_int (tmp, "height", &set_h);
            gst_structure_free (tmp);

            /* We kept the DAR and the width is nearest to the original width */
            if (set_h == h) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);
                goto done;
            }

            /* If all this failed, keep the height that was nearest to the orignal
             * height and the nearest possible width. This changes the DAR but
             * there's not much else to do here.
             */
            gst_structure_set (outs, "width", G_TYPE_INT, f_w, "height", G_TYPE_INT,
                               f_h, NULL);
            goto done;
        } else {
            GstStructure *tmp;
            gint set_h, set_w, set_par_n, set_par_d, tmp2;

            /* width, height and PAR are not fixed but passthrough is not possible */

            /* First try to keep the height and width as good as possible
             * and scale PAR */
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", from_h);
            gst_structure_get_int (tmp, "height", &set_h);
            gst_structure_fixate_field_nearest_int (tmp, "width", from_w);
            gst_structure_get_int (tmp, "width", &set_w);

            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w,
                                             &to_par_n, &to_par_d)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                gst_structure_free (tmp);
                goto done;
            }

            if (!gst_structure_has_field (tmp, "pixel-aspect-ratio"))
                gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par);
            gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio",
                    to_par_n, to_par_d);
            gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n,
                                        &set_par_d);
            gst_structure_free (tmp);

            if (set_par_n == to_par_n && set_par_d == to_par_d) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, set_h, NULL);

                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* Otherwise try to scale width to keep the DAR with the set
             * PAR and height */
            if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d,
                                             set_par_n, &num, &den)) {
                GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL),
                                   ("Error calculating the output scaled size - integer overflow"));
                goto done;
            }

            w = (guint) gst_util_uint64_scale_int (set_h, num, den);
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "width", w);
            gst_structure_get_int (tmp, "width", &tmp2);
            gst_structure_free (tmp);

            if (tmp2 == w) {
                gst_structure_set (outs, "width", G_TYPE_INT, tmp2, "height",
                                   G_TYPE_INT, set_h, NULL);
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* ... or try the same with the height */
            h = (guint) gst_util_uint64_scale_int (set_w, den, num);
            tmp = gst_structure_copy (outs);
            gst_structure_fixate_field_nearest_int (tmp, "height", h);
            gst_structure_get_int (tmp, "height", &tmp2);
            gst_structure_free (tmp);

            if (tmp2 == h) {
                gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                                   G_TYPE_INT, tmp2, NULL);
                if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                        set_par_n != set_par_d)
                    gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                       set_par_n, set_par_d, NULL);
                goto done;
            }

            /* If all fails we can't keep the DAR and take the nearest values
             * for everything from the first try */
            gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height",
                               G_TYPE_INT, set_h, NULL);
            if (gst_structure_has_field (outs, "pixel-aspect-ratio") ||
                    set_par_n != set_par_d)
                gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION,
                                   set_par_n, set_par_d, NULL);
        }
    }

done:
    GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, othercaps);

    if (from_par == &fpar)
        g_value_unset (&fpar);
    if (to_par == &tpar)
        g_value_unset (&tpar);

    return othercaps;
}
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;
}
Example #28
0
static gboolean
gst_goom_src_negotiate (GstGoom * goom)
{
  GstCaps *othercaps, *target;
  GstStructure *structure;
  GstCaps *templ;
  GstQuery *query;
  GstBufferPool *pool;
  GstStructure *config;
  guint size, min, max;

  templ = gst_pad_get_pad_template_caps (goom->srcpad);

  GST_DEBUG_OBJECT (goom, "performing negotiation");

  /* see what the peer can do */
  othercaps = gst_pad_peer_query_caps (goom->srcpad, NULL);
  if (othercaps) {
    target = gst_caps_intersect (othercaps, templ);
    gst_caps_unref (othercaps);
    gst_caps_unref (templ);

    if (gst_caps_is_empty (target))
      goto no_format;

    target = gst_caps_truncate (target);
  } else {
    target = templ;
  }

  structure = gst_caps_get_structure (target, 0);
  gst_structure_fixate_field_nearest_int (structure, "width", DEFAULT_WIDTH);
  gst_structure_fixate_field_nearest_int (structure, "height", DEFAULT_HEIGHT);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate",
      DEFAULT_FPS_N, DEFAULT_FPS_D);

  gst_goom_src_setcaps (goom, target);

  /* try to get a bufferpool now */
  /* find a pool for the negotiated caps now */
  query = gst_query_new_allocation (target, TRUE);

  if (!gst_pad_peer_query (goom->srcpad, query)) {
    /* no problem, we use the query defaults */
    GST_DEBUG_OBJECT (goom, "ALLOCATION query failed");
  }

  if (gst_query_get_n_allocation_pools (query) > 0) {
    /* we got configuration from our peer, parse them */
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
  } else {
    pool = NULL;
    size = goom->outsize;
    min = max = 0;
  }

  if (pool == NULL) {
    /* we did not get a pool, make one ourselves then */
    pool = gst_buffer_pool_new ();
  }

  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_set_params (config, target, size, min, max);
  gst_buffer_pool_set_config (pool, config);

  if (goom->pool) {
    gst_buffer_pool_set_active (goom->pool, FALSE);
    gst_object_unref (goom->pool);
  }
  goom->pool = pool;

  /* and activate */
  gst_buffer_pool_set_active (pool, TRUE);

  gst_caps_unref (target);

  return TRUE;

no_format:
  {
    gst_caps_unref (target);
    return FALSE;
  }
}
Example #29
0
static void
gst_ffmpegscale_fixate_caps(GstBaseTransform* trans,
                            GstPadDirection direction, GstCaps* caps, GstCaps* othercaps) {
    GstStructure* ins, *outs;
    const GValue* from_par, *to_par;

    g_return_if_fail(gst_caps_is_fixed(caps));

    GST_DEBUG_OBJECT(trans, "trying to fixate othercaps %" GST_PTR_FORMAT
                     " based on caps %" GST_PTR_FORMAT, othercaps, caps);

    ins = gst_caps_get_structure(caps, 0);
    outs = gst_caps_get_structure(othercaps, 0);

    from_par = gst_structure_get_value(ins, "pixel-aspect-ratio");
    to_par = gst_structure_get_value(outs, "pixel-aspect-ratio");

    /* we have both PAR but they might not be fixated */
    if (from_par && to_par) {
        gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d;
        gint count = 0, w = 0, h = 0;
        guint num, den;

        /* from_par should be fixed */
        g_return_if_fail(gst_value_is_fixed(from_par));

        from_par_n = gst_value_get_fraction_numerator(from_par);
        from_par_d = gst_value_get_fraction_denominator(from_par);

        /* fixate the out PAR */
        if (!gst_value_is_fixed(to_par)) {
            GST_DEBUG_OBJECT(trans, "fixating to_par to %dx%d", from_par_n,
                             from_par_d);
            gst_structure_fixate_field_nearest_fraction(outs, "pixel-aspect-ratio",
                    from_par_n, from_par_d);
        }

        to_par_n = gst_value_get_fraction_numerator(to_par);
        to_par_d = gst_value_get_fraction_denominator(to_par);

        /* if both width and height are already fixed, we can't do anything
         * about it anymore */
        if (gst_structure_get_int(outs, "width", &w)) {
            ++count;
        }

        if (gst_structure_get_int(outs, "height", &h)) {
            ++count;
        }

        if (count == 2) {
            GST_DEBUG_OBJECT(trans, "dimensions already set to %dx%d, not fixating",
                             w, h);
            return;
        }

        gst_structure_get_int(ins, "width", &from_w);
        gst_structure_get_int(ins, "height", &from_h);

        if (!gst_video_calculate_display_ratio(&num, &den, from_w, from_h,
                                               from_par_n, from_par_d, to_par_n, to_par_d)) {
            GST_ELEMENT_ERROR(trans, CORE, NEGOTIATION, (NULL),
                              ("Error calculating the output scaled size - integer overflow"));
            return;
        }

        GST_DEBUG_OBJECT(trans,
                         "scaling input with %dx%d and PAR %d/%d to output PAR %d/%d",
                         from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d);
        GST_DEBUG_OBJECT(trans, "resulting output should respect ratio of %d/%d",
                         num, den);

        /* now find a width x height that respects this display ratio.
         * prefer those that have one of w/h the same as the incoming video
         * using wd / hd = num / den */

        /* if one of the output width or height is fixed, we work from there */
        if (h) {
            GST_DEBUG_OBJECT(trans, "height is fixed,scaling width");
            w = (guint) gst_util_uint64_scale_int(h, num, den);
        } else if (w) {
            GST_DEBUG_OBJECT(trans, "width is fixed, scaling height");
            h = (guint) gst_util_uint64_scale_int(w, den, num);
        } else {
            /* none of width or height is fixed, figure out both of them based only on
             * the input width and height */
            /* check hd / den is an integer scale factor, and scale wd with the PAR */
            if (from_h % den == 0) {
                GST_DEBUG_OBJECT(trans, "keeping video height");
                h = from_h;
                w = (guint) gst_util_uint64_scale_int(h, num, den);
            } else if (from_w % num == 0) {
                GST_DEBUG_OBJECT(trans, "keeping video width");
                w = from_w;
                h = (guint) gst_util_uint64_scale_int(w, den, num);
            } else {
                GST_DEBUG_OBJECT(trans, "approximating but keeping video height");
                h = from_h;
                w = (guint) gst_util_uint64_scale_int(h, num, den);
            }
        }

        GST_DEBUG_OBJECT(trans, "scaling to %dx%d", w, h);

        /* now fixate */
        gst_structure_fixate_field_nearest_int(outs, "width", w);
        gst_structure_fixate_field_nearest_int(outs, "height", h);
    } else {
        gint width, height;

        if (gst_structure_get_int(ins, "width", &width)) {
            if (gst_structure_has_field(outs, "width")) {
                gst_structure_fixate_field_nearest_int(outs, "width", width);
            }
        }

        if (gst_structure_get_int(ins, "height", &height)) {
            if (gst_structure_has_field(outs, "height")) {
                gst_structure_fixate_field_nearest_int(outs, "height", height);
            }
        }
    }

    GST_DEBUG_OBJECT(trans, "fixated othercaps to %" GST_PTR_FORMAT, othercaps);
}
static gboolean
gst_monoscope_src_negotiate (GstMonoscope * monoscope)
{
  GstCaps *othercaps, *target;
  GstStructure *structure;
  GstCaps *templ;
  GstQuery *query;
  GstBufferPool *pool;
  GstStructure *config;
  guint size, min, max;

  templ = gst_pad_get_pad_template_caps (monoscope->srcpad);

  GST_DEBUG_OBJECT (monoscope, "performing negotiation");

  /* see what the peer can do */
  othercaps = gst_pad_peer_query_caps (monoscope->srcpad, NULL);
  if (othercaps) {
    target = gst_caps_intersect (othercaps, templ);
    gst_caps_unref (othercaps);
    gst_caps_unref (templ);

    if (gst_caps_is_empty (target))
      goto no_format;

    target = gst_caps_truncate (target);
  } else {
    target = templ;
  }

  target = gst_caps_make_writable (target);
  structure = gst_caps_get_structure (target, 0);
  gst_structure_fixate_field_nearest_int (structure, "width", 320);
  gst_structure_fixate_field_nearest_int (structure, "height", 240);
  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 25, 1);

  gst_monoscope_src_setcaps (monoscope, target);

  /* try to get a bufferpool now */
  /* find a pool for the negotiated caps now */
  query = gst_query_new_allocation (target, TRUE);

  if (!gst_pad_peer_query (monoscope->srcpad, query)) {
  }

  if (gst_query_get_n_allocation_pools (query) > 0) {
    /* we got configuration from our peer, parse them */
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
  } else {
    pool = NULL;
    size = monoscope->outsize;
    min = max = 0;
  }

  if (pool == NULL) {
    /* we did not get a pool, make one ourselves then */
    pool = gst_buffer_pool_new ();
  }

  config = gst_buffer_pool_get_config (pool);
  gst_buffer_pool_config_set_params (config, target, size, min, max);
  gst_buffer_pool_set_config (pool, config);

  if (monoscope->pool) {
    gst_buffer_pool_set_active (monoscope->pool, TRUE);
    gst_object_unref (monoscope->pool);
  }
  monoscope->pool = pool;

  /* and activate */
  gst_buffer_pool_set_active (pool, TRUE);

  gst_caps_unref (target);

  return TRUE;

no_format:
  {
    gst_caps_unref (target);
    return FALSE;
  }
}