Esempio n. 1
0
static GstCaps *
gst_gl_filter_transform_caps (GstBaseTransform * bt,
    GstPadDirection direction, GstCaps * caps)
{
  //GstGLFilter* filter = GST_GL_FILTER (bt);
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  GstCaps *ret = gst_caps_copy (caps);
  const GValue *par = NULL;

  structure = gst_structure_copy (gst_caps_get_structure (ret, 0));

  gst_structure_set (structure,
      "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
      "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);

  gst_caps_merge_structure (ret, gst_structure_copy (structure));

  if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
    gst_structure_set (structure,
        "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
    gst_caps_merge_structure (ret, structure);
  } else
    gst_structure_free (structure);

  GST_DEBUG_OBJECT (bt, "returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}
Esempio n. 2
0
static gboolean
gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
{
    GstCaps *decode_caps;
    guint i, n_decode_caps;

    if (decode->allowed_caps)
        return TRUE;

    if (!gst_vaapidecode_ensure_display(decode))
        goto error_no_display;

    decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
    if (!decode_caps)
        goto error_no_decode_caps;
    n_decode_caps = gst_caps_get_size(decode_caps);

    decode->allowed_caps = gst_caps_new_empty();
    if (!decode->allowed_caps)
        goto error_no_memory;

    for (i = 0; i < n_decode_caps; i++) {
        GstStructure *structure;
        structure = gst_caps_get_structure(decode_caps, i);
        if (!structure)
            continue;
        structure = gst_structure_copy(structure);
        if (!structure)
            continue;
        gst_structure_remove_field(structure, "profile");
        gst_structure_set(
            structure,
            "width",  GST_TYPE_INT_RANGE, 1, G_MAXINT,
            "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
            NULL
        );
        gst_caps_merge_structure(decode->allowed_caps, structure);
    }

    gst_caps_unref(decode_caps);
    return TRUE;

    /* ERRORS */
error_no_display:
    {
        GST_DEBUG("failed to retrieve VA display");
        return FALSE;
    }
error_no_decode_caps:
    {
        GST_DEBUG("failed to retrieve VA decode caps");
        return FALSE;
    }
error_no_memory:
    {
        GST_DEBUG("failed to allocate allowed-caps set");
        gst_caps_unref(decode_caps);
        return FALSE;
    }
}
Esempio n. 3
0
GstCaps * _owr_payload_create_encoded_caps(OwrPayload *payload)
{
    GstCaps *caps;

    g_return_val_if_fail(OWR_IS_PAYLOAD(payload), NULL);

    switch (payload->priv->codec_type) {
    case OWR_CODEC_TYPE_H264:
        caps = gst_caps_new_simple("video/x-h264",
            "profile", G_TYPE_STRING, "baseline",
            NULL);
        caps = gst_caps_merge_structure(caps, gst_structure_new("video/x-h264",
            "profile", G_TYPE_STRING, "constrained-baseline", NULL));
        break;
    case OWR_CODEC_TYPE_VP8:
        caps = gst_caps_new_empty_simple("video/x-vp8");
        break;
    case OWR_CODEC_TYPE_OPUS:
        caps = gst_caps_new_empty_simple("audio/x-opus");
        break;
    case OWR_CODEC_TYPE_PCMU:
        caps = gst_caps_new_empty_simple("audio/x-mulaw");
        break;
    case OWR_CODEC_TYPE_PCMA:
        caps = gst_caps_new_empty_simple("audio/x-alaw");
        break;
    default:
        caps = NULL;
        break;
    }

    return caps;
}
Esempio n. 4
0
static GstCaps *
gst_ffmpegscale_transform_caps (GstBaseTransform * trans,
                                GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
    GstCaps *ret;
    GstStructure *structure;
    const GValue *par;

    /* this function is always called with a simple caps */
    g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);

    structure = gst_caps_get_structure (caps, 0);

    ret = gst_caps_copy (caps);
    structure = gst_structure_copy (gst_caps_get_structure (ret, 0));

    gst_structure_set (structure,
                       "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
                       "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);

    ret = gst_caps_merge_structure (ret, gst_structure_copy (structure));

    /* if pixel aspect ratio, make a range of it */
    if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) {
        gst_structure_set (structure,
                           "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);

        ret = gst_caps_merge_structure (ret, structure);
    } else {
        gst_structure_free (structure);
    }

    /* now also unfix colour space format */
    gst_caps_append (ret, gst_ffmpegscale_caps_remove_format_info (ret));

    GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);

    return ret;
}
Esempio n. 5
0
static GstCaps *
gst_jpegenc_getcaps (GstPad * pad)
{
  GstJpegEnc *jpegenc = GST_JPEGENC (gst_pad_get_parent (pad));
  GstCaps *caps, *othercaps;
  const GstCaps *templ;
  gint i, j;
  GstStructure *structure = NULL;

  /* we want to proxy properties like width, height and framerate from the
     other end of the element */

  othercaps = gst_pad_get_allowed_caps (jpegenc->srcpad);
  if (othercaps == NULL ||
      gst_caps_is_empty (othercaps) || gst_caps_is_any (othercaps)) {
    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
    goto done;
  }

  caps = gst_caps_new_empty ();
  templ = gst_pad_get_pad_template_caps (pad);

  for (i = 0; i < gst_caps_get_size (templ); i++) {
    /* pick fields from peer caps */
    for (j = 0; j < gst_caps_get_size (othercaps); j++) {
      GstStructure *s = gst_caps_get_structure (othercaps, j);
      const GValue *val;

      structure = gst_structure_copy (gst_caps_get_structure (templ, i));
      if ((val = gst_structure_get_value (s, "width")))
        gst_structure_set_value (structure, "width", val);
      if ((val = gst_structure_get_value (s, "height")))
        gst_structure_set_value (structure, "height", val);
      if ((val = gst_structure_get_value (s, "framerate")))
        gst_structure_set_value (structure, "framerate", val);

      gst_caps_merge_structure (caps, structure);
    }
  }

done:

  gst_caps_replace (&othercaps, NULL);
  gst_object_unref (jpegenc);

  return caps;
}
static GstCaps *
gst_video_rate_divider_transform_caps (GstBaseTransform * trans,
                               GstPadDirection direction, GstCaps * caps)
{
  GstVideoRateDivider *videorate = GST_VIDEO_RATE_DIVIDER (trans);
  GstCaps *ret;
  GstStructure *s, *s2;
  gint rate_numerator, rate_denominator;

  ret = gst_caps_copy (caps);

  /* Any caps simply return */
  if (gst_caps_is_any (caps))
    {
      GST_DEBUG_OBJECT (trans,
        "transform caps: %" GST_PTR_FORMAT " (direction = %s) ANY",
                        caps, get_direction_name(direction));
      return ret;
    }

  s = gst_caps_get_structure (ret, 0);
  gst_structure_get_fraction (s, "framerate",
                              &rate_numerator, &rate_denominator);
  GST_DEBUG_OBJECT (trans,
      "transform caps: %" GST_PTR_FORMAT " (direction = %s framerate = %d/%d)",
                    caps, get_direction_name(direction), rate_numerator, rate_denominator);

  s2 = gst_structure_copy (s);

  if (direction == GST_PAD_SINK)
    {
      /* correct input flow framerate */
      /* store inpute framerate */
      videorate->from_rate_numerator = rate_numerator;
      videorate->from_rate_denominator = rate_denominator;

      gst_caps_remove_structure (ret, 0);
      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION,
          rate_numerator, rate_denominator * videorate->factor, NULL);
      gst_caps_merge_structure (ret, s2);
    }

  return ret;
}
Esempio n. 7
0
static void
caps_append (GstCaps * caps, GstStructure * in_s, guint x, guint y, guint mpi)
{
  GstStructure *s;

  if (!in_s)
    return;

  if (mpi < 1 || mpi > 32)
    return;

  s = gst_structure_copy (in_s);

  gst_structure_set (s,
      "width", GST_TYPE_INT_RANGE, 1, x,
      "height", GST_TYPE_INT_RANGE, 1, y,
      "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30000, 1001 * mpi, NULL);

  gst_caps_merge_structure (caps, s);
}
static gboolean gst_mpeg4p2unpack_sink_event(GstPad * pad, GstObject *parent, GstEvent * event)
{
	GstMpeg4P2Unpack *self = GST_MPEG4P2UNPACK(gst_pad_get_parent(pad));
	gboolean ret = FALSE;

	GST_LOG_OBJECT(self, "%s event", GST_EVENT_TYPE_NAME(event));

	switch (GST_EVENT_TYPE (event))
	{
		case GST_EVENT_CAPS:
		{
			GstCaps *caps, *srccaps;
			gst_event_parse_caps(event, &caps);
			GST_DEBUG_OBJECT(self, "sinkcaps = %s", gst_caps_to_string(caps));

			GstStructure *structure = gst_structure_copy(gst_caps_get_structure (caps, 0));
			gint numerator, denominator;
			if (gst_structure_get_fraction (structure, "framerate", &numerator, &denominator))
			{
				self->buffer_duration = 1000 / ((double)numerator * 1000 / denominator) * GST_SECOND;
			}

			srccaps = gst_caps_new_empty();
			gst_structure_set_name(structure, "video/mpeg");
			srccaps = gst_caps_merge_structure(srccaps, structure);
			gst_caps_set_simple (srccaps, "mpegversion", G_TYPE_INT, 4, NULL);
			gst_caps_set_simple (srccaps, "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
			gst_caps_set_simple (srccaps, "unpacked", G_TYPE_BOOLEAN, TRUE, NULL);

			GST_DEBUG_OBJECT(self, "srccaps = %s", gst_caps_to_string(srccaps));
			ret = gst_pad_set_caps(self->srcpad, srccaps);
			gst_caps_unref(srccaps);
			gst_event_unref(event);
		}
			break;
		case GST_EVENT_FLUSH_STOP:
		{
			guint i;
			for (i=0; i < MPEG4P2_MAX_B_FRAMES_COUNT; i++)
			{
				if (self->b_frames[i])
				{
					gst_buffer_unref(self->b_frames[i]);
					self->b_frames[i] = NULL;
				}
			}
			if (self->second_ip_frame)
			{
				gst_buffer_unref(self->second_ip_frame);
				self->second_ip_frame = NULL;
			}
			if (self->b_frame)
			{
				gst_buffer_unref(self->b_frame);
				self->b_frame = NULL;
			}
			self->b_frames_count = 0;
			self->first_ip_frame_written = FALSE;
			ret = gst_pad_push_event(self->srcpad, event);
		}
			break;
		default:
			ret = gst_pad_push_event(self->srcpad, event);
			break;
	}
	return ret;
}
static GstCaps *
gst_rtp_h264_pay_getcaps (GstRTPBasePayload * payload, GstPad * pad,
    GstCaps * filter)
{
  GstCaps *template_caps;
  GstCaps *allowed_caps;
  GstCaps *caps, *icaps;
  gboolean append_unrestricted;
  guint i;

  allowed_caps =
      gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), NULL);

  if (allowed_caps == NULL)
    return NULL;

  template_caps =
      gst_static_pad_template_get_caps (&gst_rtp_h264_pay_sink_template);

  if (gst_caps_is_any (allowed_caps)) {
    caps = gst_caps_ref (template_caps);
    goto done;
  }

  if (gst_caps_is_empty (allowed_caps)) {
    caps = gst_caps_ref (allowed_caps);
    goto done;
  }

  caps = gst_caps_new_empty ();

  append_unrestricted = FALSE;
  for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
    GstStructure *s = gst_caps_get_structure (allowed_caps, i);
    GstStructure *new_s = gst_structure_new_empty ("video/x-h264");
    const gchar *profile_level_id;

    profile_level_id = gst_structure_get_string (s, "profile-level-id");

    if (profile_level_id && strlen (profile_level_id) == 6) {
      const gchar *profile;
      const gchar *level;
      long int spsint;
      guint8 sps[3];

      spsint = strtol (profile_level_id, NULL, 16);
      sps[0] = spsint >> 16;
      sps[1] = spsint >> 8;
      sps[2] = spsint;

      profile = gst_codec_utils_h264_get_profile (sps, 3);
      level = gst_codec_utils_h264_get_level (sps, 3);

      if (profile && level) {
        GST_LOG_OBJECT (payload, "In caps, have profile %s and level %s",
            profile, level);

        if (!strcmp (profile, "constrained-baseline"))
          gst_structure_set (new_s, "profile", G_TYPE_STRING, profile, NULL);
        else {
          GValue val = { 0, };
          GValue profiles = { 0, };

          g_value_init (&profiles, GST_TYPE_LIST);
          g_value_init (&val, G_TYPE_STRING);

          g_value_set_static_string (&val, profile);
          gst_value_list_append_value (&profiles, &val);

          g_value_set_static_string (&val, "constrained-baseline");
          gst_value_list_append_value (&profiles, &val);

          gst_structure_take_value (new_s, "profile", &profiles);
        }

        if (!strcmp (level, "1"))
          gst_structure_set (new_s, "level", G_TYPE_STRING, level, NULL);
        else {
          GValue levels = { 0, };
          GValue val = { 0, };
          int j;

          g_value_init (&levels, GST_TYPE_LIST);
          g_value_init (&val, G_TYPE_STRING);

          for (j = 0; j < G_N_ELEMENTS (all_levels); j++) {
            g_value_set_static_string (&val, all_levels[j]);
            gst_value_list_prepend_value (&levels, &val);
            if (!strcmp (level, all_levels[j]))
              break;
          }
          gst_structure_take_value (new_s, "level", &levels);
        }
      } else {
        /* Invalid profile-level-id means baseline */

        gst_structure_set (new_s,
            "profile", G_TYPE_STRING, "constrained-baseline", NULL);
      }
    } else {
      /* No profile-level-id means baseline or unrestricted */

      gst_structure_set (new_s,
          "profile", G_TYPE_STRING, "constrained-baseline", NULL);
      append_unrestricted = TRUE;
    }

    caps = gst_caps_merge_structure (caps, new_s);
  }
Esempio n. 10
0
static GstCaps *
gst_video_rate_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstVideoRate *videorate = GST_VIDEO_RATE (trans);
  GstCaps *ret;
  GstStructure *s, *s1, *s2, *s3 = NULL;
  int maxrate = g_atomic_int_get (&videorate->max_rate);
  gint i;

  ret = gst_caps_new_empty ();

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

    s1 = gst_structure_copy (s);
    s2 = gst_structure_copy (s);

    if (videorate->drop_only) {
      gint min_num = 0, min_denom = 1;
      gint max_num = G_MAXINT, max_denom = 1;

      /* Clamp the caps to our maximum rate as the first caps if possible */
      if (!gst_video_max_rate_clamp_structure (s1, maxrate,
              &min_num, &min_denom, &max_num, &max_denom)) {
        min_num = 0;
        min_denom = 1;
        max_num = maxrate;
        max_denom = 1;

        /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
         * caps should become [1..maxrate], [1..maxint] and the src caps just
         * [1..maxrate].  In case there was a caps incompatibility things will
         * explode later as appropriate :)
         *
         * In case [X..maxrate] == [X..maxint], skip as we'll set it later
         */
        if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
          gst_structure_set (s1, "framerate", GST_TYPE_FRACTION_RANGE,
              min_num, min_denom, maxrate, 1, NULL);
        else {
          gst_structure_free (s1);
          s1 = NULL;
        }
      }

      if (direction == GST_PAD_SRC) {
        /* We can accept anything as long as it's at least the minimal framerate
         * the the sink needs */
        gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
            min_num, min_denom, G_MAXINT, 1, NULL);

        /* Also allow unknown framerate, if it isn't already */
        if (min_num != 0 || min_denom != 1) {
          s3 = gst_structure_copy (s);
          gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
        }
      } else if (max_num != 0 || max_denom != 1) {
        /* We can provide everything upto the maximum framerate at the src */
        gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
            0, 1, max_num, max_denom, NULL);
      }
    } else if (direction == GST_PAD_SINK) {
      gint min_num = 0, min_denom = 1;
      gint max_num = G_MAXINT, max_denom = 1;

      if (!gst_video_max_rate_clamp_structure (s1, maxrate,
              &min_num, &min_denom, &max_num, &max_denom)) {
        gst_structure_free (s1);
        s1 = NULL;
      }
      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
          maxrate, 1, NULL);
    } else {
      /* set the framerate as a range */
      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
          G_MAXINT, 1, NULL);
    }
    if (s1 != NULL)
      ret = gst_caps_merge_structure (ret, s1);
    ret = gst_caps_merge_structure (ret, s2);
    if (s3 != NULL)
      ret = gst_caps_merge_structure (ret, s3);
  }
  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (ret);
    ret = intersection;
  }
  return ret;
}
Esempio n. 11
0
static GstCaps *
create_sink_caps (const GstAmcCodecInfo * codec_info)
{
  GstCaps *ret;
  gint i;

  ret = gst_caps_new_empty ();

  for (i = 0; i < codec_info->n_supported_types; i++) {
    const GstAmcCodecType *type = &codec_info->supported_types[i];

    if (strcmp (type->mime, "audio/mpeg") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/3gpp") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/AMR",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/amr-wb") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/AMR-WB",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/mp4a-latm") == 0) {
      gint j;
      GstStructure *tmp, *tmp2;
      gboolean have_profile = FALSE;
      GValue va = { 0, };
      GValue v = { 0, };

      g_value_init (&va, GST_TYPE_LIST);
      g_value_init (&v, G_TYPE_STRING);
      g_value_set_string (&v, "raw");
      gst_value_list_append_value (&va, &v);
      g_value_set_string (&v, "adts");
      gst_value_list_append_value (&va, &v);
      g_value_unset (&v);

      tmp = gst_structure_new ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 4,
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "framed", G_TYPE_BOOLEAN, TRUE, NULL);
      gst_structure_set_value (tmp, "stream-format", &va);
      g_value_unset (&va);

      for (j = 0; j < type->n_profile_levels; j++) {
        const gchar *profile;

        profile =
            gst_amc_aac_profile_to_string (type->profile_levels[j].profile);

        if (!profile) {
          GST_ERROR ("Unable to map AAC profile 0x%08x",
              type->profile_levels[j].profile);
          continue;
        }

        tmp2 = gst_structure_copy (tmp);
        gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL);
        ret = gst_caps_merge_structure (ret, tmp2);

        have_profile = TRUE;
      }

      if (!have_profile) {
        ret = gst_caps_merge_structure (ret, tmp);
      } else {
        gst_structure_free (tmp);
      }
    } else if (strcmp (type->mime, "audio/g711-alaw") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/x-alaw",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/g711-mlaw") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/x-mulaw",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/vorbis") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/x-vorbis",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/flac") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/x-flac",
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "framed", G_TYPE_BOOLEAN, TRUE, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else if (strcmp (type->mime, "audio/mpeg-L2") == 0) {
      GstStructure *tmp;

      tmp = gst_structure_new ("audio/mpeg",
          "mpegversion", G_TYPE_INT, 1,
          "layer", G_TYPE_INT, 2,
          "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
          "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
      ret = gst_caps_merge_structure (ret, tmp);
    } else {
      GST_WARNING ("Unsupported mimetype '%s'", type->mime);
    }
  }

  return ret;
}
Esempio n. 12
0
static GstCaps *
gst_rtp_h263p_pay_sink_getcaps (GstRTPBasePayload * payload, GstPad * pad,
    GstCaps * filter)
{
  GstRtpH263PPay *rtph263ppay;
  GstCaps *caps = NULL, *templ;
  GstCaps *peercaps = NULL;
  GstCaps *intersect = NULL;
  guint i;

  rtph263ppay = GST_RTP_H263P_PAY (payload);

  peercaps =
      gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), filter);

  /* if we're just outputting to udpsink or fakesink or so, we should also
   * accept any input compatible with our sink template caps */
  if (!peercaps || gst_caps_is_any (peercaps))
    return
        gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SINKPAD (payload));

  /* We basically need to differentiate two use-cases here: One where there's
   * a capsfilter after the payloader with caps created from an SDP; in this
   * case the filter caps are fixed and we want to signal to an encoder what
   * we want it to produce. The second case is simply payloader ! depayloader
   * where we are dealing with the depayloader's template caps. In this case
   * we should accept any input compatible with our sink template caps. */
  if (!gst_caps_is_fixed (peercaps))
    return
        gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SINKPAD (payload));

  templ = gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload));
  intersect = gst_caps_intersect (peercaps, templ);
  gst_caps_unref (peercaps);
  gst_caps_unref (templ);

  if (gst_caps_is_empty (intersect))
    return intersect;

  caps = gst_caps_new_empty ();
  for (i = 0; i < gst_caps_get_size (intersect); i++) {
    GstStructure *s = gst_caps_get_structure (intersect, i);
    const gchar *encoding_name = gst_structure_get_string (s, "encoding-name");

    if (!strcmp (encoding_name, "H263-2000")) {
      const gchar *profile_str = gst_structure_get_string (s, "profile");
      const gchar *level_str = gst_structure_get_string (s, "level");
      int profile = 0;
      int level = 0;

      if (profile_str && level_str) {
        gboolean i = FALSE, j = FALSE, l = FALSE, t = FALSE, f = FALSE,
            v = FALSE;
        GstStructure *new_s = gst_structure_new ("video/x-h263",
            "variant", G_TYPE_STRING, "itu",
            NULL);

        profile = atoi (profile_str);
        level = atoi (level_str);

        /* These profiles are defined in the H.263 Annex X */
        switch (profile) {
          case 0:
            /* The Baseline Profile (Profile 0) */
            break;
          case 1:
            /* H.320 Coding Efficiency Version 2 Backward-Compatibility Profile
             * (Profile 1)
             * Baseline + Annexes I, J, L.4 and T
             */
            i = j = l = t = TRUE;
            break;
          case 2:
            /* Version 1 Backward-Compatibility Profile (Profile 2)
             * Baseline + Annex F
             */
            i = j = l = t = f = TRUE;
            break;
          case 3:
            /* Version 2 Interactive and Streaming Wireless Profile
             * Baseline + Annexes I, J, T
             */
            i = j = t = TRUE;
            break;
          case 4:
            /* Version 3 Interactive and Streaming Wireless Profile (Profile 4)
             * Baseline + Annexes I, J, T, V, W.6.3.8,
             */
            /* Missing W.6.3.8 */
            i = j = t = v = TRUE;
            break;
          case 5:
            /* Conversational High Compression Profile (Profile 5)
             * Baseline + Annexes F, I, J, L.4, T, D, U
             */
            /* Missing D, U */
            f = i = j = l = t = TRUE;
            break;
          case 6:
            /* Conversational Internet Profile (Profile 6)
             * Baseline + Annexes F, I, J, L.4, T, D, U and
             * K with arbitratry slice ordering
             */
            /* Missing D, U, K with arbitratry slice ordering */
            f = i = j = l = t = TRUE;
            break;
          case 7:
            /* Conversational Interlace Profile (Profile 7)
             * Baseline + Annexes F, I, J, L.4, T, D, U,  W.6.3.11
             */
            /* Missing D, U, W.6.3.11 */
            f = i = j = l = t = TRUE;
            break;
          case 8:
            /* High Latency Profile (Profile 8)
             * Baseline + Annexes F, I, J, L.4, T, D, U, P.5, O.1.1 and
             * K with arbitratry slice ordering
             */
            /* Missing D, U, P.5, O.1.1 */
            f = i = j = l = t = TRUE;
            break;
        }


        if (f || i || j || t || l || v) {
          GValue list = { 0 };
          GValue vstr = { 0 };

          g_value_init (&list, GST_TYPE_LIST);
          g_value_init (&vstr, G_TYPE_STRING);

          g_value_set_static_string (&vstr, "h263");
          gst_value_list_append_value (&list, &vstr);
          g_value_set_static_string (&vstr, "h263p");
          gst_value_list_append_value (&list, &vstr);

          if (l || v) {
            g_value_set_static_string (&vstr, "h263pp");
            gst_value_list_append_value (&list, &vstr);
          }
          g_value_unset (&vstr);

          gst_structure_set_value (new_s, "h263version", &list);
          g_value_unset (&list);
        } else {
          gst_structure_set (new_s, "h263version", G_TYPE_STRING, "h263", NULL);
        }


        if (!f)
          gst_structure_set (new_s, "annex-f", G_TYPE_BOOLEAN, FALSE, NULL);
        if (!i)
          gst_structure_set (new_s, "annex-i", G_TYPE_BOOLEAN, FALSE, NULL);
        if (!j)
          gst_structure_set (new_s, "annex-j", G_TYPE_BOOLEAN, FALSE, NULL);
        if (!t)
          gst_structure_set (new_s, "annex-t", G_TYPE_BOOLEAN, FALSE, NULL);
        if (!l)
          gst_structure_set (new_s, "annex-l", G_TYPE_BOOLEAN, FALSE, NULL);
        if (!v)
          gst_structure_set (new_s, "annex-v", G_TYPE_BOOLEAN, FALSE, NULL);


        if (level <= 10 || level == 45) {
          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 176,
              "height", GST_TYPE_INT_RANGE, 1, 144,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30000, 2002, NULL);
          caps = gst_caps_merge_structure (caps, new_s);
        } else if (level <= 20) {
          GstStructure *s_copy = gst_structure_copy (new_s);

          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 352,
              "height", GST_TYPE_INT_RANGE, 1, 288,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30000, 2002, NULL);
          caps = gst_caps_merge_structure (caps, new_s);

          gst_structure_set (s_copy,
              "width", GST_TYPE_INT_RANGE, 1, 176,
              "height", GST_TYPE_INT_RANGE, 1, 144,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30000, 1001, NULL);
          caps = gst_caps_merge_structure (caps, s_copy);
        } else if (level <= 40) {

          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 352,
              "height", GST_TYPE_INT_RANGE, 1, 288,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 30000, 1001, NULL);
          caps = gst_caps_merge_structure (caps, new_s);
        } else if (level <= 50) {
          GstStructure *s_copy = gst_structure_copy (new_s);

          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 352,
              "height", GST_TYPE_INT_RANGE, 1, 288,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 50, 1, NULL);
          caps = gst_caps_merge_structure (caps, new_s);

          gst_structure_set (s_copy,
              "width", GST_TYPE_INT_RANGE, 1, 352,
              "height", GST_TYPE_INT_RANGE, 1, 240,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 60000, 1001, NULL);
          caps = gst_caps_merge_structure (caps, s_copy);
        } else if (level <= 60) {
          GstStructure *s_copy = gst_structure_copy (new_s);

          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 720,
              "height", GST_TYPE_INT_RANGE, 1, 288,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 50, 1, NULL);
          caps = gst_caps_merge_structure (caps, new_s);

          gst_structure_set (s_copy,
              "width", GST_TYPE_INT_RANGE, 1, 720,
              "height", GST_TYPE_INT_RANGE, 1, 240,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 60000, 1001, NULL);
          caps = gst_caps_merge_structure (caps, s_copy);
        } else if (level <= 70) {
          GstStructure *s_copy = gst_structure_copy (new_s);

          gst_structure_set (new_s,
              "width", GST_TYPE_INT_RANGE, 1, 720,
              "height", GST_TYPE_INT_RANGE, 1, 576,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 50, 1, NULL);
          caps = gst_caps_merge_structure (caps, new_s);

          gst_structure_set (s_copy,
              "width", GST_TYPE_INT_RANGE, 1, 720,
              "height", GST_TYPE_INT_RANGE, 1, 480,
              "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 60000, 1001, NULL);
          caps = gst_caps_merge_structure (caps, s_copy);
        } else {
          caps = gst_caps_merge_structure (caps, new_s);
        }

      } else {
        GstStructure *new_s = gst_structure_new ("video/x-h263",
            "variant", G_TYPE_STRING, "itu",
            "h263version", G_TYPE_STRING, "h263",
            NULL);

        GST_DEBUG_OBJECT (rtph263ppay, "No profile or level specified"
            " for H263-2000, defaulting to baseline H263");

        caps = gst_caps_merge_structure (caps, new_s);
      }
    } else {
      gboolean f = FALSE, i = FALSE, j = FALSE, t = FALSE;
      /* FIXME: ffmpeg support the Appendix K too, how do we express it ?
       *   guint k;
       */
      const gchar *str;
      GstStructure *new_s = gst_structure_new ("video/x-h263",
          "variant", G_TYPE_STRING, "itu",
          NULL);
      gboolean added = FALSE;

      str = gst_structure_get_string (s, "f");
      if (str && !strcmp (str, "1"))
        f = TRUE;

      str = gst_structure_get_string (s, "i");
      if (str && !strcmp (str, "1"))
        i = TRUE;

      str = gst_structure_get_string (s, "j");
      if (str && !strcmp (str, "1"))
        j = TRUE;

      str = gst_structure_get_string (s, "t");
      if (str && !strcmp (str, "1"))
        t = TRUE;

      if (f || i || j || t) {
        GValue list = { 0 };
        GValue vstr = { 0 };

        g_value_init (&list, GST_TYPE_LIST);
        g_value_init (&vstr, G_TYPE_STRING);

        g_value_set_static_string (&vstr, "h263");
        gst_value_list_append_value (&list, &vstr);
        g_value_set_static_string (&vstr, "h263p");
        gst_value_list_append_value (&list, &vstr);
        g_value_unset (&vstr);

        gst_structure_set_value (new_s, "h263version", &list);
        g_value_unset (&list);
      } else {
        gst_structure_set (new_s, "h263version", G_TYPE_STRING, "h263", NULL);
      }

      if (!f)
        gst_structure_set (new_s, "annex-f", G_TYPE_BOOLEAN, FALSE, NULL);
      if (!i)
        gst_structure_set (new_s, "annex-i", G_TYPE_BOOLEAN, FALSE, NULL);
      if (!j)
        gst_structure_set (new_s, "annex-j", G_TYPE_BOOLEAN, FALSE, NULL);
      if (!t)
        gst_structure_set (new_s, "annex-t", G_TYPE_BOOLEAN, FALSE, NULL);


      str = gst_structure_get_string (s, "custom");
      if (str) {
        unsigned int xmax, ymax, mpi;
        if (sscanf (str, "%u,%u,%u", &xmax, &ymax, &mpi) == 3) {
          if (xmax % 4 && ymax % 4 && mpi >= 1 && mpi <= 32) {
            caps = caps_append (caps, new_s, xmax, ymax, mpi);
            added = TRUE;
          } else {
            GST_WARNING_OBJECT (rtph263ppay, "Invalid custom framesize/MPI"
                " %u x %u at %u, ignoring", xmax, ymax, mpi);
          }
        } else {
          GST_WARNING_OBJECT (rtph263ppay, "Invalid custom framesize/MPI: %s,"
              " ignoring", str);
        }
      }

      str = gst_structure_get_string (s, "16cif");
      if (str) {
        int mpi = atoi (str);
        caps = caps_append (caps, new_s, 1408, 1152, mpi);
        added = TRUE;
      }

      str = gst_structure_get_string (s, "4cif");
      if (str) {
        int mpi = atoi (str);
        caps = caps_append (caps, new_s, 704, 576, mpi);
        added = TRUE;
      }

      str = gst_structure_get_string (s, "cif");
      if (str) {
        int mpi = atoi (str);
        caps = caps_append (caps, new_s, 352, 288, mpi);
        added = TRUE;
      }

      str = gst_structure_get_string (s, "qcif");
      if (str) {
        int mpi = atoi (str);
        caps = caps_append (caps, new_s, 176, 144, mpi);
        added = TRUE;
      }

      str = gst_structure_get_string (s, "sqcif");
      if (str) {
        int mpi = atoi (str);
        caps = caps_append (caps, new_s, 128, 96, mpi);
        added = TRUE;
      }

      if (added)
        gst_structure_free (new_s);
      else
        caps = gst_caps_merge_structure (caps, new_s);
    }
  }

  gst_caps_unref (intersect);

  return caps;
}
Esempio n. 13
0
void Caps::mergeStructure(const Structure & structure)
{
    gst_caps_merge_structure(object<GstCaps>(), gst_structure_copy(structure));
}
Esempio n. 14
0
static GstCaps *
gst_base_video_encoder_sink_getcaps (GstPad * pad)
{
  GstBaseVideoEncoder *base_video_encoder;
  const GstCaps *templ_caps;
  GstCaps *allowed;
  GstCaps *fcaps, *filter_caps;
  gint i, j;

  base_video_encoder = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad));

  /* FIXME: Allow subclass to override this? */

  /* Allow downstream to specify width/height/framerate/PAR constraints
   * and forward them upstream for video converters to handle
   */
  templ_caps =
      gst_pad_get_pad_template_caps (GST_BASE_VIDEO_CODEC_SINK_PAD
      (base_video_encoder));
  allowed =
      gst_pad_get_allowed_caps (GST_BASE_VIDEO_CODEC_SRC_PAD
      (base_video_encoder));
  if (!allowed || gst_caps_is_empty (allowed) || gst_caps_is_any (allowed)) {
    fcaps = gst_caps_copy (templ_caps);
    goto done;
  }

  GST_LOG_OBJECT (base_video_encoder, "template caps %" GST_PTR_FORMAT,
      templ_caps);
  GST_LOG_OBJECT (base_video_encoder, "allowed caps %" GST_PTR_FORMAT, allowed);

  filter_caps = gst_caps_new_empty ();

  for (i = 0; i < gst_caps_get_size (templ_caps); i++) {
    GQuark q_name =
        gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));

    for (j = 0; j < gst_caps_get_size (allowed); j++) {
      const GstStructure *allowed_s = gst_caps_get_structure (allowed, j);
      const GValue *val;
      GstStructure *s;

      s = gst_structure_id_empty_new (q_name);
      if ((val = gst_structure_get_value (allowed_s, "width")))
        gst_structure_set_value (s, "width", val);
      if ((val = gst_structure_get_value (allowed_s, "height")))
        gst_structure_set_value (s, "height", val);
      if ((val = gst_structure_get_value (allowed_s, "framerate")))
        gst_structure_set_value (s, "framerate", val);
      if ((val = gst_structure_get_value (allowed_s, "pixel-aspect-ratio")))
        gst_structure_set_value (s, "pixel-aspect-ratio", val);

      gst_caps_merge_structure (filter_caps, s);
    }
  }

  fcaps = gst_caps_intersect (filter_caps, templ_caps);
  gst_caps_unref (filter_caps);

