示例#1
0
static gboolean gst_iqcmplx_setcaps(GstPad *pad, GstCaps *caps)
{
	Gst_iqcmplx *cmplx;
	GstCaps *newcaps;
	GstStructure *structure;

	cmplx = GST_IQCMPLX(gst_pad_get_parent(pad));
	newcaps = gst_caps_copy(caps);
	if (!newcaps)
		return FALSE;
	structure = gst_caps_get_structure(newcaps, 0);

	if (!strcmp(gst_structure_get_name(structure), "audio/x-raw-float")) {
		gst_structure_set_name(structure, "audio/x-complex-float");
		gst_structure_set(structure, "channels", G_TYPE_INT, 1, NULL);
		gst_structure_set(structure, "depth", G_TYPE_INT, 64, NULL);
		gst_structure_set(structure, "width", G_TYPE_INT, 64, NULL);
	} else {
		gst_structure_set_name(structure, "audio/x-raw-float");
		gst_structure_set(structure, "channels", G_TYPE_INT, 2, NULL);
		gst_structure_set(structure, "depth", G_TYPE_INT, 32, NULL);
		gst_structure_set(structure, "width", G_TYPE_INT, 32, NULL);
	}
	gst_pad_use_fixed_caps(
	    pad == cmplx->srcpad ? cmplx->sinkpad : cmplx->srcpad);
	return gst_pad_set_caps(
	    pad == cmplx->srcpad ? cmplx->sinkpad : cmplx->srcpad, newcaps);
}
示例#2
0
/* copies the given caps */
static GstCaps *
gst_csp_caps_remove_format_info (GstCaps * caps)
{
  GstStructure *yuvst, *rgbst, *grayst;

  /* We know there's only one structure since we're given simple caps */
  caps = gst_caps_copy (caps);

  yuvst = gst_caps_get_structure (caps, 0);

  gst_structure_set_name (yuvst, "video/x-raw-yuv");
  gst_structure_remove_fields (yuvst, "format", "endianness", "depth",
      "bpp", "red_mask", "green_mask", "blue_mask", "alpha_mask",
      "palette_data", "color-matrix", NULL);

  rgbst = gst_structure_copy (yuvst);
  gst_structure_set_name (rgbst, "video/x-raw-rgb");
  gst_structure_remove_fields (rgbst, "color-matrix", "chroma-site", NULL);

  grayst = gst_structure_copy (rgbst);
  gst_structure_set_name (grayst, "video/x-raw-gray");

  gst_caps_append_structure (caps, rgbst);
  gst_caps_append_structure (caps, grayst);

  return caps;
}
static GstCaps *
gst_amr_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps, *templ;
  GstCaps *res;


  templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
  peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), filter);

  if (peercaps) {
    guint i, n;

    /* Rename structure names */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);

      if (gst_structure_has_name (s, "audio/AMR"))
        gst_structure_set_name (s, "audio/x-amr-nb-sh");
      else
        gst_structure_set_name (s, "audio/x-amr-wb-sh");
    }

    res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    res = gst_caps_make_writable (res);
    /* Append the template caps because we still want to accept
     * caps without any fields in the case upstream does not
     * know anything.
     */
    gst_caps_append (res, templ);
  } else {
    res = templ;
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

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

  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  ps = gst_caps_get_structure (caps, 0);

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

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

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

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

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

  otherpad = gst_pad_get_element_private (pad);

  ret = gst_pad_set_caps (otherpad, caps);

  gst_caps_unref (caps);

  return ret;
}
示例#5
0
static GstCaps *
mulawenc_getcaps (GstPad * pad)
{
  GstMuLawEnc *mulawenc;
  GstPad *otherpad;
  GstCaps *othercaps, *result;
  const GstCaps *templ;
  const gchar *name;
  gint i;

  mulawenc = GST_MULAWENC (GST_PAD_PARENT (pad));

  /* figure out the name of the caps we are going to return */
  if (pad == mulawenc->srcpad) {
    name = "audio/x-mulaw";
    otherpad = mulawenc->sinkpad;
  } else {
    name = "audio/x-raw-int";
    otherpad = mulawenc->srcpad;
  }
  /* get caps from the peer, this can return NULL when there is no peer */
  othercaps = gst_pad_peer_get_caps (otherpad);

  /* get the template caps to make sure we return something acceptable */
  templ = gst_pad_get_pad_template_caps (pad);

  if (othercaps) {
    /* there was a peer */
    othercaps = gst_caps_make_writable (othercaps);

    /* go through the caps and remove the fields we don't want */
    for (i = 0; i < gst_caps_get_size (othercaps); i++) {
      GstStructure *structure;

      structure = gst_caps_get_structure (othercaps, i);

      /* adjust the name */
      gst_structure_set_name (structure, name);

      if (pad == mulawenc->srcpad) {
        /* remove the fields we don't want */
        gst_structure_remove_fields (structure, "width", "depth", "endianness",
            "signed", NULL);
      } else {
        /* add fixed fields */
        gst_structure_set (structure, "width", G_TYPE_INT, 16,
            "depth", G_TYPE_INT, 16,
            "endianness", G_TYPE_INT, G_BYTE_ORDER,
            "signed", G_TYPE_BOOLEAN, TRUE, NULL);
      }
    }
    /* filter against the allowed caps of the pad to return our result */
    result = gst_caps_intersect (othercaps, templ);
    gst_caps_unref (othercaps);
  } else {
    /* there was no peer, return the template caps */
    result = gst_caps_copy (templ);
  }
  return result;
}
static GstCaps *
gst_mill_color_transform_caps (GstBaseTransform * btrans,
GstPadDirection direction, GstCaps * caps)
{
  const GstCaps *tmpl_caps = NULL;
  GstCaps *result = NULL, *local_caps = NULL;
  guint i;

  local_caps = gst_caps_copy (caps);

  for (i = 0; i < gst_caps_get_size (local_caps); i++) {
    GstStructure *structure = gst_caps_get_structure (local_caps, i);

    /* Throw away the structure name and set it to transformed format */
    if (direction == GST_PAD_SINK) {
      gst_structure_set_name (structure, "video/x-raw-yuv");
    } else if (direction == GST_PAD_SRC) {
      gst_structure_set_name (structure, "video/x-raw-rgb");
    }
    /* Remove any specific parameter from the structure */
    gst_structure_remove_field (structure, "format");
    gst_structure_remove_field (structure, "endianness");
    gst_structure_remove_field (structure, "depth");
    gst_structure_remove_field (structure, "bpp");
    gst_structure_remove_field (structure, "red_mask");
    gst_structure_remove_field (structure, "green_mask");
    gst_structure_remove_field (structure, "blue_mask");
    gst_structure_remove_field (structure, "alpha_mask");
  }

  /* Get the appropriate template */
  if (direction == GST_PAD_SINK) {
    tmpl_caps = gst_static_pad_template_get_caps (&src_template);
  } else if (direction == GST_PAD_SRC) {
    tmpl_caps = gst_static_pad_template_get_caps (&sink_template);
  }

  /* Intersect with our template caps */
  result = gst_caps_intersect (local_caps, tmpl_caps);

  gst_caps_unref (local_caps);
  gst_caps_do_simplify (result);

  GST_LOG ("transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT, caps, result);

  return result;
}
示例#7
0
/* copies the given caps */
static GstCaps *
gst_ffmpegcsp_caps_remove_format_info (GstCaps * caps)
{
  int i;
  GstStructure *structure;
  GstCaps *rgbcaps;
  GstCaps *graycaps;

  caps = gst_caps_copy (caps);

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

    gst_structure_set_name (structure, "video/x-raw-yuv");
    gst_structure_remove_field (structure, "format");
    gst_structure_remove_field (structure, "endianness");
    gst_structure_remove_field (structure, "depth");
    gst_structure_remove_field (structure, "bpp");
    gst_structure_remove_field (structure, "red_mask");
    gst_structure_remove_field (structure, "green_mask");
    gst_structure_remove_field (structure, "blue_mask");
    gst_structure_remove_field (structure, "alpha_mask");
    gst_structure_remove_field (structure, "palette_data");
  }

  gst_caps_do_simplify (caps);
  rgbcaps = gst_caps_copy (caps);

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

    gst_structure_set_name (structure, "video/x-raw-rgb");
  }
  graycaps = gst_caps_copy (caps);

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

    gst_structure_set_name (structure, "video/x-raw-gray");
  }

  gst_caps_append (caps, graycaps);
  gst_caps_append (caps, rgbcaps);

  return caps;
}
示例#8
0
GstCaps *
gst_vdp_yuv_to_video_caps (GstCaps * yuv_caps)
{
  GstCaps *video_caps;
  gint i;

  g_return_val_if_fail (GST_IS_CAPS (yuv_caps), NULL);

  video_caps = gst_caps_copy (yuv_caps);
  for (i = 0; i < gst_caps_get_size (video_caps); i++) {
    GstStructure *structure;
    guint32 fourcc;
    VdpChromaType chroma_type;

    structure = gst_caps_get_structure (video_caps, i);
    if (!gst_structure_has_name (structure, "video/x-raw-yuv"))
      goto not_yuv_error;

    if (!gst_structure_get_fourcc (structure, "format", &fourcc))
      goto no_format_error;

    chroma_type = -1;
    for (i = 0; i < G_N_ELEMENTS (formats); i++) {
      if (formats[i].fourcc == fourcc) {
        chroma_type = formats[i].chroma_type;
        break;
      }
    }

    if (chroma_type == -1)
      goto no_chroma_error;

    /* now we transform the caps */
    gst_structure_set_name (structure, "video/x-vdpau-video");
    gst_structure_remove_field (structure, "format");
    gst_structure_set (structure, "chroma-type", G_TYPE_INT, chroma_type, NULL);
  }

  return video_caps;

error:
  gst_caps_unref (video_caps);
  return NULL;

not_yuv_error:
  GST_WARNING ("The caps weren't of type \"video/x-raw-yuv\"");
  goto error;

no_format_error:
  GST_WARNING ("The caps didn't have a \"fourcc\" field");
  goto error;

no_chroma_error:
  GST_WARNING ("The caps had an invalid \"fourcc\" field");
  goto error;

}
static GstCaps *
gst_alpha_color_transform_caps (GstBaseTransform * btrans,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstCaps *tmpl_caps = NULL;
  GstCaps *result = NULL, *local_caps = NULL;
  guint i;

  local_caps = gst_caps_new_empty ();

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

    /* Remove any specific parameter from the structure */
    gst_structure_remove_field (structure, "format");
    gst_structure_remove_field (structure, "colorimetry");
    gst_structure_remove_field (structure, "chroma-site");

    gst_structure_set_name (structure, "video/x-raw");
    gst_caps_append_structure (local_caps, structure);
  }

  /* Get the appropriate template */
  if (direction == GST_PAD_SINK) {
    tmpl_caps = gst_static_pad_template_get_caps (&src_template);
  } else if (direction == GST_PAD_SRC) {
    tmpl_caps = gst_static_pad_template_get_caps (&sink_template);
  }

  /* Intersect with our template caps */
  result = gst_caps_intersect (local_caps, tmpl_caps);
  gst_caps_unref (tmpl_caps);
  gst_caps_unref (local_caps);

  result = gst_caps_simplify (result);

  GST_LOG_OBJECT (btrans, "transformed %" GST_PTR_FORMAT " to %" GST_PTR_FORMAT,
      caps, result);

  if (filter) {
    GstCaps *intersection;

    GST_DEBUG_OBJECT (btrans, "Using filter caps %" GST_PTR_FORMAT, filter);
    intersection =
        gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (result);
    result = intersection;
    GST_DEBUG_OBJECT (btrans, "Intersection %" GST_PTR_FORMAT, result);
  }


  return result;
}
示例#10
0
static GstCaps *
gst_caps_setter_transform_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps)
{
  GstCapsSetter *filter;
  GstCaps *ret, *filter_caps;
  GstStructure *structure, *merge;
  const gchar *name;
  gint i, j;

  filter = GST_CAPS_SETTER (trans);

  GST_DEBUG_OBJECT (trans, "receiving caps: %" GST_PTR_FORMAT, caps);

  ret = gst_caps_copy (caps);

  /* this function is always called with a simple caps */
  if (!GST_CAPS_IS_SIMPLE (ret) || direction != GST_PAD_SINK)
    return ret;

  structure = gst_caps_get_structure (ret, 0);
  name = gst_structure_get_name (structure);

  GST_OBJECT_LOCK (filter);
  filter_caps = gst_caps_ref (filter->caps);
  GST_OBJECT_UNLOCK (filter);

  for (i = 0; i < gst_caps_get_size (filter_caps); ++i) {
    merge = gst_caps_get_structure (filter_caps, i);
    if (gst_structure_has_name (merge, name) || !filter->join) {

      if (!filter->join)
        gst_structure_set_name (structure, gst_structure_get_name (merge));

      if (filter->replace)
        gst_structure_remove_all_fields (structure);

      for (j = 0; j < gst_structure_n_fields (merge); ++j) {
        const gchar *fname;

        fname = gst_structure_nth_field_name (merge, j);
        gst_structure_set_value (structure, fname,
            gst_structure_get_value (merge, fname));
      }
    }
  }

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

  gst_caps_unref (filter_caps);

  return ret;
}
示例#11
0
static GstCaps *
gst_smokeenc_getcaps (GstPad * pad)
{
  GstSmokeEnc *smokeenc = GST_SMOKEENC (gst_pad_get_parent (pad));
  GstPad *otherpad;
  GstCaps *result, *caps;
  const GstCaps *tcaps;
  const char *name;
  int i;
  GstStructure *structure = NULL;

  /* we want to proxy properties like width, height and framerate from the
     other end of the element */
  otherpad = (pad == smokeenc->srcpad) ? smokeenc->sinkpad : smokeenc->srcpad;

  /* get template caps, we always need this to fiter the peer caps */
  tcaps = gst_pad_get_pad_template_caps (otherpad);

  /* get any constraints on the peer pad */
  caps = gst_pad_peer_get_caps (otherpad);

  if (caps == NULL)
    caps = gst_caps_copy (tcaps);
  else
    caps = gst_caps_make_writable (caps);

  /* intersect with the template */
  result = gst_caps_intersect (caps, tcaps);
  gst_caps_unref (caps);

  if (pad == smokeenc->srcpad) {
    name = "video/x-smoke";
  } else {
    name = "video/x-raw-yuv";
  }

  /* we can only copy width, height, framerate from one side to the other */
  for (i = 0; i < gst_caps_get_size (result); i++) {
    structure = gst_caps_get_structure (result, i);

    gst_structure_set_name (structure, name);
    gst_structure_remove_field (structure, "format");
    /* ... but for the sink pad, we only do I420 anyway, so add that */
    if (pad == smokeenc->sinkpad) {
      gst_structure_set (structure, "format", GST_TYPE_FOURCC,
          GST_STR_FOURCC ("I420"), NULL);
    }
  }

  gst_object_unref (smokeenc);

  return result;
}
示例#12
0
GstCaps *
gst_vdp_video_to_output_caps (GstCaps * video_caps)
{
  GstCaps *output_caps;
  gint i;

  g_return_val_if_fail (GST_IS_CAPS (video_caps), NULL);

  output_caps = gst_caps_copy (video_caps);
  for (i = 0; i < gst_caps_get_size (video_caps); i++) {

    GstStructure *structure, *rgb_structure;

    structure = gst_caps_get_structure (output_caps, i);
    if (!gst_structure_has_name (structure, "video/x-vdpau-video"))
      goto not_video_error;

    rgb_structure = gst_structure_copy (structure);

    gst_structure_set_name (structure, "video/x-vdpau-output");
    gst_structure_remove_field (structure, "chroma-type");
    gst_vdp_video_remove_pixel_aspect_ratio (structure);

    gst_structure_set_name (rgb_structure, "video/x-raw-rgb");
    gst_structure_remove_field (rgb_structure, "chroma-type");
    gst_vdp_video_remove_pixel_aspect_ratio (rgb_structure);
    gst_caps_append_structure (output_caps, rgb_structure);
  }

  return output_caps;

error:
  gst_caps_unref (output_caps);
  return NULL;

not_video_error:
  GST_WARNING ("The caps weren't of type \"video/x-vdpau-video\"");
  goto error;
}
示例#13
0
void gst_caps_change_name (GstCaps* caps, const char* name)
{
    for (unsigned int i = 0; i < gst_caps_get_size(caps); ++i)
    {
        GstStructure* struc = gst_caps_get_structure(caps, i);

        if (struc != nullptr)
        {
            gst_structure_set_name(struc, name);
            gst_structure_remove_field(struc, "format");
        }
    }
}
示例#14
0
static gboolean
gst_dc1394_set_caps_color (GstStructure * gs, gint mc)
{
    gboolean ret = TRUE;
    gint fourcc;

    switch (mc) {
    case DC1394_COLOR_CODING_YUV444:
        gst_structure_set_name (gs, "video/x-raw-yuv");

        fourcc = GST_MAKE_FOURCC ('I', 'Y', 'U', '2');
        gst_structure_set (gs,
                           "format", GST_TYPE_FOURCC, fourcc, "bpp", G_TYPE_INT, 16, NULL);
        break;

    case DC1394_COLOR_CODING_YUV422:
        gst_structure_set_name (gs, "video/x-raw-yuv");
        fourcc = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
        gst_structure_set (gs,
                           "format", GST_TYPE_FOURCC, fourcc, "bpp", G_TYPE_INT, 16, NULL);
        break;

    case DC1394_COLOR_CODING_YUV411:
        gst_structure_set_name (gs, "video/x-raw-yuv");
        fourcc = GST_MAKE_FOURCC ('I', 'Y', 'U', '1');
        gst_structure_set (gs,
                           "format", GST_TYPE_FOURCC, fourcc, "bpp", G_TYPE_INT, 12, NULL);
        break;
    case DC1394_COLOR_CODING_RGB8:
        gst_structure_set_name (gs, "video/x-raw-rgb");
        gst_structure_set (gs,
                           "bpp", G_TYPE_INT, 24,
                           "depth", G_TYPE_INT, 24,
                           "endianness", G_TYPE_INT, G_BIG_ENDIAN,
                           "red_mask", G_TYPE_INT, 0xFF0000,
                           "green_mask", G_TYPE_INT, 0x00FF00,
                           "blue_mask", G_TYPE_INT, 0x0000FF, NULL);
        break;
    case DC1394_COLOR_CODING_MONO8:
        gst_structure_set_name (gs, "video/x-raw-gray");
        gst_structure_set (gs,
                           "bpp", G_TYPE_INT, 8, "depth", G_TYPE_INT, 8, NULL);

        break;
    case DC1394_COLOR_CODING_MONO16:
        gst_structure_set_name (gs, "video/x-raw-gray");
        gst_structure_set (gs,
                           "bpp", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
        // there is no fourcc for this format
        break;
    default:
        GST_DEBUG ("Ignoring unsupported color format %d", mc);
        ret = FALSE;
        break;
    }
    return ret;
}
示例#15
0
static GstCaps *
extend_caps (GstCaps * caps, gboolean add_private)
{
  guint i, n;
  GstCaps *ncaps = gst_caps_new_empty ();

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

    if (add_private && !gst_structure_has_name (s, "audio/x-private1-ac3")) {
      GstStructure *ns = gst_structure_copy (s);
      gst_structure_set_name (ns, "audio/x-private1-ac3");
      gst_caps_append_structure (ncaps, ns);
    } else if (!add_private &&
        gst_structure_has_name (s, "audio/x-private1-ac3")) {
      GstStructure *ns = gst_structure_copy (s);
      gst_structure_set_name (ns, "audio/x-ac3");
      gst_caps_append_structure (ncaps, ns);
      ns = gst_structure_copy (s);
      gst_structure_set_name (ns, "audio/x-eac3");
      gst_caps_append_structure (ncaps, ns);
    } else if (!add_private) {
      gst_caps_append_structure (ncaps, gst_structure_copy (s));
    }
  }

  if (add_private) {
    gst_caps_append (caps, ncaps);
  } else {
    gst_caps_unref (caps);
    caps = ncaps;
  }

  return caps;
}
示例#16
0
static GstCaps *
gst_xvidenc_getcaps (GstPad * pad)
{
  GstXvidEnc *xvidenc;
  GstPad *peer;
  GstCaps *caps;

  /* If we already have caps return them */
  if (GST_PAD_CAPS (pad))
    return gst_caps_ref (GST_PAD_CAPS (pad));

  xvidenc = GST_XVIDENC (gst_pad_get_parent (pad));
  if (!xvidenc)
    return gst_caps_new_empty ();

  peer = gst_pad_get_peer (xvidenc->srcpad);
  if (peer) {
    const GstCaps *templcaps;
    GstCaps *peercaps;
    guint i, n;

    peercaps = gst_pad_get_caps (peer);

    /* Translate peercaps to YUV */
    peercaps = gst_caps_make_writable (peercaps);
    n = gst_caps_get_size (peercaps);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (peercaps, i);

      gst_structure_set_name (s, "video/x-raw-yuv");
      gst_structure_remove_field (s, "mpegversion");
      gst_structure_remove_field (s, "systemstream");
    }

    templcaps = gst_pad_get_pad_template_caps (pad);

    caps = gst_caps_intersect (peercaps, templcaps);
    gst_caps_unref (peercaps);
    gst_object_unref (peer);
    peer = NULL;
  } else {
    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
  }

  gst_object_unref (xvidenc);

  return caps;
}
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;
}
示例#18
0
static GstCaps *
gst_shape_wipe_src_getcaps (GstPad * pad, GstCaps * filter)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad));
  GstCaps *templ, *ret, *tmp;

  if (gst_pad_has_current_caps (pad))
    return gst_pad_get_current_caps (pad);
  else if (gst_pad_has_current_caps (self->video_sinkpad))
    return gst_pad_get_current_caps (self->video_sinkpad);

  templ = gst_pad_get_pad_template_caps (self->video_sinkpad);
  tmp = gst_pad_peer_query_caps (self->video_sinkpad, NULL);
  if (tmp) {
    ret = gst_caps_intersect (tmp, templ);
    gst_caps_unref (templ);
    gst_caps_unref (tmp);
  } else {
    ret = templ;
  }

  GST_LOG_OBJECT (pad, "video sink accepted caps: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  tmp = gst_pad_peer_query_caps (pad, NULL);
  GST_LOG_OBJECT (pad, "peer accepted caps: %" GST_PTR_FORMAT, ret);
  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

  GST_LOG_OBJECT (pad, "intersection: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  if (self->vinfo.height && self->vinfo.width) {
    guint i, n;

    ret = gst_caps_make_writable (ret);
    n = gst_caps_get_size (ret);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (ret, i);

      gst_structure_set (s, "width", G_TYPE_INT, self->vinfo.width, "height",
          G_TYPE_INT, self->vinfo.height, NULL);
    }
  }

  tmp = gst_pad_peer_query_caps (self->mask_sinkpad, NULL);
  GST_LOG_OBJECT (pad, "mask sink accepted caps: %" GST_PTR_FORMAT, ret);
  if (tmp) {
    GstCaps *intersection, *tmp2;
    guint i, n;

    tmp2 = gst_pad_get_pad_template_caps (self->mask_sinkpad);
    intersection = gst_caps_intersect (tmp, tmp2);
    gst_caps_unref (tmp);
    gst_caps_unref (tmp2);

    tmp = gst_caps_make_writable (intersection);
    n = gst_caps_get_size (tmp);

    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (tmp, i);

      gst_structure_remove_fields (s, "format", "framerate", NULL);
      gst_structure_set_name (s, "video/x-raw");
    }

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

