예제 #1
0
static gboolean
gst_dv_pay_negotiate (GstRTPDVPay * rtpdvpay, guint8 * data, guint size)
{
  const gchar *encode, *media;
  gboolean audio_bundled, res;

  if ((data[3] & 0x80) == 0) {  /* DSF flag */
    /* it's an NTSC format */
    if ((data[80 * 5 + 48 + 3] & 0x4) && (data[80 * 5 + 48] == 0x60)) { /* 4:2:2 sampling */
      /* NTSC 50Mbps */
      encode = "314M-25/525-60";
    } else {                    /* 4:1:1 sampling */
      /* NTSC 25Mbps */
      encode = "SD-VCR/525-60";
    }
  } else {
    /* it's a PAL format */
    if ((data[80 * 5 + 48 + 3] & 0x4) && (data[80 * 5 + 48] == 0x60)) { /* 4:2:2 sampling */
      /* PAL 50Mbps */
      encode = "314M-50/625-50";
    } else if ((data[5] & 0x07) == 0) { /* APT flag */
      /* PAL 25Mbps 4:2:0 */
      encode = "SD-VCR/625-50";
    } else
      /* PAL 25Mbps 4:1:1 */
      encode = "314M-25/625-50";
  }

  media = "video";
  audio_bundled = FALSE;

  switch (rtpdvpay->mode) {
    case GST_DV_PAY_MODE_AUDIO:
      media = "audio";
      break;
    case GST_DV_PAY_MODE_BUNDLED:
      audio_bundled = TRUE;
      break;
    default:
      break;
  }
  gst_basertppayload_set_options (GST_BASE_RTP_PAYLOAD (rtpdvpay), media, TRUE,
      "DV", 90000);

  if (audio_bundled) {
    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpdvpay),
        "encode", G_TYPE_STRING, encode,
        "audio", G_TYPE_STRING, "bundled", NULL);
  } else {
    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpdvpay),
        "encode", G_TYPE_STRING, encode, NULL);
  }
  return res;
}
예제 #2
0
static gboolean
gst_rtp_h263p_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gboolean res;
  GstCaps *peercaps;
  gchar *encoding_name = NULL;

  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  peercaps = gst_pad_peer_get_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload));
  if (peercaps) {
    GstCaps *intersect = gst_caps_intersect (peercaps,
        gst_pad_get_pad_template_caps (GST_BASE_RTP_PAYLOAD_SRCPAD (payload)));

    gst_caps_unref (peercaps);
    if (!gst_caps_is_empty (intersect)) {
      GstStructure *s = gst_caps_get_structure (intersect, 0);
      encoding_name = g_strdup (gst_structure_get_string (s, "encoding-name"));
    }
    gst_caps_unref (intersect);
  }

  if (!encoding_name)
    encoding_name = g_strdup ("H263-1998");

  gst_basertppayload_set_options (payload, "video", TRUE,
      (gchar *) encoding_name, 90000);
  res = gst_basertppayload_set_outcaps (payload, NULL);
  g_free (encoding_name);

  return res;
}
예제 #3
0
static gboolean
gst_rtp_gsm_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  const char *stname;
  GstStructure *structure;
  gboolean res;

  structure = gst_caps_get_structure (caps, 0);

  stname = gst_structure_get_name (structure);

  if (strcmp ("audio/x-gsm", stname))
    goto invalid_type;

  gst_basertppayload_set_options (payload, "audio", FALSE, "GSM", 8000);
  res = gst_basertppayload_set_outcaps (payload, NULL);

  return res;

  /* ERRORS */