done:

  gst_caps_replace (&allowed, NULL);

  GST_LOG_OBJECT (base_video_encoder, "Returning caps %" GST_PTR_FORMAT, fcaps);

  return fcaps;
}
Esempio n. 15
0
static GstCaps *
gst_video_rate_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps)
{
  GstVideoRate *videorate = GST_VIDEO_RATE (trans);
  GstCaps *ret;
  GstStructure *s, *s2;
  GstStructure *s3 = NULL;
  int maxrate = g_atomic_int_get (&videorate->max_rate);

  /* Should always be called with simple caps */
  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);

  ret = gst_caps_copy (caps);

  s = gst_caps_get_structure (ret, 0);
  s2 = gst_structure_copy (s);

  if (videorate->drop_only) {
    gint min_num = 0, min_denom = 1;
    gint max_num = G_MAXINT, max_denom = 1;

    /* Clamp the caps to our maximum rate as the first caps if possible */
    if (!gst_video_max_rate_clamp_structure (s, maxrate,
            &min_num, &min_denom, &max_num, &max_denom)) {
      min_num = 0;
      min_denom = 1;
      max_num = maxrate;
      max_denom = 1;

      /* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
       * caps should become [1..maxrate], [1..maxint] and the src caps just
       * [1..maxrate].  In case there was a caps incompatibility things will
       * explode later as appropriate :)
       *
       * In case [X..maxrate] == [X..maxint], skip as we'll set it later
       */
      if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
        gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE,
            min_num, min_denom, maxrate, 1, NULL);
      else
        gst_caps_remove_structure (ret, 0);
    }

    if (direction == GST_PAD_SRC) {
      /* We can accept anything as long as it's at least the minimal framerate
       * the the sink needs */
      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
          min_num, min_denom, G_MAXINT, 1, NULL);

      /* Also allow unknown framerate, if it isn't already */
      if (min_num != 0 || min_denom != 1) {
        s3 = gst_structure_copy (s);
        gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
      }
    } else if (max_num != 0 || max_denom != 1) {
      /* We can provide everything upto the maximum framerate at the src */
      gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
          0, 1, max_num, max_denom, NULL);
    }
  } else if (direction == GST_PAD_SINK) {
    gint min_num = 0, min_denom = 1;
    gint max_num = G_MAXINT, max_denom = 1;

    if (!gst_video_max_rate_clamp_structure (s, maxrate,
            &min_num, &min_denom, &max_num, &max_denom))
      gst_caps_remove_structure (ret, 0);

    gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
        maxrate, 1, NULL);
  } else {
    /* set the framerate as a range */
    gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
        G_MAXINT, 1, NULL);
  }

  gst_caps_merge_structure (ret, s2);
  if (s3 != NULL)
    gst_caps_merge_structure (ret, s3);

  return ret;
}