done:

  gst_object_unref (self);

  GST_LOG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}
示例#19
0
static GstCaps *
gst_shape_wipe_mask_sink_getcaps (GstPad * pad, GstCaps * filter)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad));
  GstCaps *ret, *tmp;
  guint i, n;

  if (gst_pad_has_current_caps (pad))
    return gst_pad_get_current_caps (pad);

  tmp = gst_pad_peer_query_caps (self->video_sinkpad, NULL);
  if (tmp) {
    ret =
        gst_caps_intersect (tmp,
        gst_pad_get_pad_template_caps (self->video_sinkpad));
    gst_caps_unref (tmp);
  } else {
    ret = gst_pad_get_pad_template_caps (self->video_sinkpad);
  }

  GST_LOG_OBJECT (pad, "video sink accepted caps: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  tmp = gst_pad_peer_query_caps (self->srcpad, NULL);
  GST_LOG_OBJECT (pad, "srcpad accepted caps: %" GST_PTR_FORMAT, ret);

  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (ret, tmp);
    gst_caps_unref (ret);
    gst_caps_unref (tmp);
    ret = intersection;
  }

  GST_LOG_OBJECT (pad, "intersection: %" GST_PTR_FORMAT, ret);

  if (gst_caps_is_empty (ret))
    goto done;

  n = gst_caps_get_size (ret);
  tmp = gst_caps_new_empty ();
  for (i = 0; i < n; i++) {
    GstStructure *s = gst_caps_get_structure (ret, i);
    GstStructure *t;

    gst_structure_set_name (s, "video/x-raw");
    gst_structure_remove_fields (s, "format", "framerate", NULL);

    if (self->vinfo.width && self->vinfo.height)
      gst_structure_set (s, "width", G_TYPE_INT, self->vinfo.width, "height",
          G_TYPE_INT, self->vinfo.height, NULL);

    gst_structure_set (s, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);

    t = gst_structure_copy (s);

    gst_structure_set (s, "format", G_TYPE_STRING, GST_VIDEO_NE (GRAY16), NULL);
    gst_structure_set (t, "format", G_TYPE_STRING, "GRAY8", NULL);

    gst_caps_append_structure (tmp, t);
  }
  gst_caps_append (ret, tmp);

  tmp = gst_pad_peer_query_caps (pad, NULL);
  GST_LOG_OBJECT (pad, "peer accepted caps: %" GST_PTR_FORMAT, tmp);

  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