invalid_type:
  {
    GST_WARNING_OBJECT (payload, "invalid media type received");
    return FALSE;
  }
}
예제 #4
0
static gboolean
gst_rtp_mpa_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gst_basertppayload_set_options (payload, "audio", TRUE, "MPA", 90000);
  gst_basertppayload_set_outcaps (payload, NULL);

  return TRUE;
}
예제 #5
0
static gboolean
gst_rtp_pcmu_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  payload->pt = GST_RTP_PAYLOAD_PCMU;
  gst_basertppayload_set_options (payload, "audio", FALSE, "PCMU", 8000);

  gst_basertppayload_set_outcaps (payload, NULL);

  return TRUE;
}
static gboolean
gst_rtp_mp2t_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gboolean res;

  gst_basertppayload_set_options (payload, "video", TRUE, "MP2T-ES", 90000);
  res = gst_basertppayload_set_outcaps (payload, NULL);

  return res;
}
예제 #7
0
static gboolean
gst_rtp_pcma_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gboolean res;

  payload->pt = GST_RTP_PAYLOAD_PCMA;

  gst_basertppayload_set_options (payload, "audio", FALSE, "PCMA", 8000);
  res = gst_basertppayload_set_outcaps (payload, NULL);

  return res;
}
예제 #8
0
static gboolean
gst_rtp_mp4g_pay_new_caps (GstRtpMP4GPay * rtpmp4gpay)
{
  gchar *config;
  GValue v = { 0 };
  gboolean res;

#define MP4GCAPS						\
  "streamtype", G_TYPE_STRING, rtpmp4gpay->streamtype, 		\
  "profile-level-id", G_TYPE_STRING, rtpmp4gpay->profile,	\
  "mode", G_TYPE_STRING, rtpmp4gpay->mode,			\
  "config", G_TYPE_STRING, config,				\
  "sizelength", G_TYPE_STRING, "13",				\
  "indexlength", G_TYPE_STRING, "3",				\
  "indexdeltalength", G_TYPE_STRING, "3",			\
  NULL

  g_value_init (&v, GST_TYPE_BUFFER);
  gst_value_set_buffer (&v, rtpmp4gpay->config);
  config = gst_value_serialize (&v);

  /* hmm, silly */
  if (rtpmp4gpay->params) {
    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
        "encoding-params", G_TYPE_STRING, rtpmp4gpay->params, MP4GCAPS);
  } else {
    res = gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4gpay),
        MP4GCAPS);
  }

  g_value_unset (&v);
  g_free (config);

