void PointerDetectorFilter::removeWindow (std::string id) { GstStructure *buttonsLayout; gint len; /* The function obtains the actual window list */ g_object_get (G_OBJECT (pointerDetector), WINDOWS_LAYOUT, &buttonsLayout, NULL); len = gst_structure_n_fields (buttonsLayout); if (len == 0) { GST_WARNING ("There are no windows in the layout"); return; } for (int i = 0; i < len; i++) { const gchar *name; name = gst_structure_nth_field_name (buttonsLayout, i); if ( g_strcmp0 (name, id.c_str() ) == 0) { /* this window will be removed */ gst_structure_remove_field (buttonsLayout, name); } } /* Set the buttons layout list without the window with id = id */ g_object_set (G_OBJECT (pointerDetector), WINDOWS_LAYOUT, buttonsLayout, NULL); gst_structure_free (buttonsLayout); }
void ImageOverlayFilterImpl::removeImage (const std::string &id) { GstStructure *imagesLayout; gint len; /* The function obtains the actual window list */ g_object_get (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, &imagesLayout, NULL); len = gst_structure_n_fields (imagesLayout); if (len == 0) { GST_WARNING ("There are no images in the layout"); return; } for (int i = 0; i < len; i++) { const gchar *name; name = gst_structure_nth_field_name (imagesLayout, i); if (strcmp (id.c_str (), name) == 0) { /* this image will be removed */ gst_structure_remove_field (imagesLayout, name); break; } } /* Set the buttons layout list without the window with id = id */ g_object_set (G_OBJECT (imageOverlay), IMAGES_TO_OVERLAY, imagesLayout, NULL); gst_structure_free (imagesLayout); }
static GSList * get_faces (GstStructure * faces) { gint len, aux; GSList *list = NULL; len = gst_structure_n_fields (faces); for (aux = 0; aux < len; aux++) { GstStructure *face; gboolean ret; const gchar *name = gst_structure_nth_field_name (faces, aux); if (g_strcmp0 (name, "timestamp") == 0) { continue; } ret = gst_structure_get (faces, name, GST_TYPE_STRUCTURE, &face, NULL); if (ret) { CvRect *aux = g_slice_new0 (CvRect); gst_structure_get (face, "x", G_TYPE_UINT, &aux->x, NULL); gst_structure_get (face, "y", G_TYPE_UINT, &aux->y, NULL); gst_structure_get (face, "width", G_TYPE_UINT, &aux->width, NULL); gst_structure_get (face, "height", G_TYPE_UINT, &aux->height, NULL); gst_structure_free (face); list = g_slist_append (list, aux); } } return list; }
static void set_program (GstObject * elem, GstStructure * prog) { const GstStructure *s; GstControlSource *cs; GstClockTime ts, dur; gdouble v; const GValue *frame; GHashTable *css; gint i, j; const gchar *name; css = g_hash_table_new (g_str_hash, g_str_equal); ts = 0; dur = gst_util_uint64_scale_int (GST_SECOND, 1, 15); /* loop over each image in prog */ for (i = 0; i < gst_structure_n_fields (prog); i++) { GST_DEBUG ("ctrl on %" GST_TIME_FORMAT, GST_TIME_ARGS (ts)); frame = gst_structure_get_value (prog, gst_structure_nth_field_name (prog, i)); s = gst_value_get_structure (frame); for (j = 0; j < gst_structure_n_fields (s); j++) { name = gst_structure_nth_field_name (s, j); cs = g_hash_table_lookup (css, name); if (!cs) { cs = gst_interpolation_control_source_new (); gst_object_add_control_binding (elem, gst_direct_control_binding_new (elem, name, cs)); g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL); g_hash_table_insert (css, (gpointer) name, cs); gst_object_unref (cs); } gst_structure_get_double (s, name, &v); gst_timed_value_control_source_set ((GstTimedValueControlSource *) cs, ts, v); GST_DEBUG (" %s = %lf", name, v); } ts += dur; } g_hash_table_unref (css); }
/** * pk_gst_structure_to_provide: **/ static gchar * pk_gst_structure_to_provide (GstStructure *s) { GString *string; guint i, num_fields; GList *l; _cleanup_list_free_ GList *fields = NULL; num_fields = gst_structure_n_fields (s); fields = NULL; for (i = 0; i < num_fields; i++) { const gchar *field_name; field_name = gst_structure_nth_field_name (s, i); if (pk_gst_field_get_type (field_name) < 0) { g_message ("PackageKit: ignoring field named %s", field_name); continue; } fields = g_list_insert_sorted (fields, g_strdup (field_name), (GCompareFunc) pk_gst_fields_type_compare); } string = g_string_new(""); for (l = fields; l != NULL; l = l->next) { gchar *field_name; GType type; field_name = l->data; type = gst_structure_get_field_type (s, field_name); g_message ("PackageKit: field is: %s, type: %s", field_name, g_type_name (type)); if (type == G_TYPE_INT) { int value; gst_structure_get_int (s, field_name, &value); g_string_append_printf (string, "(%s=%d)", field_name, value); } else if (type == G_TYPE_BOOLEAN) { int value; gst_structure_get_boolean (s, field_name, &value); g_string_append_printf (string, "(%s=%s)", field_name, value ? "true" : "false"); } else if (type == G_TYPE_STRING) { const gchar *value; value = gst_structure_get_string (s, field_name); g_string_append_printf (string, "(%s=%s)", field_name, value); } else { g_warning ("PackageKit: unhandled type! %s", g_type_name (type)); } g_free (field_name); } return g_string_free (string, FALSE); }
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; }
static gboolean structure_is_subset (const GstStructure *st1, const GstStructure *st2) { int i; for (i = 0; i < gst_structure_n_fields (st2); i++) { const gchar *name = gst_structure_nth_field_name (st2, i); if (!gst_structure_has_field(st1, name)) { gupnp_dlna_debug (" missing field %s", name); return FALSE; } } return TRUE; }
static void clear_caps (GstCaps * caps, gboolean only_clock_rate) { gint i, j; /* Lets only match on the clock-rate */ for (i = 0; i < gst_caps_get_size (caps); i++) { GstStructure *s = gst_caps_get_structure (caps, i); for (j = 0; j < gst_structure_n_fields (s); j++) { const gchar *name = gst_structure_nth_field_name (s, j); if (strcmp (name, "clock-rate") && (only_clock_rate || (strcmp (name, "ssrc")))) { gst_structure_remove_field (s, name); j--; } } } }
static void collectRTCDataChannelStats (std::map <std::string, std::shared_ptr<Stats>> &statsReport, double timestamp, const GstStructure *stats) { gint i, n; n = gst_structure_n_fields (stats); for (i = 0; i < n; i++) { std::shared_ptr<RTCDataChannelStats> rtcDataStats; const GValue *value; const gchar *name; name = gst_structure_nth_field_name (stats, i); if (!g_str_has_prefix (name, "data-channel-") ) { continue; } value = gst_structure_get_value (stats, name); if (!GST_VALUE_HOLDS_STRUCTURE (value) ) { gchar *str_val; str_val = g_strdup_value_contents (value); GST_WARNING ("Unexpected field type (%s) = %s", name, str_val); g_free (str_val); continue; } rtcDataStats = createtRTCDataChannelStats (gst_value_get_structure (value) ); rtcDataStats->setTimestamp (timestamp); statsReport[rtcDataStats->getId ()] = rtcDataStats; } std::shared_ptr<RTCPeerConnectionStats> peerConnStats = createtRTCPeerConnectionStats (stats); peerConnStats->setTimestamp (timestamp); statsReport[peerConnStats->getId ()] = peerConnStats; }
/* filter out the audio and 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 */ static void gst_cenc_remove_codec_fields (GstStructure *gs) { gint j, n_fields = gst_structure_n_fields (gs); for(j=n_fields-1; j>=0; --j){ const gchar *field_name; field_name = gst_structure_nth_field_name (gs, j); GST_TRACE ("Check field \"%s\" for removal", field_name); if( g_strcmp0 (field_name, "base-profile")==0 || g_strcmp0 (field_name, "codec_data")==0 || g_strcmp0 (field_name, "height")==0 || g_strcmp0 (field_name, "framerate")==0 || g_strcmp0 (field_name, "level")==0 || g_strcmp0 (field_name, "pixel-aspect-ratio")==0 || g_strcmp0 (field_name, "profile")==0 || g_strcmp0 (field_name, "rate")==0 || g_strcmp0 (field_name, "width")==0 ){ gst_structure_remove_field (gs, field_name); GST_TRACE ("Removing field %s", field_name); } } }
/* 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 void kms_crowd_detector_extract_rois (KmsCrowdDetector * self) { int it = 0, it2; self->priv->num_rois = gst_structure_n_fields (self->priv->rois); if (self->priv->num_rois != 0) { self->priv->curves = g_malloc0 (sizeof (CvPoint *) * self->priv->num_rois); self->priv->n_points = g_malloc (sizeof (int) * self->priv->num_rois); self->priv->rois_data = g_malloc0 (sizeof (RoiData) * self->priv->num_rois); } while (it < self->priv->num_rois) { int len; GstStructure *roi; gboolean ret2; const gchar *nameRoi = gst_structure_nth_field_name (self->priv->rois, it); ret2 = gst_structure_get (self->priv->rois, nameRoi, GST_TYPE_STRUCTURE, &roi, NULL); if (!ret2) { continue; } len = gst_structure_n_fields (roi) - 1; self->priv->n_points[it] = len; if (len == 0) { self->priv->num_rois--; continue; } else { self->priv->curves[it] = g_malloc (sizeof (CvPoint) * len); } for (it2 = 0; it2 < len; it2++) { const gchar *name = gst_structure_nth_field_name (roi, it2); GstStructure *point; gboolean ret; ret = gst_structure_get (roi, name, GST_TYPE_STRUCTURE, &point, NULL); if (ret) { gfloat percentageX; gfloat percentageY; gst_structure_get (point, "x", G_TYPE_FLOAT, &percentageX, NULL); gst_structure_get (point, "y", G_TYPE_FLOAT, &percentageY, NULL); self->priv->curves[it][it2].x = percentageX * self->priv->image_width; self->priv->curves[it][it2].y = percentageY * self->priv->image_height; } gst_structure_free (point); } { const gchar *name = gst_structure_nth_field_name (roi, it2); GstStructure *point; gboolean ret; ret = gst_structure_get (roi, name, GST_TYPE_STRUCTURE, &point, NULL); if (ret) { self->priv->rois_data[it].name = NULL; gst_structure_get (point, "id", G_TYPE_STRING, &self->priv->rois_data[it].name, NULL); gst_structure_get (point, "occupancy_level_min", G_TYPE_INT, &self->priv->rois_data[it].occupancy_level_min, NULL); gst_structure_get (point, "occupancy_level_med", G_TYPE_INT, &self->priv->rois_data[it].occupancy_level_med, NULL); gst_structure_get (point, "occupancy_level_max", G_TYPE_INT, &self->priv->rois_data[it].occupancy_level_max, NULL); gst_structure_get (point, "occupancy_num_frames_to_event", G_TYPE_INT, &self->priv->rois_data[it].occupancy_num_frames_to_event, NULL); gst_structure_get (point, "fluidity_level_min", G_TYPE_INT, &self->priv->rois_data[it].fluidity_level_min, NULL); gst_structure_get (point, "fluidity_level_med", G_TYPE_INT, &self->priv->rois_data[it].fluidity_level_med, NULL); gst_structure_get (point, "fluidity_level_max", G_TYPE_INT, &self->priv->rois_data[it].fluidity_level_max, NULL); gst_structure_get (point, "fluidity_num_frames_to_event", G_TYPE_INT, &self->priv->rois_data[it].fluidity_num_frames_to_event, NULL); gst_structure_get (point, "send_optical_flow_event", G_TYPE_BOOLEAN, &self->priv->rois_data[it].send_optical_flow_event, NULL); gst_structure_get (point, "optical_flow_num_frames_to_event", G_TYPE_INT, &self->priv->rois_data[it].optical_flow_num_frames_to_event, NULL); gst_structure_get (point, "optical_flow_num_frames_to_reset", G_TYPE_INT, &self->priv->rois_data[it].optical_flow_num_frames_to_reset, NULL); gst_structure_get (point, "optical_flow_angle_offset", G_TYPE_INT, &self->priv->rois_data[it].optical_flow_angle_offset, NULL); GST_DEBUG ("rois info loaded: %s %d %d %d %d %d %d %d %d %d %d %d %d", self->priv->rois_data[it].name, self->priv->rois_data[it].occupancy_level_min, self->priv->rois_data[it].occupancy_level_med, self->priv->rois_data[it].occupancy_level_max, self->priv->rois_data[it].occupancy_num_frames_to_event, self->priv->rois_data[it].fluidity_level_min, self->priv->rois_data[it].fluidity_level_med, self->priv->rois_data[it].fluidity_level_max, self->priv->rois_data[it].fluidity_num_frames_to_event, self->priv->rois_data[it].send_optical_flow_event, self->priv->rois_data[it].optical_flow_num_frames_to_event, self->priv->rois_data[it].optical_flow_num_frames_to_reset, self->priv->rois_data[it].optical_flow_angle_offset); } gst_structure_free (point); } gst_structure_free (roi); it++; } self->priv->pixels_rois_counted = TRUE; }
static void make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPMedia * media, GstRTSPStream * stream, GstStructure * s, GstRTSPProfile profile) { GstSDPMedia *smedia; const gchar *caps_str, *caps_enc, *caps_params; gchar *tmp; gint caps_pt, caps_rate; guint n_fields, j; gboolean first; GString *fmtp; GstRTSPLowerTrans ltrans; GSocketFamily family; const gchar *addrtype, *proto; gchar *address; guint ttl; GstClockTime rtx_time; gst_sdp_media_new (&smedia); /* get media type and payload for the m= line */ caps_str = gst_structure_get_string (s, "media"); gst_sdp_media_set_media (smedia, caps_str); gst_structure_get_int (s, "payload", &caps_pt); tmp = g_strdup_printf ("%d", caps_pt); gst_sdp_media_add_format (smedia, tmp); g_free (tmp); gst_sdp_media_set_port_info (smedia, 0, 1); switch (profile) { case GST_RTSP_PROFILE_AVP: proto = "RTP/AVP"; break; case GST_RTSP_PROFILE_AVPF: proto = "RTP/AVPF"; break; case GST_RTSP_PROFILE_SAVP: proto = "RTP/SAVP"; break; case GST_RTSP_PROFILE_SAVPF: proto = "RTP/SAVPF"; break; default: proto = "udp"; break; } gst_sdp_media_set_proto (smedia, proto); if (info->is_ipv6) { addrtype = "IP6"; family = G_SOCKET_FAMILY_IPV6; } else { addrtype = "IP4"; family = G_SOCKET_FAMILY_IPV4; } ltrans = gst_rtsp_stream_get_protocols (stream); if (ltrans == GST_RTSP_LOWER_TRANS_UDP_MCAST) { GstRTSPAddress *addr; addr = gst_rtsp_stream_get_multicast_address (stream, family); if (addr == NULL) goto no_multicast; address = g_strdup (addr->address); ttl = addr->ttl; gst_rtsp_address_free (addr); } else { ttl = 16; if (info->is_ipv6) address = g_strdup ("::"); else address = g_strdup ("0.0.0.0"); } /* for the c= line */ gst_sdp_media_add_connection (smedia, "IN", addrtype, address, ttl, 1); g_free (address); /* get clock-rate, media type and params for the rtpmap attribute */ gst_structure_get_int (s, "clock-rate", &caps_rate); caps_enc = gst_structure_get_string (s, "encoding-name"); caps_params = gst_structure_get_string (s, "encoding-params"); if (caps_enc) { if (caps_params) tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate, caps_params); else tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate); gst_sdp_media_add_attribute (smedia, "rtpmap", tmp); g_free (tmp); } /* the config uri */ tmp = gst_rtsp_stream_get_control (stream); gst_sdp_media_add_attribute (smedia, "control", tmp); g_free (tmp); /* check for srtp */ do { GstBuffer *srtpkey; const GValue *val; const gchar *srtpcipher, *srtpauth, *srtcpcipher, *srtcpauth; GstMIKEYMessage *msg; GstMIKEYPayload *payload, *pkd; GBytes *bytes; GstMapInfo info; const guint8 *data; gsize size; gchar *base64; guint8 byte; guint32 ssrc; val = gst_structure_get_value (s, "srtp-key"); if (val == NULL) break; srtpkey = gst_value_get_buffer (val); if (srtpkey == NULL) break; srtpcipher = gst_structure_get_string (s, "srtp-cipher"); srtpauth = gst_structure_get_string (s, "srtp-auth"); srtcpcipher = gst_structure_get_string (s, "srtcp-cipher"); srtcpauth = gst_structure_get_string (s, "srtcp-auth"); if (srtpcipher == NULL || srtpauth == NULL || srtcpcipher == NULL || srtcpauth == NULL) break; msg = gst_mikey_message_new (); /* unencrypted MIKEY message, we send this over TLS so this is allowed */ gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT, FALSE, GST_MIKEY_PRF_MIKEY_1, 0, GST_MIKEY_MAP_TYPE_SRTP); /* add policy '0' for our SSRC */ gst_rtsp_stream_get_ssrc (stream, &ssrc); gst_mikey_message_add_cs_srtp (msg, 0, ssrc, 0); /* timestamp is now */ gst_mikey_message_add_t_now_ntp_utc (msg); /* add some random data */ gst_mikey_message_add_rand_len (msg, 16); /* the policy '0' is SRTP with the above discovered algorithms */ payload = gst_mikey_payload_new (GST_MIKEY_PT_SP); gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP); /* only AES-CM is supported */ byte = 1; gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1, &byte); /* Encryption key length */ byte = enc_key_length_from_cipher_name (srtpcipher); gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1, &byte); /* only HMAC-SHA1 */ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1, &byte); /* Authentication key length */ byte = auth_key_length_from_auth_name (srtpauth); gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 1, &byte); /* we enable encryption on RTP and RTCP */ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1, &byte); gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTCP_ENC, 1, &byte); /* we enable authentication on RTP and RTCP */ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_AUTH, 1, &byte); gst_mikey_message_add_payload (msg, payload); /* make unencrypted KEMAC */ payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC); gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL, GST_MIKEY_MAC_NULL); /* add the key in key data */ pkd = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA); gst_buffer_map (srtpkey, &info, GST_MAP_READ); gst_mikey_payload_key_data_set_key (pkd, GST_MIKEY_KD_TEK, info.size, info.data); gst_buffer_unmap (srtpkey, &info); /* add key data to KEMAC */ gst_mikey_payload_kemac_add_sub (payload, pkd); gst_mikey_message_add_payload (msg, payload); /* now serialize this to bytes */ bytes = gst_mikey_message_to_bytes (msg, NULL, NULL); gst_mikey_message_unref (msg); /* and make it into base64 */ data = g_bytes_get_data (bytes, &size); base64 = g_base64_encode (data, size); g_bytes_unref (bytes); tmp = g_strdup_printf ("mikey %s", base64); g_free (base64); gst_sdp_media_add_attribute (smedia, "key-mgmt", tmp); g_free (tmp); } while (FALSE); /* collect all other properties and add them to fmtp or attributes */ fmtp = g_string_new (""); g_string_append_printf (fmtp, "%d ", caps_pt); first = TRUE; n_fields = gst_structure_n_fields (s); for (j = 0; j < n_fields; j++) { const gchar *fname, *fval; fname = gst_structure_nth_field_name (s, j); /* filter out standard properties */ if (!strcmp (fname, "media")) continue; if (!strcmp (fname, "payload")) continue; if (!strcmp (fname, "clock-rate")) continue; if (!strcmp (fname, "encoding-name")) continue; if (!strcmp (fname, "encoding-params")) continue; if (!strcmp (fname, "ssrc")) continue; if (!strcmp (fname, "timestamp-offset")) continue; if (!strcmp (fname, "seqnum-offset")) continue; if (g_str_has_prefix (fname, "srtp-")) continue; if (g_str_has_prefix (fname, "srtcp-")) continue; /* handled later */ if (g_str_has_prefix (fname, "x-gst-rtsp-server-rtx-time")) continue; if (!strcmp (fname, "a-framesize")) { /* a-framesize attribute */ if ((fval = gst_structure_get_string (s, fname))) { tmp = g_strdup_printf ("%d %s", caps_pt, fval); gst_sdp_media_add_attribute (smedia, fname + 2, tmp); g_free (tmp); } continue; } if (g_str_has_prefix (fname, "a-")) { /* attribute */ if ((fval = gst_structure_get_string (s, fname))) gst_sdp_media_add_attribute (smedia, fname + 2, fval); continue; } if (g_str_has_prefix (fname, "x-")) { /* attribute */ if ((fval = gst_structure_get_string (s, fname))) gst_sdp_media_add_attribute (smedia, fname, fval); continue; } if ((fval = gst_structure_get_string (s, fname))) { g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval); first = FALSE; } } if (!first) { tmp = g_string_free (fmtp, FALSE); gst_sdp_media_add_attribute (smedia, "fmtp", tmp); g_free (tmp); } else { g_string_free (fmtp, TRUE); } update_sdp_from_tags (stream, smedia); if ((rtx_time = gst_rtsp_stream_get_retransmission_time (stream))) { /* ssrc multiplexed retransmit functionality */ guint rtx_pt = gst_rtsp_stream_get_retransmission_pt (stream); if (rtx_pt == 0) { g_warning ("failed to find an available dynamic payload type. " "Not adding retransmission"); } else { gchar *tmp; tmp = g_strdup_printf ("%d", rtx_pt); gst_sdp_media_add_format (smedia, tmp); g_free (tmp); tmp = g_strdup_printf ("%d rtx/%d", rtx_pt, caps_rate); gst_sdp_media_add_attribute (smedia, "rtpmap", tmp); g_free (tmp); tmp = g_strdup_printf ("%d apt=%d;rtx-time=%" G_GINT64_FORMAT, rtx_pt, caps_pt, GST_TIME_AS_MSECONDS (rtx_time)); gst_sdp_media_add_attribute (smedia, "fmtp", tmp); g_free (tmp); } } gst_sdp_message_add_media (sdp, smedia); gst_sdp_media_free (smedia); return; /* ERRORS */ no_multicast: { gst_sdp_media_free (smedia); g_warning ("ignoring stream %d without multicast address", gst_rtsp_stream_get_index (stream)); return; } }
static gboolean plugin_init (GstPlugin * plugin) { gboolean res = FALSE; gint n = 0; GST_DEBUG_CATEGORY_INIT (ladspa_debug, "ladspa", 0, "LADSPA plugins"); #ifdef ENABLE_NLS GST_DEBUG_OBJECT (plugin, "binding text domain %s to locale dir %s", GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif gst_plugin_add_dependency_simple (plugin, "LADSPA_PATH", GST_LADSPA_DEFAULT_PATH, NULL, GST_PLUGIN_DEPENDENCY_FLAG_NONE); #ifdef HAVE_LRDF lrdf_init (); #endif ladspa_meta_all = (GstStructure *) gst_plugin_get_cache_data (plugin); if (ladspa_meta_all) { n = gst_structure_n_fields (ladspa_meta_all); } GST_INFO_OBJECT (plugin, "%d entries in cache", n); if (!n) { ladspa_meta_all = gst_structure_new_empty ("ladspa"); if ((res = ladspa_plugin_path_search (plugin))) { n = gst_structure_n_fields (ladspa_meta_all); GST_INFO_OBJECT (plugin, "%d entries after scanning", n); gst_plugin_set_cache_data (plugin, ladspa_meta_all); } } else { res = TRUE; } if (n) { gint i; const gchar *name; const GValue *value; GST_INFO_OBJECT (plugin, "register types"); for (i = 0; i < n; i++) { name = gst_structure_nth_field_name (ladspa_meta_all, i); value = gst_structure_get_value (ladspa_meta_all, name); if (G_VALUE_TYPE (value) == GST_TYPE_STRUCTURE) { GstStructure *ladspa_meta = g_value_get_boxed (value); ladspa_plugin_register_element (plugin, ladspa_meta); } } } if (!res) { GST_WARNING_OBJECT (plugin, "no LADSPA plugins found, check LADSPA_PATH"); } /* we don't want to fail, even if there are no elements registered */ return TRUE; }
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 gboolean plugin_init (GstPlugin * plugin) { guint i, cnt; GST_DEBUG_CATEGORY_INIT (gstomx_debug, "omx", 0, "gst-openmax"); GST_DEBUG_CATEGORY_INIT (gstomx_util_debug, "omx_util", 0, "gst-openmax utility"); element_name_quark = g_quark_from_static_string ("element-name"); /* * First, call all the _get_type() functions to ensure the types are * registered. */ for (i = 0; i < G_N_ELEMENTS (get_type); i++) get_type[i] (); fetch_element_table (plugin); g_omx_init (); cnt = gst_structure_n_fields (element_table); for (i = 0; i < cnt; i++) { const gchar *element_name = gst_structure_nth_field_name (element_table, i); GstStructure *element = get_element_entry (element_name); const gchar *type_name, *parent_type_name; const gchar *component_name, *library_name; GType type; gint rank; GST_DEBUG ("element_name=%s, element=%" GST_PTR_FORMAT, element_name, element); parent_type_name = gst_structure_get_string (element, "parent-type"); type_name = gst_structure_get_string (element, "type"); component_name = gst_structure_get_string (element, "component-name"); library_name = gst_structure_get_string (element, "library-name"); if (!type_name || !component_name || !library_name) { g_warning ("malformed config file: missing required fields for %s", element_name); return FALSE; } if (parent_type_name) { type = g_type_from_name (parent_type_name); if (type) { type = create_subtype (type, type_name); } else { g_warning ("malformed config file: invalid parent-type '%s' for %s", parent_type_name, element_name); return FALSE; } } else { type = g_type_from_name (type_name); } if (!type) { g_warning ("malformed config file: invalid type '%s' for %s", type_name, element_name); return FALSE; } g_type_set_qdata (type, element_name_quark, (gpointer) element_name); if (!gst_structure_get_int (element, "rank", &rank)) { /* use default rank: */ rank = GST_RANK_NONE; } if (!gst_element_register (plugin, element_name, rank, type)) { g_warning ("failed registering '%s'", element_name); return FALSE; } } return TRUE; }
// possible values in GstCaps are: // width // height // format // framerate bool ExtractImageParams(GstCaps *caps, int & width, int & height, PixelFormat & pixelFormat) { width = height = 0; pixelFormat = PF__UNKNOWN; char text[4000]; text[0] = 0; strcat_s(text, "\r\n\r\n"); for (unsigned int j = 0; j < gst_caps_get_size(caps); ++j) { GstStructure * structure = gst_caps_get_structure(caps, j); for (int i = 0; i < gst_structure_n_fields(structure); ++i) { const char * name = gst_structure_nth_field_name(structure, i); GType type = gst_structure_get_field_type(structure, name); const GValue * value = gst_structure_get_value(structure, name); if (strcmp("width", name) == 0) { width = value->data->v_int; } if (strcmp("height", name) == 0) { height = value->data->v_int; } if (strcmp("format", name) == 0) { const gchar * format = g_value_get_string(value); if (strcmp(format, "RGB") == 0) pixelFormat = PF__RGB; else if (strcmp(format, "BGR") == 0) pixelFormat = PF__BGR; else if (strcmp(format, "I420") == 0) pixelFormat = PF__I420; } strcat_s(text, name); strcat_s(text, "["); strcat_s(text, g_type_name(type)); strcat_s(text, ":"); if (g_type_is_a(type, G_TYPE_STRING)) strcat_s(text, g_value_get_string(value)); else if (GST_VALUE_HOLDS_FRACTION(&type)) { char size[100]; sprintf_s(size, "%d/%d", value->data[0].v_int, value->data[1].v_int); strcat_s(text, size); } else { char size[100]; sprintf_s(size, "%d", value->data->v_int); strcat_s(text, size); } strcat(text ,"]\r\n"); } printf(text); } return width > 0 && height > 0 && pixelFormat != PF__UNKNOWN; }
/* * Makes a pipeline in the form: * filesrc location=file ! demuxer ! fakesink * * And gets the tags that are posted on the bus to compare * with the tags in 'tag_str' */ static void test_demux_tags (const gchar * tag_str, const gchar * demuxer, const gchar * file) { GstElement *pipeline; GstBus *bus; GMainLoop *loop; GstTagList *sent_tags; gint i, j, n_recv, n_sent; const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found; gint comparison; GstElement *demux; gchar *launch_str; guint bus_watch = 0; GST_DEBUG ("testing tags : %s", tag_str); if (received_tags) { gst_tag_list_free (received_tags); received_tags = NULL; } launch_str = g_strdup_printf ("filesrc location=%s ! %s name=demux ! " "fakesink", file, demuxer); pipeline = gst_parse_launch (launch_str, NULL); g_free (launch_str); fail_unless (pipeline != NULL); demux = gst_bin_get_by_name (GST_BIN (pipeline), "demux"); fail_unless (demux != NULL); loop = g_main_loop_new (NULL, TRUE); fail_unless (loop != NULL); bus = gst_element_get_bus (pipeline); fail_unless (bus != NULL); bus_watch = gst_bus_add_watch (bus, bus_handler, loop); gst_object_unref (bus); sent_tags = gst_structure_from_string (tag_str, NULL); fail_unless (sent_tags != NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop); GST_DEBUG ("mainloop done : %p", received_tags); /* verify tags */ fail_unless (received_tags != NULL); n_recv = gst_structure_n_fields (received_tags); n_sent = gst_structure_n_fields (sent_tags); fail_unless (n_recv >= n_sent); /* FIXME: compare taglits values */ for (i = 0; i < n_sent; i++) { name_sent = gst_structure_nth_field_name (sent_tags, i); value_sent = gst_structure_get_value (sent_tags, name_sent); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_structure_nth_field_name (received_tags, j); if (!strcmp (name_sent, name_recv)) { value_recv = gst_structure_get_value (received_tags, name_recv); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } fail_unless (found, "tag item %s is lost", name_sent); } gst_tag_list_free (received_tags); received_tags = NULL; gst_tag_list_free (sent_tags); gst_element_set_state (pipeline, GST_STATE_NULL); g_main_loop_unref (loop); g_object_unref (demux); g_object_unref (pipeline); g_source_remove (bus_watch); }
static GstBusSyncReply bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * pipeline) { const GstStructure *structure; gint64 position, length; GstFormat format = GST_FORMAT_TIME; const GValue *x_value, *y_value; gint x, i, y; /* select msg */ if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT || !gst_structure_has_name (gst_message_get_structure (message), "hand-gesture")) return GST_BUS_PASS; /* parse msg structure */ structure = gst_message_get_structure (message); /* if PALM gesture detected */ if (structure && strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 && strcmp (gst_structure_get_string (structure, "gesture"), "palm") == 0) { /* media operation - closed palm to stop media play */ gst_element_set_state (playbin, GST_STATE_PAUSED); } /* if FIST gesture detected */ if (structure && strcmp (gst_structure_get_name (structure), "hand-gesture") == 0 && strcmp (gst_structure_get_string (structure, "gesture"), "fist") == 0) { /* print message type and structure name */ g_print ("%s{{%s}}\n", gst_message_type_get_name (message->type), gst_structure_get_name (structure)); /* print msg structure names&values */ for (i = 0; i < gst_structure_n_fields (structure); i++) { const gchar *name = gst_structure_nth_field_name (structure, i); GType type = gst_structure_get_field_type (structure, name); const GValue *value = gst_structure_get_value (structure, name); type == G_TYPE_STRING ? g_print ("-%s[%s]{%s}\n", name, g_type_name (type), g_value_get_string (value)) : g_print ("-%s[%s]{%d}\n", name, g_type_name (type), g_value_get_uint (value)); } g_print ("\n"); /* get X,Y positions in frame */ x_value = gst_structure_get_value (structure, "x"); x = g_value_get_uint (x_value); y_value = gst_structure_get_value (structure, "y"); y = g_value_get_uint (y_value); /* set object volumes [0-10] based on Y */ g_object_set (G_OBJECT (playbin), "volume", (gdouble) (10 - y / 24), NULL); /* seek playback positions */ gst_element_query_duration (playbin, format, &length); /* Width = 320 is specified in caps */ position = (gint64) length *x / 320; gst_element_set_state (playbin, GST_STATE_PAUSED); gst_element_seek (GST_ELEMENT (playbin), 1.0, format, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); gst_element_set_state (GST_ELEMENT (playbin), GST_STATE_PLAYING); } gst_message_unref (message); return GST_BUS_DROP; }
static void kms_pointer_detector_load_buttonsLayout (KmsPointerDetector * pointerdetector) { int aux, len; gboolean have_inactive_icon, have_active_icon, have_transparency; gchar *inactive_uri, *active_uri; if (pointerdetector->buttonsLayoutList != NULL) { kms_pointer_detector_dispose_buttons_layout_list (pointerdetector); } len = gst_structure_n_fields (pointerdetector->buttonsLayout); GST_DEBUG ("len: %d", len); for (aux = 0; aux < len; aux++) { const gchar *name = gst_structure_nth_field_name (pointerdetector->buttonsLayout, aux); GstStructure *button; gboolean ret; ret = gst_structure_get (pointerdetector->buttonsLayout, name, GST_TYPE_STRUCTURE, &button, NULL); if (ret) { ButtonStruct *structAux = g_malloc0 (sizeof (ButtonStruct)); IplImage *aux = NULL; gst_structure_get (button, "upRightCornerX", G_TYPE_INT, &structAux->cvButtonLayout.x, NULL); gst_structure_get (button, "upRightCornerY", G_TYPE_INT, &structAux->cvButtonLayout.y, NULL); gst_structure_get (button, "width", G_TYPE_INT, &structAux->cvButtonLayout.width, NULL); gst_structure_get (button, "height", G_TYPE_INT, &structAux->cvButtonLayout.height, NULL); gst_structure_get (button, "id", G_TYPE_STRING, &structAux->id, NULL); have_inactive_icon = gst_structure_get (button, "inactive_uri", G_TYPE_STRING, &inactive_uri, NULL); have_transparency = gst_structure_get (button, "transparency", G_TYPE_DOUBLE, &structAux->transparency, NULL); have_active_icon = gst_structure_get (button, "active_uri", G_TYPE_STRING, &active_uri, NULL); if (have_inactive_icon) { aux = load_image (inactive_uri, pointerdetector->images_dir, structAux->id, INACTIVE_IMAGE_VARIANT_NAME); if (aux != NULL) { structAux->inactive_icon = cvCreateImage (cvSize (structAux->cvButtonLayout.width, structAux->cvButtonLayout.height), aux->depth, aux->nChannels); cvResize (aux, structAux->inactive_icon, CV_INTER_CUBIC); cvReleaseImage (&aux); } else { structAux->inactive_icon = NULL; } } else { structAux->inactive_icon = NULL; } if (have_active_icon) { aux = load_image (active_uri, pointerdetector->images_dir, structAux->id, ACTIVE_IMAGE_VARIANT_NAME); if (aux != NULL) { structAux->active_icon = cvCreateImage (cvSize (structAux->cvButtonLayout.width, structAux->cvButtonLayout.height), aux->depth, aux->nChannels); cvResize (aux, structAux->active_icon, CV_INTER_CUBIC); cvReleaseImage (&aux); } else { structAux->active_icon = NULL; } } else { structAux->active_icon = NULL; } if (have_transparency) { structAux->transparency = 1.0 - structAux->transparency; } else { structAux->transparency = 1.0; } GST_DEBUG ("check: %d %d %d %d", structAux->cvButtonLayout.x, structAux->cvButtonLayout.y, structAux->cvButtonLayout.width, structAux->cvButtonLayout.height); pointerdetector->buttonsLayoutList = g_slist_append (pointerdetector->buttonsLayoutList, structAux); gst_structure_free (button); if (have_inactive_icon) { g_free (inactive_uri); } if (have_active_icon) { g_free (active_uri); } } } }
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; }
static GstBusSyncReply bus_sync_handler (GstBus * bus, GstMessage * message, GstPipeline * pipeline) { const GstStructure *structure; const GValue *value; gchar *contents; gint i; guint size = 0; /* select msg */ if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT || !gst_structure_has_name (gst_message_get_structure (message), "facedetect")) return GST_BUS_PASS; /* parse msg structure */ structure = gst_message_get_structure (message); /* if facedetect is into buffer */ if (structure && strcmp (gst_structure_get_name (structure), "facedetect") == 0) { if (!silent) { /* print message type and structure name */ g_print ("Type message, name message: %s{{%s}}\n", gst_message_type_get_name (message->type), gst_structure_get_name (structure)); /* print msg structure names and type */ for (i = 0; i < gst_structure_n_fields (structure); i++) { const gchar *name = gst_structure_nth_field_name (structure, i); GType type = gst_structure_get_field_type (structure, name); g_print ("-Name field, type: %s[%s]\n", name, g_type_name (type)); } } /* get structure of faces */ value = gst_structure_get_value (structure, "faces"); /* obtain the contents into the structure */ contents = g_strdup_value_contents (value); if (!silent) g_print ("Detected objects: %s\n\n", *(&contents)); /* list size */ size = gst_value_list_get_size (value); /* if face is detected, obtain the values X and Y of mouth and of nose. */ if (size != 0) { GstState state; /* if paused, set to playing */ gst_element_get_state (GST_ELEMENT (playbin), &state, NULL, GST_CLOCK_TIME_NONE); if (state != GST_STATE_PLAYING) { gst_element_set_state (GST_ELEMENT (playbin), GST_STATE_PLAYING); } if (ctrlvol) { gdouble volume; const GValue *faces_value = gst_value_list_get_value (value, 0); const GstStructure *faces_structure = gst_value_get_structure (faces_value); gboolean have_mouth_y = gst_structure_has_field (faces_structure, "mouth->y"); gboolean have_mouth_x = gst_structure_has_field (faces_structure, "mouth->x"); gboolean have_nose_y = gst_structure_has_field (faces_structure, "nose->y"); gboolean have_nose_x = gst_structure_has_field (faces_structure, "nose->x"); /* get the volume value */ g_object_get (G_OBJECT (playbin), "volume", &volume, NULL); /* media operation - hide your mouth for down the volume of the video */ if (have_mouth_y == 0 && have_mouth_x == 0) { volume = volume - 0.5; if (volume <= 0.5) volume = 0.0; g_object_set (G_OBJECT (playbin), "volume", volume, NULL); } /* media operation - hide your nose for up the volume of the video */ if (have_nose_y == 0 && have_nose_x == 0) { volume = volume + 0.5; if (volume >= 9.5) volume = 10.0; g_object_set (G_OBJECT (playbin), "volume", volume, NULL); } } /* if face is not detected */ } else { /* media operation - hide your face to stop media play */ gst_element_set_state (playbin, GST_STATE_PAUSED); } } gst_message_unref (message); return GST_BUS_DROP; }
BoolLog SDPMedia::add_to_sdp_description(GstSDPMessage* sdp_description, unsigned int index, const std::string& ip_addr) const { if (0 == port_ || nullptr == caps_structure_) { return BoolLog(false, "missing information for adding media to sdp description"); } /* get media type and payload for the m= line */ std::string caps_str(gst_structure_get_string(caps_structure_, "media")); gst_sdp_media_set_media(media_, caps_str.c_str()); gint caps_pt = 0; gst_structure_get_int(caps_structure_, "payload", &caps_pt); gst_sdp_media_add_format(media_, std::to_string(caps_pt).c_str()); gst_sdp_media_set_port_info(media_, port_, 1); gst_sdp_media_set_proto(media_, "RTP/AVP"); /* for the c= line */ gst_sdp_media_add_connection(media_, "IN", "IP4", ip_addr.c_str(), 16, 0); // sendonly gst_sdp_media_add_attribute(media_, "sendonly", ""); /* get clock-rate, media type and params for the rtpmap attribute */ gint caps_rate = 0; gst_structure_get_int(caps_structure_, "clock-rate", &caps_rate); std::string caps_enc(gst_structure_get_string(caps_structure_, "encoding-name")); std::string rtpmap(std::to_string(caps_pt) + " " + caps_enc + "/" + std::to_string(caps_rate)); const gchar* caps_params = gst_structure_get_string(caps_structure_, "encoding-params"); if (nullptr != caps_params) { rtpmap.append("/"); rtpmap.append(caps_params); } gst_sdp_media_add_attribute(media_, "rtpmap", rtpmap.c_str()); /* the config uri */ std::string control("stream=" + std::to_string(index)); gst_sdp_media_add_attribute(media_, "control", control.c_str()); /* collect all other properties and add them to fmtp */ std::string fmtp = std::to_string(caps_pt); fmtp.append(" "); bool first = true; guint n_fields = gst_structure_n_fields(caps_structure_); for (uint j = 0; j < n_fields; j++) { const gchar* fname_c = gst_structure_nth_field_name(caps_structure_, j); if (nullptr == fname_c) continue; std::string fname(fname_c); /* filter out standard properties */ if (fname.compare("media") == 0 || fname.compare("payload") == 0 || fname.compare("clock-rate") == 0 || fname.compare("encoding-name") == 0 || fname.compare("encoding-params") == 0 || fname.compare("ssrc") == 0 || fname.compare("clock-base") == 0 || fname.compare("seqnum-base") == 0) continue; const gchar* struct_str = gst_structure_get_string(caps_structure_, fname.c_str()); if (nullptr == struct_str) continue; std::string val = std::string(struct_str); if (0 == fname.compare("sprop-parameter-sets")) { auto equal_pos = val.find('='); if (std::string::npos != equal_pos) { // removing buggy trailing = at the end of sprop-parameter-sets val = std::string(val, 0, equal_pos); } auto comma_pos = val.find(','); if (std::string::npos != comma_pos) { // removing buggy trailing comma and the rest from sprop-parameter-sets val = std::string(val, 0, comma_pos); } } std::string fname_value(fname + "=" + val); if (gst_structure_get_string(caps_structure_, fname.c_str())) { if (!first) fmtp.append(";"); else first = false; fmtp.append(fname_value); } } if (!first) gst_sdp_media_add_attribute(media_, "fmtp", fmtp.c_str()); for (auto& it : ice_candidate_values_) { gst_sdp_media_add_attribute(media_, "candidate", it.c_str()); } gst_sdp_message_add_media(sdp_description, media_); return BoolLog(true); }
static void test_tags (const gchar * tag_str) { GstElement *pipeline; GstBus *bus; GMainLoop *loop; GstTagList *sent_tags; gint i, j, n_recv, n_sent; const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found, ok; gint comparison; GstElement *videotestsrc, *jpegenc, *metadatamux, *metadatademux, *fakesink; GstTagSetter *setter; GST_DEBUG ("testing tags : %s", tag_str); if (received_tags) { gst_tag_list_free (received_tags); received_tags = NULL; } pipeline = gst_pipeline_new ("pipeline"); fail_unless (pipeline != NULL); videotestsrc = gst_element_factory_make ("videotestsrc", "src"); fail_unless (videotestsrc != NULL); g_object_set (G_OBJECT (videotestsrc), "num-buffers", 1, NULL); jpegenc = gst_element_factory_make ("jpegenc", "enc"); if (jpegenc == NULL) { g_print ("Cannot test - jpegenc not available\n"); return; } metadatamux = gst_element_factory_make ("metadatamux", "mux"); g_object_set (G_OBJECT (metadatamux), "exif", TRUE, NULL); fail_unless (metadatamux != NULL); metadatademux = gst_element_factory_make ("metadatademux", "demux"); fail_unless (metadatademux != NULL); fakesink = gst_element_factory_make ("fakesink", "sink"); fail_unless (fakesink != NULL); gst_bin_add_many (GST_BIN (pipeline), videotestsrc, jpegenc, metadatamux, metadatademux, fakesink, NULL); ok = gst_element_link_many (videotestsrc, jpegenc, metadatamux, metadatademux, fakesink, NULL); fail_unless (ok == TRUE); loop = g_main_loop_new (NULL, TRUE); fail_unless (loop != NULL); bus = gst_element_get_bus (pipeline); fail_unless (bus != NULL); gst_bus_add_watch (bus, bus_handler, loop); gst_object_unref (bus); gst_element_set_state (pipeline, GST_STATE_READY); setter = GST_TAG_SETTER (metadatamux); fail_unless (setter != NULL); sent_tags = gst_structure_from_string (tag_str, NULL); fail_unless (sent_tags != NULL); gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop); GST_DEBUG ("mainloop done : %p", received_tags); /* verify tags */ fail_unless (received_tags != NULL); n_recv = gst_structure_n_fields (received_tags); n_sent = gst_structure_n_fields (sent_tags); /* we also get e.g. an exif binary block */ fail_unless (n_recv >= n_sent); /* FIXME: compare taglits values */ for (i = 0; i < n_sent; i++) { name_sent = gst_structure_nth_field_name (sent_tags, i); value_sent = gst_structure_get_value (sent_tags, name_sent); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_structure_nth_field_name (received_tags, j); if (!strcmp (name_sent, name_recv)) { value_recv = gst_structure_get_value (received_tags, name_recv); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } fail_unless (found, "tag item %s is lost", name_sent); } gst_tag_list_free (received_tags); received_tags = NULL; gst_tag_list_free (sent_tags); gst_element_set_state (pipeline, GST_STATE_NULL); g_main_loop_unref (loop); g_object_unref (pipeline); }
/** * gst_rtsp_sdp_from_media: * @sdp: a #GstSDPMessage * @info: info * @media: a #GstRTSPMedia * * Add @media specific info to @sdp. @info is used to configure the connection * information in the SDP. * * Returns: TRUE on success. */ gboolean gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPMedia * media) { guint i, n_streams; gchar *rangestr; n_streams = gst_rtsp_media_n_streams (media); rangestr = gst_rtsp_media_get_range_string (media, FALSE, GST_RTSP_RANGE_NPT); if (rangestr == NULL) goto not_prepared; gst_sdp_message_add_attribute (sdp, "range", rangestr); g_free (rangestr); for (i = 0; i < n_streams; i++) { GstRTSPStream *stream; GstSDPMedia *smedia; GstStructure *s; const gchar *caps_str, *caps_enc, *caps_params; gchar *tmp; gint caps_pt, caps_rate; guint n_fields, j; gboolean first; GString *fmtp; GstCaps *caps; stream = gst_rtsp_media_get_stream (media, i); caps = gst_rtsp_stream_get_caps (stream); if (caps == NULL) { g_warning ("ignoring stream %d without media type", i); continue; } s = gst_caps_get_structure (caps, 0); if (s == NULL) { gst_caps_unref (caps); g_warning ("ignoring stream %d without media type", i); continue; } gst_sdp_media_new (&smedia); /* get media type and payload for the m= line */ caps_str = gst_structure_get_string (s, "media"); gst_sdp_media_set_media (smedia, caps_str); gst_structure_get_int (s, "payload", &caps_pt); tmp = g_strdup_printf ("%d", caps_pt); gst_sdp_media_add_format (smedia, tmp); g_free (tmp); gst_sdp_media_set_port_info (smedia, 0, 1); gst_sdp_media_set_proto (smedia, "RTP/AVP"); /* for the c= line */ if (info->is_ipv6) { gst_sdp_media_add_connection (smedia, "IN", "IP6", "::", 16, 0); } else { gst_sdp_media_add_connection (smedia, "IN", "IP4", "0.0.0.0", 16, 0); } /* get clock-rate, media type and params for the rtpmap attribute */ gst_structure_get_int (s, "clock-rate", &caps_rate); caps_enc = gst_structure_get_string (s, "encoding-name"); caps_params = gst_structure_get_string (s, "encoding-params"); if (caps_enc) { if (caps_params) tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate, caps_params); else tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate); gst_sdp_media_add_attribute (smedia, "rtpmap", tmp); g_free (tmp); } /* the config uri */ tmp = gst_rtsp_stream_get_control (stream); gst_sdp_media_add_attribute (smedia, "control", tmp); g_free (tmp); /* collect all other properties and add them to fmtp or attributes */ fmtp = g_string_new (""); g_string_append_printf (fmtp, "%d ", caps_pt); first = TRUE; n_fields = gst_structure_n_fields (s); for (j = 0; j < n_fields; j++) { const gchar *fname, *fval; fname = gst_structure_nth_field_name (s, j); /* filter out standard properties */ if (!strcmp (fname, "media")) continue; if (!strcmp (fname, "payload")) continue; if (!strcmp (fname, "clock-rate")) continue; if (!strcmp (fname, "encoding-name")) continue; if (!strcmp (fname, "encoding-params")) continue; if (!strcmp (fname, "ssrc")) continue; if (!strcmp (fname, "clock-base")) continue; if (!strcmp (fname, "seqnum-base")) continue; if (g_str_has_prefix (fname, "a-")) { /* attribute */ if ((fval = gst_structure_get_string (s, fname))) gst_sdp_media_add_attribute (smedia, fname + 2, fval); continue; } if (g_str_has_prefix (fname, "x-")) { /* attribute */ if ((fval = gst_structure_get_string (s, fname))) gst_sdp_media_add_attribute (smedia, fname, fval); continue; } if ((fval = gst_structure_get_string (s, fname))) { g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval); first = FALSE; } } if (!first) { tmp = g_string_free (fmtp, FALSE); gst_sdp_media_add_attribute (smedia, "fmtp", tmp); g_free (tmp); } else { g_string_free (fmtp, TRUE); } update_sdp_from_tags (stream, smedia); gst_sdp_message_add_media (sdp, smedia); gst_sdp_media_free (smedia); gst_caps_unref (caps); } { GstNetTimeProvider *provider; if ((provider = gst_rtsp_media_get_time_provider (media, info->server_ip, 0))) { GstClock *clock; gchar *address, *str; gint port; g_object_get (provider, "clock", &clock, "address", &address, "port", &port, NULL); str = g_strdup_printf ("GstNetTimeProvider %s %s:%d %" G_GUINT64_FORMAT, g_type_name (G_TYPE_FROM_INSTANCE (clock)), address, port, gst_clock_get_time (clock)); gst_sdp_message_add_attribute (sdp, "x-gst-clock", str); g_free (str); gst_object_unref (clock); g_free (address); gst_object_unref (provider); } } return TRUE; /* ERRORS */ not_prepared: { GST_ERROR ("media %p is not prepared", media); return FALSE; } }