done:
  gst_object_unref (self);

  GST_LOG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}
示例#20
0
static gboolean
gst_raw_video_parse_set_config_from_caps (GstRawBaseParse * raw_base_parse,
    GstRawBaseParseConfig config, GstCaps * caps)
{
  int i;
  GstStructure *structure;
  GstRawVideoParse *raw_video_parse = GST_RAW_VIDEO_PARSE (raw_base_parse);
  GstRawVideoParseConfig *config_ptr =
      gst_raw_video_parse_get_config_ptr (raw_video_parse, config);

  g_assert (caps != NULL);

  /* Caps might get copied, and the copy needs to be unref'd.
   * Also, the caller retains ownership over the original caps.
   * So, to make this mechanism also work with cases where the
   * caps are *not* copied, ref the original caps here first. */
  gst_caps_ref (caps);

  structure = gst_caps_get_structure (caps, 0);

  /* For unaligned raw data, the output caps stay the same,
   * except that video/x-unaligned-raw becomes video/x-raw,
   * since the parser aligns the frame data */
  if (gst_structure_has_name (structure, "video/x-unaligned-raw")) {
    /* Copy the caps to be able to modify them */
    GstCaps *new_caps = gst_caps_copy (caps);
    gst_caps_unref (caps);
    caps = new_caps;

    /* Change the media type to video/x-raw , otherwise
     * gst_video_info_from_caps() won't work */
    structure = gst_caps_get_structure (caps, 0);
    gst_structure_set_name (structure, "video/x-raw");
  }

  config_ptr->ready = gst_video_info_from_caps (&(config_ptr->info), caps);

  if (config_ptr->ready) {
    config_ptr->width = GST_VIDEO_INFO_WIDTH (&(config_ptr->info));
    config_ptr->height = GST_VIDEO_INFO_HEIGHT (&(config_ptr->info));
    config_ptr->pixel_aspect_ratio_n =
        GST_VIDEO_INFO_PAR_N (&(config_ptr->info));
    config_ptr->pixel_aspect_ratio_d =
        GST_VIDEO_INFO_PAR_D (&(config_ptr->info));
    config_ptr->framerate_n = GST_VIDEO_INFO_FPS_N (&(config_ptr->info));
    config_ptr->framerate_d = GST_VIDEO_INFO_FPS_D (&(config_ptr->info));
    config_ptr->interlaced = GST_VIDEO_INFO_IS_INTERLACED (&(config_ptr->info));
    config_ptr->height = GST_VIDEO_INFO_HEIGHT (&(config_ptr->info));
    config_ptr->top_field_first = 0;
    config_ptr->frame_stride = 0;

    for (i = 0; i < GST_VIDEO_MAX_PLANES; ++i) {
      config_ptr->plane_offsets[i] =
          GST_VIDEO_INFO_PLANE_OFFSET (&(config_ptr->info), i);
      config_ptr->plane_strides[i] =
          GST_VIDEO_INFO_PLANE_STRIDE (&(config_ptr->info), i);
    }
  }

  gst_caps_unref (caps);

  return config_ptr->ready;
}
static gboolean
compare_encoding_profile_with_discoverer_stream (GstValidateFileChecker * fc,
    GstEncodingProfile * prof, GstDiscovererStreamInfo * stream, gchar ** msg)
{
  gboolean ret = TRUE;
  GstCaps *caps = NULL;
  const GstCaps *profile_caps;
  const GstCaps *restriction_caps;

  caps = gst_discoverer_stream_info_get_caps (stream);
  profile_caps = gst_encoding_profile_get_format (prof);
  restriction_caps = gst_encoding_profile_get_restriction (prof);

  /* TODO need to consider profile caps restrictions */
  if (!_gst_caps_can_intersect_safe (caps, profile_caps)) {
    gchar *caps_str = gst_caps_to_string (caps);
    gchar *profile_caps_str = gst_caps_to_string (profile_caps);
    SET_MESSAGE (msg, g_strdup_printf ("Caps '%s' didn't match profile '%s'",
            profile_caps_str, caps_str));
    g_free (caps_str);
    g_free (profile_caps_str);
    ret = FALSE;
    goto end;
  }

  if (restriction_caps) {
    GstStructure *structure;
    gint i;
    gboolean found = FALSE;

    for (i = 0; i < gst_caps_get_size (restriction_caps); i++) {
      structure = gst_caps_get_structure (restriction_caps, i);
      structure = gst_structure_copy (structure);
      gst_structure_set_name (structure,
          gst_structure_get_name (gst_caps_get_structure (caps, 0)));
      if (gst_structure_can_intersect (structure, gst_caps_get_structure (caps,
                  0))) {
        gst_structure_free (structure);
        found = TRUE;
        break;
      }
      gst_structure_free (structure);
    }
    if (!found) {
      gchar *caps_str = gst_caps_to_string (caps);
      gchar *restriction_caps_str = gst_caps_to_string (restriction_caps);
      SET_MESSAGE (msg,
          g_strdup_printf ("Caps restriction '%s' wasn't respected on file "
              "with caps '%s'", restriction_caps_str, caps_str));
      g_free (caps_str);
      g_free (restriction_caps_str);
      ret = FALSE;
      goto end;
    }
  }

  if (GST_IS_ENCODING_CONTAINER_PROFILE (prof)) {
    if (GST_IS_DISCOVERER_CONTAINER_INFO (stream)) {
      ret =
          ret & compare_container_profile_with_container_discoverer_stream (fc,
          (GstEncodingContainerProfile *) prof,
          (GstDiscovererContainerInfo *) stream, msg);
    } else {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected container profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }

  } else if (GST_IS_ENCODING_VIDEO_PROFILE (prof)) {
    if (!GST_IS_DISCOVERER_VIDEO_INFO (stream)) {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected video profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }

  } else if (GST_IS_ENCODING_AUDIO_PROFILE (prof)) {
    if (!GST_IS_DISCOVERER_AUDIO_INFO (stream)) {
      SET_MESSAGE (msg,
          g_strdup_printf ("Expected audio profile but found stream of %s",
              gst_discoverer_stream_info_get_stream_type_nick (stream)));
      ret = FALSE;
      goto end;
    }
  } else {
    g_assert_not_reached ();
    return FALSE;
  }


end:
  if (caps)
    gst_caps_unref (caps);

  return ret;
}
示例#22
0
static gboolean
gst_srtp_dec_sink_query (GstPad * pad, GstObject * parent, GstQuery * query,
    gboolean is_rtcp)
{
  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter = NULL;
      GstCaps *other_filter = NULL;
      GstCaps *template_caps;
      GstPad *otherpad;
      GstCaps *other_caps;
      GstCaps *ret;
      int i;

      gst_query_parse_caps (query, &filter);

      otherpad = (GstPad *) gst_pad_get_element_private (pad);

      if (filter) {
        other_filter = gst_caps_copy (filter);

        for (i = 0; i < gst_caps_get_size (other_filter); i++) {
          GstStructure *ps = gst_caps_get_structure (other_filter, i);
          if (is_rtcp)
            gst_structure_set_name (ps, "application/x-rtcp");
          else
            gst_structure_set_name (ps, "application/x-rtp");
          gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher",
              "srtp-auth", "srtcp-cipher", "srtcp-auth", NULL);
        }
      }


      other_caps = gst_pad_peer_query_caps (otherpad, other_filter);
      if (other_filter)
        gst_caps_unref (other_filter);
      if (!other_caps) {
        goto return_template;
      }

      template_caps = gst_pad_get_pad_template_caps (otherpad);
      ret = gst_caps_intersect_full (other_caps, template_caps,
          GST_CAPS_INTERSECT_FIRST);
      gst_caps_unref (other_caps);
      gst_caps_unref (template_caps);

      ret = gst_caps_make_writable (ret);

      for (i = 0; i < gst_caps_get_size (ret); i++) {
        GstStructure *ps = gst_caps_get_structure (ret, i);
        if (is_rtcp)
          gst_structure_set_name (ps, "application/x-srtcp");
        else
          gst_structure_set_name (ps, "application/x-srtp");
      }

      if (filter) {
        GstCaps *tmp;

        tmp = gst_caps_intersect (ret, filter);
        gst_caps_unref (ret);
        ret = tmp;
      }

      gst_query_set_caps_result (query, ret);
      gst_caps_unref (ret);
      return TRUE;

    return_template:

      ret = gst_pad_get_pad_template_caps (pad);
      gst_query_set_caps_result (query, ret);
      gst_caps_unref (ret);
      return TRUE;
    }
    default:
      return gst_pad_query_default (pad, parent, query);
  }
}
示例#23
0
static GstCaps *
gst_shape_wipe_src_getcaps (GstPad * pad)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad));
  GstCaps *ret, *tmp;

  if (GST_PAD_CAPS (pad))
    return gst_caps_copy (GST_PAD_CAPS (pad));
  else if (GST_PAD_CAPS (self->video_sinkpad))
    return gst_caps_copy (GST_PAD_CAPS (self->video_sinkpad));

  tmp = gst_pad_peer_get_caps (self->video_sinkpad);
  if (tmp) {
    ret =
        gst_caps_intersect (tmp,
        gst_pad_get_pad_template_caps (self->video_sinkpad));
    gst_caps_unref (tmp);
  } else {
    ret = gst_caps_copy (gst_pad_get_pad_template_caps (self->video_sinkpad));
  }

  tmp = gst_pad_peer_get_caps (pad);
  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

  if (self->height && self->width) {
    guint i, n;

    n = gst_caps_get_size (ret);
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (ret, i);

      gst_structure_set (s, "width", G_TYPE_INT, self->width, "height",
          G_TYPE_INT, self->height, NULL);
    }
  }

  tmp = gst_pad_peer_get_caps (self->mask_sinkpad);
  if (tmp) {
    GstCaps *intersection, *tmp2;
    guint i, n;

    tmp = gst_caps_make_writable (tmp);
    tmp2 = gst_caps_copy (gst_pad_get_pad_template_caps (self->mask_sinkpad));

    intersection = gst_caps_intersect (tmp, tmp2);
    gst_caps_unref (tmp);
    gst_caps_unref (tmp2);

    tmp = intersection;
    n = gst_caps_get_size (tmp);

    tmp2 = gst_caps_new_empty ();
    for (i = 0; i < n; i++) {
      GstStructure *s = gst_caps_get_structure (tmp, i);
      GstStructure *c;

      gst_structure_remove_fields (s, "format", "bpp", "depth", "endianness",
          "framerate", "red_mask", "green_mask", "blue_mask", "alpha_mask",
          NULL);
      gst_structure_set_name (s, "video/x-raw-yuv");
      c = gst_structure_copy (s);

      gst_caps_append_structure (tmp2, c);
    }
    gst_caps_append (tmp, tmp2);

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

  gst_object_unref (self);

  GST_DEBUG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}