#undef MP4GCAPS
  return res;
}
예제 #9
0
static gboolean
gst_rtp_mpv_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  const char *stname;
  GstStructure *structure;

  structure = gst_caps_get_structure (caps, 0);

  stname = gst_structure_get_name (structure);

  gst_basertppayload_set_options (payload, "video", FALSE, "MPV", 90000);
  gst_basertppayload_set_outcaps (payload, NULL);

  return TRUE;
}
예제 #10
0
static gboolean
gst_rtp_amr_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
{
  GstRtpAMRPay *rtpamrpay;
  gboolean res;
  const GstStructure *s;
  const gchar *str;

  rtpamrpay = GST_RTP_AMR_PAY (basepayload);

  /* figure out the mode Narrow or Wideband */
  s = gst_caps_get_structure (caps, 0);
  if ((str = gst_structure_get_name (s))) {
    if (strcmp (str, "audio/AMR") == 0)
      rtpamrpay->mode = GST_RTP_AMR_P_MODE_NB;
    else if (strcmp (str, "audio/AMR-WB") == 0)
      rtpamrpay->mode = GST_RTP_AMR_P_MODE_WB;
    else
      goto wrong_type;
  } else
    goto wrong_type;

  if (rtpamrpay->mode == GST_RTP_AMR_P_MODE_NB)
    gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR", 8000);
  else
    gst_basertppayload_set_options (basepayload, "audio", TRUE, "AMR-WB",
        16000);

  res = gst_basertppayload_set_outcaps (basepayload,
      "encoding-params", G_TYPE_STRING, "1", "octet-align", G_TYPE_STRING, "1",
      /* don't set the defaults
       *
       * "crc", G_TYPE_STRING, "0",
       * "robust-sorting", G_TYPE_STRING, "0",
       * "interleaving", G_TYPE_STRING, "0",
       */
      NULL);

  return res;

  /* ERRORS */
wrong_type:
  {
    GST_ERROR_OBJECT (rtpamrpay, "unsupported media type '%s'",
        GST_STR_NULL (str));
    return FALSE;
  }
}
예제 #11
0
static gboolean
gst_rtp_g723_pay_set_caps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gboolean res;
  GstStructure *structure;
  gint pt;

  structure = gst_caps_get_structure (caps, 0);
  if (!gst_structure_get_int (structure, "payload", &pt))
    pt = GST_RTP_PAYLOAD_G723;

  payload->pt = pt;
  payload->dynamic = pt != GST_RTP_PAYLOAD_G723;

  res = gst_basertppayload_set_outcaps (payload, NULL);

  return res;
}
예제 #12
0
static gboolean
gst_rtp_siren_pay_setcaps (GstBaseRTPPayload * basertppayload, GstCaps * caps)
{
  GstRTPSirenPay *rtpsirenpay;
  GstBaseRTPAudioPayload *basertpaudiopayload;
  gint dct_length;
  GstStructure *structure;
  const char *payload_name;

  rtpsirenpay = GST_RTP_SIREN_PAY (basertppayload);
  basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (basertppayload);

  structure = gst_caps_get_structure (caps, 0);

  gst_structure_get_int (structure, "dct-length", &dct_length);
  if (dct_length != 320)
    goto wrong_dct;

  payload_name = gst_structure_get_name (structure);
  if (g_ascii_strcasecmp ("audio/x-siren", payload_name))
    goto wrong_caps;

  gst_basertppayload_set_options (basertppayload, "audio", TRUE, "SIREN",
      16000);
  /* set options for this frame based audio codec */
  gst_base_rtp_audio_payload_set_frame_options (basertpaudiopayload, 20, 40);

  return gst_basertppayload_set_outcaps (basertppayload, NULL);

  /* ERRORS */
wrong_dct:
  {
    GST_ERROR_OBJECT (rtpsirenpay, "dct-length must be 320, received %d",
        dct_length);
    return FALSE;
  }
wrong_caps:
  {
    GST_ERROR_OBJECT (rtpsirenpay, "expected audio/x-siren, received %s",
        payload_name);
    return FALSE;
  }
}
예제 #13
0
static GstFlowReturn
gst_rtp_asf_pay_parse_headers (GstRtpAsfPay * rtpasfpay)
{
  gchar *maxps;
  g_return_val_if_fail (rtpasfpay->headers, GST_FLOW_ERROR);

  if (!gst_asf_parse_headers (rtpasfpay->headers, &rtpasfpay->asfinfo))
    goto error;

  GST_DEBUG_OBJECT (rtpasfpay, "Packets number: %" G_GUINT64_FORMAT,
      rtpasfpay->asfinfo.packets_count);
  GST_DEBUG_OBJECT (rtpasfpay, "Packets size: %" G_GUINT32_FORMAT,
      rtpasfpay->asfinfo.packet_size);
  GST_DEBUG_OBJECT (rtpasfpay, "Broadcast mode: %s",
      rtpasfpay->asfinfo.broadcast ? "true" : "false");

  /* get the config for caps */
  g_free (rtpasfpay->config);
  rtpasfpay->config = g_base64_encode (GST_BUFFER_DATA (rtpasfpay->headers),
      GST_BUFFER_SIZE (rtpasfpay->headers));
  GST_DEBUG_OBJECT (rtpasfpay, "Serialized headers to base64 string %s",
      rtpasfpay->config);

  g_assert (rtpasfpay->config != NULL);
  GST_DEBUG_OBJECT (rtpasfpay, "Setting optional caps values: maxps=%"
      G_GUINT32_FORMAT " and config=%s", rtpasfpay->asfinfo.packet_size,
      rtpasfpay->config);
  maxps =
      g_strdup_printf ("%" G_GUINT32_FORMAT, rtpasfpay->asfinfo.packet_size);
  gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpasfpay), "maxps",
      G_TYPE_STRING, maxps, "config", G_TYPE_STRING, rtpasfpay->config, NULL);
  g_free (maxps);

  return GST_FLOW_OK;

