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; }
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; }
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; } }
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; }
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; }
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; }
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; }
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; }
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; } }
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; }
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; } }
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; } }
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); }
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); }
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; } }
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; } }
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); }
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; } }
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; } }