示例#24
0
/*
  Given the pad in this direction and the given caps, what caps are allowed on
  the other pad in this element ?
*/
static GstCaps *
gst_cenc_decrypt_transform_caps (GstBaseTransform * base,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
  GstCaps *res = NULL;
  gint i, j;

  g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);

  GST_DEBUG_OBJECT (base, "direction: %s   caps: %" GST_PTR_FORMAT "   filter:"
      " %" GST_PTR_FORMAT, (direction == GST_PAD_SRC) ? "Src" : "Sink",
      caps, filter);

  if(direction == GST_PAD_SRC && gst_caps_is_any (caps)){
    res = gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SINK_PAD (base));
    goto filter;
  }
  
  res = gst_caps_new_empty ();

  for (i = 0; i < gst_caps_get_size (caps); ++i) {
    GstStructure *in = gst_caps_get_structure (caps, i);
    GstStructure *out = NULL;

    if (direction == GST_PAD_SINK) {
      gint n_fields;

      if (!gst_structure_has_field (in, "original-media-type"))
        continue;

      out = gst_structure_copy (in);
      n_fields = gst_structure_n_fields (in);

      gst_structure_set_name (out,
          gst_structure_get_string (out, "original-media-type"));

      /* filter out the DRM related fields from the down-stream caps */
      for(j=n_fields-1; j>=0; --j){
          const gchar *field_name;

          field_name = gst_structure_nth_field_name (in, j);

          if( g_str_has_prefix(field_name, "protection-system") ||
              g_str_has_prefix(field_name, "original-media-type") ){
              gst_structure_remove_field (out, field_name);
          }
      }
      gst_cenc_decrypt_append_if_not_duplicate(res, out);
    } else {                    /* GST_PAD_SRC */
      gint n_fields;
      GstStructure *tmp = NULL;
      guint p;
      tmp = gst_structure_copy (in);
      gst_cenc_remove_codec_fields (tmp);
      for(p=0; gst_cenc_decrypt_protection_ids[p]; ++p){
        /* filter out the audio/video related fields from the down-stream 
           caps, because they are not relevant to the input caps of this 
           element and they can cause caps negotiation failures with 
           adaptive bitrate streams */
        out = gst_structure_copy (tmp);
        gst_structure_set (out,
                           "protection-system", G_TYPE_STRING, gst_cenc_decrypt_protection_ids[p],
                           "original-media-type", G_TYPE_STRING, gst_structure_get_name (in),
                           NULL);
        gst_structure_set_name (out, "application/x-cenc");
        gst_cenc_decrypt_append_if_not_duplicate(res, out);
      }
      gst_structure_free (tmp);
    }
  }
  if(direction == GST_PAD_SINK && gst_caps_get_size (res)==0){
    gst_caps_unref (res);
    res = gst_caps_new_any ();
  }
 filter:
  if (filter) {
    GstCaps *intersection;

    GST_DEBUG_OBJECT (base, "Using filter caps %" GST_PTR_FORMAT, filter);
    intersection =
      gst_caps_intersect_full (res, filter, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

  GST_DEBUG_OBJECT (base, "returning %" GST_PTR_FORMAT, res);
  return res;
}
static GstCaps* webkitMediaPlayReadyDecryptTransformCaps(GstBaseTransform* base, GstPadDirection direction, GstCaps* caps, GstCaps* filter)
{
    g_return_val_if_fail(direction != GST_PAD_UNKNOWN, nullptr);
    GstCaps* transformedCaps = gst_caps_new_empty();

    GST_LOG_OBJECT(base, "direction: %s, caps: %" GST_PTR_FORMAT " filter:"
        " %" GST_PTR_FORMAT, (direction == GST_PAD_SRC) ? "src" : "sink", caps, filter);

    unsigned size = gst_caps_get_size(caps);
    for (unsigned i = 0; i < size; ++i) {
        GstStructure* in = gst_caps_get_structure(caps, i);
        GstStructure* out = nullptr;

        if (direction == GST_PAD_SINK) {
            if (!gst_structure_has_field(in, "original-media-type"))
                continue;

            out = gst_structure_copy(in);
            gst_structure_set_name(out, gst_structure_get_string(out, "original-media-type"));

            /* filter out the DRM related fields from the down-stream caps */
            for (int j = 0; j < gst_structure_n_fields(in); ++j) {
                const gchar* fieldName = gst_structure_nth_field_name(in, j);

                if (g_str_has_prefix(fieldName, "protection-system")
                    || g_str_has_prefix(fieldName, "original-media-type"))
                    gst_structure_remove_field(out, fieldName);
            }
        } else {
            GstStructure* tmp = gst_structure_copy(in);
            /* filter out the video related fields from the up-stream caps,
               because they are not relevant to the input caps of this element and
               can cause caps negotiation failures with adaptive bitrate streams */
            for (int index = gst_structure_n_fields(tmp) - 1; index >= 0; --index) {
                const gchar* fieldName = gst_structure_nth_field_name(tmp, index);
                GST_TRACE("Check field \"%s\" for removal", fieldName);

                if (!g_strcmp0(fieldName, "base-profile")
                    || !g_strcmp0(fieldName, "codec_data")
                    || !g_strcmp0(fieldName, "height")
                    || !g_strcmp0(fieldName, "framerate")
                    || !g_strcmp0(fieldName, "level")
                    || !g_strcmp0(fieldName, "pixel-aspect-ratio")
                    || !g_strcmp0(fieldName, "profile")
                    || !g_strcmp0(fieldName, "rate")
                    || !g_strcmp0(fieldName, "width")) {
                    gst_structure_remove_field(tmp, fieldName);
                    GST_TRACE("Removing field %s", fieldName);
                }
            }

            out = gst_structure_copy(tmp);
            gst_structure_set(out, "protection-system", G_TYPE_STRING, PLAYREADY_PROTECTION_SYSTEM_ID,
                "original-media-type", G_TYPE_STRING, gst_structure_get_name(in), nullptr);

            gst_structure_set_name(out, "application/x-cenc");
            gst_structure_free(tmp);
        }

        webkitMediaPlayReadyDecryptCapsAppendIfNotDuplicate(transformedCaps, out);
    }

    if (filter) {
        GstCaps* intersection;

        GST_LOG_OBJECT(base, "Using filter caps %" GST_PTR_FORMAT, filter);
        intersection = gst_caps_intersect_full(transformedCaps, filter, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref(transformedCaps);
        transformedCaps = intersection;
    }

    GST_LOG_OBJECT(base, "returning %" GST_PTR_FORMAT, transformedCaps);
    return transformedCaps;
}
static GstCaps* webkitMediaCommonEncryptionDecryptTransformCaps(GstBaseTransform* base, GstPadDirection direction, GstCaps* caps, GstCaps* filter)
{
    if (direction == GST_PAD_UNKNOWN)
        return nullptr;

    GstCaps* transformedCaps = gst_caps_new_empty();
    WebKitMediaCommonEncryptionDecrypt* self = WEBKIT_MEDIA_CENC_DECRYPT(base);
    WebKitMediaCommonEncryptionDecryptClass* klass = WEBKIT_MEDIA_CENC_DECRYPT_GET_CLASS(self);

    GST_DEBUG_OBJECT(base, "direction: %s, caps: %" GST_PTR_FORMAT " filter: %" GST_PTR_FORMAT, (direction == GST_PAD_SRC) ? "src" : "sink", caps, filter);

    unsigned size = gst_caps_get_size(caps);
    for (unsigned i = 0; i < size; ++i) {
        GstStructure* in = gst_caps_get_structure(caps, i);
        GstStructure* out = nullptr;

        if (direction == GST_PAD_SINK) {
            if (!gst_structure_has_field(in, "original-media-type"))
                continue;

            out = gst_structure_copy(in);
            gst_structure_set_name(out, gst_structure_get_string(out, "original-media-type"));

            // Filter out the DRM related fields from the down-stream caps.
            for (int j = 0; j < gst_structure_n_fields(in); ++j) {
                const gchar* fieldName = gst_structure_nth_field_name(in, j);

                if (g_str_has_prefix(fieldName, "protection-system")
                    || g_str_has_prefix(fieldName, "original-media-type"))
                    gst_structure_remove_field(out, fieldName);
            }
        } else {
            GstStructure* tmp = gst_structure_copy(in);
            // Filter out the video related fields from the up-stream caps,
            // because they are not relevant to the input caps of this element and
            // can cause caps negotiation failures with adaptive bitrate streams.
            for (int index = gst_structure_n_fields(tmp) - 1; index >= 0; --index) {
                const gchar* fieldName = gst_structure_nth_field_name(tmp, index);
                GST_TRACE("Check field \"%s\" for removal", fieldName);

                if (!g_strcmp0(fieldName, "base-profile")
                    || !g_strcmp0(fieldName, "codec_data")
                    || !g_strcmp0(fieldName, "height")
                    || !g_strcmp0(fieldName, "framerate")
                    || !g_strcmp0(fieldName, "level")
                    || !g_strcmp0(fieldName, "pixel-aspect-ratio")
                    || !g_strcmp0(fieldName, "profile")
                    || !g_strcmp0(fieldName, "rate")
                    || !g_strcmp0(fieldName, "width")) {
                    gst_structure_remove_field(tmp, fieldName);
                    GST_TRACE("Removing field %s", fieldName);
                }
            }

            out = gst_structure_copy(tmp);
            gst_structure_set(out, "protection-system", G_TYPE_STRING, klass->protectionSystemId,
                "original-media-type", G_TYPE_STRING, gst_structure_get_name(in), nullptr);

            gst_structure_set_name(out, "application/x-cenc");
            gst_structure_free(tmp);
        }

        bool duplicate = false;
        unsigned size = gst_caps_get_size(transformedCaps);

        for (unsigned index = 0; !duplicate && index < size; ++index) {
            GstStructure* s = gst_caps_get_structure(transformedCaps, index);
            if (gst_structure_is_equal(s, out))
                duplicate = true;
        }

        if (!duplicate)
            gst_caps_append_structure(transformedCaps, out);
        else
            gst_structure_free(out);
    }

    if (filter) {
        GstCaps* intersection;

        GST_DEBUG_OBJECT(base, "Using filter caps %" GST_PTR_FORMAT, filter);
        intersection = gst_caps_intersect_full(transformedCaps, filter, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref(transformedCaps);
        transformedCaps = intersection;
    }

    GST_DEBUG_OBJECT(base, "returning %" GST_PTR_FORMAT, transformedCaps);
    return transformedCaps;
}
示例#27
0
static gboolean
gst_raw_audio_parse_caps_to_config (GstRawAudioParse * raw_audio_parse,
    GstCaps * caps, GstRawAudioParseConfig * config)
{
  gboolean ret = FALSE;
  GstStructure *structure;

  /* Caps might get copied, and the copy needs to be unref'd.
   * Also, the caller retains ownership over the original caps.
   * So, to make this mechanism also work with cases where the
   * caps are *not* copied, ref the original caps here first. */
  gst_caps_ref (caps);

  structure = gst_caps_get_structure (caps, 0);

  /* For unaligned raw data, the output caps stay the same,
   * except that audio/x-unaligned-raw becomes audio/x-raw,
   * since the parser aligns the sample data */
  if (gst_structure_has_name (structure, "audio/x-unaligned-raw")) {
    /* Copy the caps to be able to modify them */
    GstCaps *new_caps = gst_caps_copy (caps);
    gst_caps_unref (caps);
    caps = new_caps;

    /* Change the media type to audio/x-raw , otherwise
     * gst_audio_info_from_caps() won't work */
    structure = gst_caps_get_structure (caps, 0);
    gst_structure_set_name (structure, "audio/x-raw");
  }

  if (gst_structure_has_name (structure, "audio/x-raw")) {
    guint num_channels;
    GstAudioInfo info;
    if (!gst_audio_info_from_caps (&info, caps)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "failed to parse caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }

    num_channels = GST_AUDIO_INFO_CHANNELS (&info);

    config->format = GST_RAW_AUDIO_PARSE_FORMAT_PCM;
    config->pcm_format = GST_AUDIO_INFO_FORMAT (&info);
    config->bpf = GST_AUDIO_INFO_BPF (&info);
    config->sample_rate = GST_AUDIO_INFO_RATE (&info);
    config->interleaved =
        (GST_AUDIO_INFO_LAYOUT (&info) == GST_AUDIO_LAYOUT_INTERLEAVED);

    gst_raw_audio_parse_set_config_channels (config, num_channels, 0, FALSE);
    memcpy (config->channel_positions, &(GST_AUDIO_INFO_POSITION (&info, 0)),
        sizeof (GstAudioChannelPosition) * num_channels);
  } else if (gst_structure_has_name (structure, "audio/x-alaw")
      || gst_structure_has_name (structure, "audio/x-mulaw")) {
    gint i;
    guint64 channel_mask;
    guint num_channels;

    config->format =
        gst_structure_has_name (structure,
        "audio/x-alaw") ? GST_RAW_AUDIO_PARSE_FORMAT_ALAW :
        GST_RAW_AUDIO_PARSE_FORMAT_MULAW;

    if (!gst_structure_get_int (structure, "rate", &i)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "missing rate value in caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }
    config->sample_rate = i;

    if (!gst_structure_get_int (structure, "channels", &i)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "missing channels value in caps %" GST_PTR_FORMAT, (gpointer) caps);
      goto done;
    }
    num_channels = i;

    if (!gst_structure_get (structure, "channel-mask", GST_TYPE_BITMASK,
            &channel_mask, NULL)) {
      channel_mask = gst_audio_channel_get_fallback_mask (num_channels);
      GST_DEBUG_OBJECT (raw_audio_parse,
          "input caps have no channel mask - using fallback mask %#"
          G_GINT64_MODIFIER "x for %u channels", channel_mask, num_channels);
    }

    if (!gst_raw_audio_parse_set_config_channels (config, num_channels,
            channel_mask, TRUE)) {
      GST_ERROR_OBJECT (raw_audio_parse,
          "could not use channel mask %#" G_GINT64_MODIFIER
          "x for channel positions", channel_mask);
      goto done;
    }

    /* A-law and mu-law both use 1 byte per sample */
    config->bpf = 1 * num_channels;
  } else {
    GST_ERROR_OBJECT (raw_audio_parse,
        "caps %" GST_PTR_FORMAT " have an unsupported media type",
        (gpointer) caps);
    goto done;
  }

  ret = TRUE;

done:
  gst_caps_unref (caps);
  if (ret)
    config->ready = TRUE;
  return ret;
}
示例#28
0
static GstCaps *
gst_shape_wipe_mask_sink_getcaps (GstPad * pad)
{
  GstShapeWipe *self = GST_SHAPE_WIPE (gst_pad_get_parent (pad));
  GstCaps *ret, *tmp;
  guint i, n;

  if (GST_PAD_CAPS (pad))
    return gst_caps_copy (GST_PAD_CAPS (pad));

  tmp = gst_pad_peer_get_caps (self->video_sinkpad);
  if (tmp) {
    ret =
        gst_caps_intersect (tmp,
        gst_pad_get_pad_template_caps (self->video_sinkpad));
    gst_caps_unref (tmp);
  } else {
    ret = gst_caps_copy (gst_pad_get_pad_template_caps (self->video_sinkpad));
  }

  tmp = gst_pad_peer_get_caps (self->srcpad);
  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (ret, tmp);
    gst_caps_unref (ret);
    gst_caps_unref (tmp);
    ret = intersection;
  }

  n = gst_caps_get_size (ret);
  tmp = gst_caps_new_empty ();
  for (i = 0; i < n; i++) {
    GstStructure *s = gst_caps_get_structure (ret, i);
    GstStructure *t;

    gst_structure_set_name (s, "video/x-raw-gray");
    gst_structure_remove_fields (s, "format", "framerate", "bpp", "depth",
        "endianness", "framerate", "red_mask", "green_mask", "blue_mask",
        "alpha_mask", NULL);

    if (self->width && self->height)
      gst_structure_set (s, "width", G_TYPE_INT, self->width, "height",
          G_TYPE_INT, self->height, NULL);

    gst_structure_set (s, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);

    t = gst_structure_copy (s);

    gst_structure_set (s, "bpp", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
        "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL);
    gst_structure_set (t, "bpp", G_TYPE_INT, 8, "depth", G_TYPE_INT, 8, NULL);

    gst_caps_append_structure (tmp, t);
  }
  gst_caps_append (ret, tmp);

  tmp = gst_pad_peer_get_caps (pad);
  if (tmp) {
    GstCaps *intersection;

    intersection = gst_caps_intersect (tmp, ret);
    gst_caps_unref (tmp);
    gst_caps_unref (ret);
    ret = intersection;
  }

  gst_object_unref (self);

  GST_DEBUG_OBJECT (pad, "Returning caps: %" GST_PTR_FORMAT, ret);

  return ret;
}