error:
  {
    GST_ELEMENT_ERROR (rtpasfpay, STREAM, DECODE, (NULL),
        ("Error parsing headers"));
    return GST_FLOW_ERROR;
  }
}
예제 #14
0
static void
gst_rtp_mp4v_pay_new_caps (GstRtpMP4VPay * rtpmp4vpay)
{
  gchar *profile, *config;
  GValue v = { 0 };

  profile = g_strdup_printf ("%d", rtpmp4vpay->profile);
  g_value_init (&v, GST_TYPE_BUFFER);
  gst_value_set_buffer (&v, rtpmp4vpay->config);
  config = gst_value_serialize (&v);

  gst_basertppayload_set_outcaps (GST_BASE_RTP_PAYLOAD (rtpmp4vpay),
      "profile-level-id", G_TYPE_STRING, profile,
      "config", G_TYPE_STRING, config, NULL);

  g_value_unset (&v);

  g_free (profile);
  g_free (config);
}
예제 #15
0
파일: gstrtpsbcpay.c 프로젝트: Bisheg/bluez
static gboolean gst_rtp_sbc_pay_set_caps(GstBaseRTPPayload *payload,
			GstCaps *caps)
{
	GstRtpSBCPay *sbcpay;
	gint rate, subbands, channels, blocks, bitpool;
	gint frame_len;
	const gchar *channel_mode;
	GstStructure *structure;

	sbcpay = GST_RTP_SBC_PAY(payload);

	structure = gst_caps_get_structure(caps, 0);
	if (!gst_structure_get_int(structure, "rate", &rate))
		return FALSE;
	if (!gst_structure_get_int(structure, "channels", &channels))
		return FALSE;
	if (!gst_structure_get_int(structure, "blocks", &blocks))
		return FALSE;
	if (!gst_structure_get_int(structure, "bitpool", &bitpool))
		return FALSE;
	if (!gst_structure_get_int(structure, "subbands", &subbands))
		return FALSE;

	channel_mode = gst_structure_get_string(structure, "mode");
	if (!channel_mode)
		return FALSE;

	frame_len = gst_rtp_sbc_pay_get_frame_len(subbands, channels, blocks,
				bitpool, channel_mode);

	sbcpay->frame_length = frame_len;

	gst_basertppayload_set_options(payload, "audio", TRUE, "SBC", rate);

	GST_DEBUG_OBJECT(payload, "calculated frame length: %d ", frame_len);

	return gst_basertppayload_set_outcaps(payload, NULL);
}
예제 #16
0
static gboolean
gst_rtp_speex_pay_parse_ident (GstRtpSPEEXPay * rtpspeexpay,
    const guint8 * data, guint size)
{
  guint32 version, header_size, rate, mode, nb_channels;
  GstBaseRTPPayload *payload;
  gchar *cstr;
  gboolean res;

  /* we need the header string (8), the version string (20), the version
   * and the header length. */
  if (size < 36)
    goto too_small;

  if (!g_str_has_prefix ((const gchar *) data, "Speex   "))
    goto wrong_header;

  /* skip header and version string */
  data += 28;

  version = GST_READ_UINT32_LE (data);
  if (version != 1)
    goto wrong_version;

  data += 4;
  /* ensure sizes */
  header_size = GST_READ_UINT32_LE (data);
  if (header_size < 80)
    goto header_too_small;

  if (size < header_size)
    goto payload_too_small;

  data += 4;
  rate = GST_READ_UINT32_LE (data);
  data += 4;
  mode = GST_READ_UINT32_LE (data);
  data += 8;
  nb_channels = GST_READ_UINT32_LE (data);

  GST_DEBUG_OBJECT (rtpspeexpay, "rate %d, mode %d, nb_channels %d",
      rate, mode, nb_channels);

  payload = GST_BASE_RTP_PAYLOAD (rtpspeexpay);

  gst_basertppayload_set_options (payload, "audio", FALSE, "SPEEX", rate);
  cstr = g_strdup_printf ("%d", nb_channels);
  res = gst_basertppayload_set_outcaps (payload, "encoding-params",
      G_TYPE_STRING, cstr, NULL);
  g_free (cstr);

  return res;

  /* ERRORS */
too_small:
  {
    GST_DEBUG_OBJECT (rtpspeexpay,
        "ident packet too small, need at least 32 bytes");
    return FALSE;
  }
wrong_header:
  {
    GST_DEBUG_OBJECT (rtpspeexpay,
        "ident packet does not start with \"Speex   \"");
    return FALSE;
  }
wrong_version:
  {
    GST_DEBUG_OBJECT (rtpspeexpay, "can only handle version 1, have version %d",
        version);
    return FALSE;
  }
header_too_small:
  {
    GST_DEBUG_OBJECT (rtpspeexpay,
        "header size too small, need at least 80 bytes, " "got only %d",
        header_size);
    return FALSE;
  }
payload_too_small:
  {
    GST_DEBUG_OBJECT (rtpspeexpay,
        "payload too small, need at least %d bytes, got only %d", header_size,
        size);
    return FALSE;
  }
}
예제 #17
0
static gboolean
gst_rtp_celt_pay_parse_ident (GstRtpCELTPay * rtpceltpay,
    const guint8 * data, guint size)
{
  guint32 version, header_size, rate, nb_channels, frame_size, overlap;
  guint32 bytes_per_packet;
  GstBaseRTPPayload *payload;
  gchar *cstr, *fsstr;
  gboolean res;

  /* we need the header string (8), the version string (20), the version
   * and the header length. */
  if (size < 36)
    goto too_small;

  if (!g_str_has_prefix ((const gchar *) data, "CELT    "))
    goto wrong_header;

  /* skip header and version string */
  data += 28;

  version = GST_READ_UINT32_LE (data);
  GST_DEBUG_OBJECT (rtpceltpay, "version %08x", version);
#if 0
  if (version != 1)
    goto wrong_version;
#endif

  data += 4;
  /* ensure sizes */
  header_size = GST_READ_UINT32_LE (data);
  if (header_size < 56)
    goto header_too_small;

  if (size < header_size)
    goto payload_too_small;

  data += 4;
  rate = GST_READ_UINT32_LE (data);
  data += 4;
  nb_channels = GST_READ_UINT32_LE (data);
  data += 4;
  frame_size = GST_READ_UINT32_LE (data);
  data += 4;
  overlap = GST_READ_UINT32_LE (data);
  data += 4;
  bytes_per_packet = GST_READ_UINT32_LE (data);

  GST_DEBUG_OBJECT (rtpceltpay, "rate %d, nb_channels %d, frame_size %d",
      rate, nb_channels, frame_size);
  GST_DEBUG_OBJECT (rtpceltpay, "overlap %d, bytes_per_packet %d",
      overlap, bytes_per_packet);

  payload = GST_BASE_RTP_PAYLOAD (rtpceltpay);

  gst_basertppayload_set_options (payload, "audio", FALSE, "CELT", rate);
  cstr = g_strdup_printf ("%d", nb_channels);
  fsstr = g_strdup_printf ("%d", frame_size);
  res = gst_basertppayload_set_outcaps (payload, "encoding-params",
      G_TYPE_STRING, cstr, "frame-size", G_TYPE_STRING, fsstr, NULL);
  g_free (cstr);
  g_free (fsstr);

  return res;

  /* ERRORS */
too_small:
  {
    GST_DEBUG_OBJECT (rtpceltpay,
        "ident packet too small, need at least 32 bytes");
    return FALSE;
  }
wrong_header:
  {
    GST_DEBUG_OBJECT (rtpceltpay,
        "ident packet does not start with \"CELT    \"");
    return FALSE;
  }
#if 0
wrong_version:
  {
    GST_DEBUG_OBJECT (rtpceltpay, "can only handle version 1, have version %d",
        version);
    return FALSE;
  }
#endif
header_too_small:
  {
    GST_DEBUG_OBJECT (rtpceltpay,
        "header size too small, need at least 80 bytes, " "got only %d",
        header_size);
    return FALSE;
  }
payload_too_small:
  {
    GST_DEBUG_OBJECT (rtpceltpay,
        "payload too small, need at least %d bytes, got only %d", header_size,
        size);
    return FALSE;
  }
}
예제 #18
0
static gboolean
gst_rtp_mpv_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
  gst_basertppayload_set_options (payload, "video", FALSE, "MPV", 90000);
  return gst_basertppayload_set_outcaps (payload, NULL);
}
예제 #19
0
static gboolean
gst_rtp_ilbc_pay_sink_setcaps (GstBaseRTPPayload * basertppayload,
    GstCaps * caps)
{
  GstRTPILBCPay *rtpilbcpay;
  GstBaseRTPAudioPayload *basertpaudiopayload;
  gboolean ret;
  gint mode;
  gchar *mode_str;
  GstStructure *structure;
  const char *payload_name;

  rtpilbcpay = GST_RTP_ILBC_PAY (basertppayload);
  basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (basertppayload);

  structure = gst_caps_get_structure (caps, 0);

  payload_name = gst_structure_get_name (structure);
  if (g_ascii_strcasecmp ("audio/x-iLBC", payload_name))
    goto wrong_caps;

  if (!gst_structure_get_int (structure, "mode", &mode))
    goto no_mode;

  if (mode != 20 && mode != 30)
    goto wrong_mode;

  gst_basertppayload_set_options (basertppayload, "audio", TRUE, "ILBC", 8000);
  /* set options for this frame based audio codec */
  gst_base_rtp_audio_payload_set_frame_options (basertpaudiopayload,
      mode, mode == 30 ? 50 : 38);

  mode_str = g_strdup_printf ("%d", mode);
  ret =
      gst_basertppayload_set_outcaps (basertppayload, "mode", G_TYPE_STRING,
      mode_str, NULL);
  g_free (mode_str);

  if (mode != rtpilbcpay->mode && rtpilbcpay->mode != -1)
    goto mode_changed;

  rtpilbcpay->mode = mode;

  return ret;

  /* ERRORS */
wrong_caps:
  {
    GST_ERROR_OBJECT (rtpilbcpay, "expected audio/x-iLBC, received %s",
        payload_name);
    return FALSE;
  }
no_mode:
  {
    GST_ERROR_OBJECT (rtpilbcpay, "did not receive a mode");
    return FALSE;
  }
wrong_mode:
  {
    GST_ERROR_OBJECT (rtpilbcpay, "mode must be 20 or 30, received %d", mode);
    return FALSE;
  }
mode_changed:
  {
    GST_ERROR_OBJECT (rtpilbcpay, "Mode has changed from %d to %d! "
        "Mode cannot change while streaming", rtpilbcpay->mode, mode);
    return FALSE;
  }
}
예제 #20
0
static gboolean
gst_rtp_g722_pay_setcaps (GstBaseRTPPayload * basepayload, GstCaps * caps)
{
    GstRtpG722Pay *rtpg722pay;
    GstStructure *structure;
    gint rate, channels, clock_rate;
    gboolean res;
    gchar *params;
    GstAudioChannelPosition *pos;
    const GstRTPChannelOrder *order;
    GstBaseRTPAudioPayload *basertpaudiopayload;

    basertpaudiopayload = GST_BASE_RTP_AUDIO_PAYLOAD (basepayload);
    rtpg722pay = GST_RTP_G722_PAY (basepayload);

    structure = gst_caps_get_structure (caps, 0);

    /* first parse input caps */
    if (!gst_structure_get_int (structure, "rate", &rate))
        goto no_rate;

    if (!gst_structure_get_int (structure, "channels", &channels))
        goto no_channels;

    /* get the channel order */
    pos = gst_audio_get_channel_positions (structure);
    if (pos)
        order = gst_rtp_channels_get_by_pos (channels, pos);
    else
        order = NULL;

    /* Clock rate is always 8000 Hz for G722 according to
     * RFC 3551 although the sampling rate is 16000 Hz */
    clock_rate = 8000;

    gst_basertppayload_set_options (basepayload, "audio", TRUE, "G722",
                                    clock_rate);
    params = g_strdup_printf ("%d", channels);

    if (!order && channels > 2) {
        GST_ELEMENT_WARNING (rtpg722pay, STREAM, DECODE,
                             (NULL), ("Unknown channel order for %d channels", channels));
    }

    if (order && order->name) {
        res = gst_basertppayload_set_outcaps (basepayload,
                                              "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
                                              channels, "channel-order", G_TYPE_STRING, order->name, NULL);
    } else {
        res = gst_basertppayload_set_outcaps (basepayload,
                                              "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
                                              channels, NULL);
    }

    g_free (params);
    g_free (pos);

    rtpg722pay->rate = rate;
    rtpg722pay->channels = channels;

    /* octet-per-sample is 1 * channels for G722 */
    gst_base_rtp_audio_payload_set_samplebits_options (basertpaudiopayload,
            4 * rtpg722pay->channels);

    return res;

    /* ERRORS */
no_rate:
    {
        GST_DEBUG_OBJECT (rtpg722pay, "no rate given");
        return FALSE;
    }
no_channels:
    {
        GST_DEBUG_OBJECT (rtpg722pay, "no channels given");
        return FALSE;
    }
}
static gboolean
gst_rtp_vraw_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps)
{
    GstRtpVRawPay *rtpvrawpay;
    GstStructure *s;
    gboolean res;
    const gchar *name;
    gint width, height;
    gint yp, up, vp;
    gint pgroup, ystride, uvstride = 0, xinc, yinc;
    GstVideoFormat sampling;
    const gchar *depthstr, *samplingstr, *colorimetrystr;
    gchar *wstr, *hstr;
    gboolean interlaced;
    const gchar *color_matrix;
    gint depth;

    rtpvrawpay = GST_RTP_VRAW_PAY (payload);

    s = gst_caps_get_structure (caps, 0);

    /* start parsing the format */
    name = gst_structure_get_name (s);

    /* these values are the only thing we can do */
    depthstr = "8";

    /* parse common width/height */
    res = gst_structure_get_int (s, "width", &width);
    res &= gst_structure_get_int (s, "height", &height);
    if (!res)
        goto missing_dimension;

    if (!gst_structure_get_boolean (s, "interlaced", &interlaced))
        interlaced = FALSE;

    color_matrix = gst_structure_get_string (s, "color-matrix");
    colorimetrystr = "SMPTE240M";
    if (color_matrix) {
        if (g_str_equal (color_matrix, "sdtv")) {
            /* BT.601 implies a bit more than just color-matrix */
            colorimetrystr = "BT601-5";
        } else if (g_str_equal (color_matrix, "hdtv")) {
            colorimetrystr = "BT709-2";
        }
    }

    yp = up = vp = 0;
    xinc = yinc = 1;

    if (!strcmp (name, "video/x-raw-rgb")) {
        gint amask, rmask;
        gboolean has_alpha;

        has_alpha = gst_structure_get_int (s, "alpha_mask", &amask);
        depth = 8;

        if (!gst_structure_get_int (s, "red_mask", &rmask))
            goto unknown_mask;

        if (has_alpha) {
            pgroup = 4;
            ystride = width * 4;
            if (rmask == 0xFF000000) {
                sampling = GST_VIDEO_FORMAT_RGBA;
                samplingstr = "RGBA";
            } else {
                sampling = GST_VIDEO_FORMAT_BGRA;
                samplingstr = "BGRA";
            }
        } else {
            pgroup = 3;
            ystride = GST_ROUND_UP_4 (width * 3);
            if (rmask == 0x00FF0000) {
                sampling = GST_VIDEO_FORMAT_RGB;
                samplingstr = "RGB";
            } else {
                sampling = GST_VIDEO_FORMAT_BGR;
                samplingstr = "BGR";
            }
        }
    } else if (!strcmp (name, "video/x-raw-yuv")) {
        guint32 fourcc;

        if (!gst_structure_get_fourcc (s, "format", &fourcc))
            goto unknown_fourcc;

        GST_LOG_OBJECT (payload, "have fourcc %" GST_FOURCC_FORMAT,
                        GST_FOURCC_ARGS (fourcc));

        switch (fourcc) {
        case GST_MAKE_FOURCC ('A', 'Y', 'U', 'V'):
            sampling = GST_VIDEO_FORMAT_AYUV;
            samplingstr = "YCbCr-4:4:4";
            pgroup = 3;
            ystride = width * 4;
            depth = 8;
            break;
        case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
            sampling = GST_VIDEO_FORMAT_UYVY;
            samplingstr = "YCbCr-4:2:2";
            pgroup = 4;
            xinc = 2;
            ystride = GST_ROUND_UP_2 (width) * 2;
            depth = 8;
            break;
        case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
            sampling = GST_VIDEO_FORMAT_Y41B;
            samplingstr = "YCbCr-4:1:1";
            pgroup = 6;
            xinc = 4;
            ystride = GST_ROUND_UP_4 (width);
            uvstride = GST_ROUND_UP_8 (width) / 4;
            up = ystride * height;
            vp = up + uvstride * height;
            depth = 8;
            break;
        case GST_MAKE_FOURCC ('I', '4', '2', '0'):
            sampling = GST_VIDEO_FORMAT_I420;
            samplingstr = "YCbCr-4:2:0";
            pgroup = 6;
            xinc = yinc = 2;
            ystride = GST_ROUND_UP_4 (width);
            uvstride = GST_ROUND_UP_8 (width) / 2;
            up = ystride * GST_ROUND_UP_2 (height);
            vp = up + uvstride * GST_ROUND_UP_2 (height) / 2;
            depth = 8;
            break;
        case GST_MAKE_FOURCC ('U', 'Y', 'V', 'P'):
#define GST_VIDEO_FORMAT_UYVP GST_VIDEO_FORMAT_UYVY     /* FIXME */
            sampling = GST_VIDEO_FORMAT_UYVP;
            samplingstr = "YCbCr-4:2:2";
            pgroup = 4;
            xinc = 2;
            ystride = GST_ROUND_UP_2 (width) * 2;
            depth = 10;
            break;
        default:
            goto unknown_fourcc;
        }
    } else
        goto unknown_format;

    if (interlaced) {
        yinc *= 2;
    }
    if (depth == 10) {
        depthstr = "10";
    }

    rtpvrawpay->width = width;
    rtpvrawpay->height = height;
    rtpvrawpay->sampling = sampling;
    rtpvrawpay->pgroup = pgroup;
    rtpvrawpay->xinc = xinc;
    rtpvrawpay->yinc = yinc;
    rtpvrawpay->yp = yp;
    rtpvrawpay->up = up;
    rtpvrawpay->vp = vp;
    rtpvrawpay->ystride = ystride;
    rtpvrawpay->uvstride = uvstride;
    rtpvrawpay->interlaced = interlaced;
    rtpvrawpay->depth = depth;

    GST_DEBUG_OBJECT (payload, "width %d, height %d, sampling %d", width, height,
                      sampling);
    GST_DEBUG_OBJECT (payload, "yp %d, up %d, vp %d", yp, up, vp);
    GST_DEBUG_OBJECT (payload, "pgroup %d, ystride %d, uvstride %d", pgroup,
                      ystride, uvstride);

    wstr = g_strdup_printf ("%d", rtpvrawpay->width);
    hstr = g_strdup_printf ("%d", rtpvrawpay->height);

    gst_basertppayload_set_options (payload, "video", TRUE, "RAW", 90000);
    if (interlaced) {
        res = gst_basertppayload_set_outcaps (payload, "sampling", G_TYPE_STRING,
                                              samplingstr, "depth", G_TYPE_STRING, depthstr, "width", G_TYPE_STRING,
                                              wstr, "height", G_TYPE_STRING, hstr, "colorimetry", G_TYPE_STRING,
                                              colorimetrystr, "interlace", G_TYPE_STRING, "true", NULL);
    } else {
        res = gst_basertppayload_set_outcaps (payload, "sampling", G_TYPE_STRING,
                                              samplingstr, "depth", G_TYPE_STRING, depthstr, "width", G_TYPE_STRING,
                                              wstr, "height", G_TYPE_STRING, hstr, "colorimetry", G_TYPE_STRING,
                                              colorimetrystr, NULL);
    }
    g_free (wstr);
    g_free (hstr);

    return res;

    /* ERRORS */
unknown_mask:
    {
        GST_ERROR_OBJECT (payload, "unknown red mask specified");
        return FALSE;
    }
unknown_format:
    {
        GST_ERROR_OBJECT (payload, "unknown caps format");
        return FALSE;
    }
unknown_fourcc:
    {
        GST_ERROR_OBJECT (payload, "invalid or missing fourcc");
        return FALSE;
    }
missing_dimension:
    {
        GST_ERROR_OBJECT (payload, "missing width or height property");
        return FALSE;
    }
}