static gboolean gst_udpsrc_stop (GstBaseSrc * bsrc) { GstUDPSrc *src; src = GST_UDPSRC (bsrc); GST_DEBUG ("stopping, closing sockets"); if (src->used_socket) { if (src->auto_multicast && g_inet_address_get_is_multicast (g_inet_socket_address_get_address (src->addr))) { GError *err = NULL; GST_DEBUG_OBJECT (src, "leaving multicast group %s", src->host); if (!g_socket_leave_multicast_group (src->used_socket, g_inet_socket_address_get_address (src->addr), FALSE, src->multi_iface, &err)) { GST_ERROR_OBJECT (src, "Failed to leave multicast group: %s", err->message); g_clear_error (&err); } } if (src->close_socket || !src->external_socket) { GError *err = NULL; if (!g_socket_close (src->used_socket, &err)) { GST_ERROR_OBJECT (src, "Failed to close socket: %s", err->message); g_clear_error (&err); } } g_object_unref (src->used_socket); src->used_socket = NULL; g_object_unref (src->addr); src->addr = NULL; } return TRUE; }
static gboolean gst_udpsrc_close (GstUDPSrc * src) { GST_DEBUG ("closing sockets"); if (src->used_socket) { if (src->auto_multicast && g_inet_address_get_is_multicast (g_inet_socket_address_get_address (src->addr))) { GError *err = NULL; GST_DEBUG_OBJECT (src, "leaving multicast group %s", src->address); if (!g_socket_leave_multicast_group (src->used_socket, g_inet_socket_address_get_address (src->addr), FALSE, src->multi_iface, &err)) { GST_ERROR_OBJECT (src, "Failed to leave multicast group: %s", err->message); g_clear_error (&err); } } if (src->close_socket || !src->external_socket) { GError *err = NULL; if (!g_socket_close (src->used_socket, &err)) { GST_ERROR_OBJECT (src, "Failed to close socket: %s", err->message); g_clear_error (&err); } } g_object_unref (src->used_socket); src->used_socket = NULL; g_object_unref (src->addr); src->addr = NULL; } gst_udpsrc_reset_memory_allocator (src); gst_udpsrc_free_cancellable (src); return TRUE; }
void gst_multiudpsink_remove (GstMultiUDPSink * sink, const gchar * host, gint port) { GList *find; GstUDPClient udpclient; GstUDPClient *client; GTimeVal now; udpclient.host = (gchar *) host; udpclient.port = port; g_mutex_lock (&sink->client_lock); find = g_list_find_custom (sink->clients, &udpclient, (GCompareFunc) client_compare); if (!find) goto not_found; client = (GstUDPClient *) find->data; GST_DEBUG_OBJECT (sink, "found %d clients with host %s, port %d", client->refcount, host, port); client->refcount--; if (client->refcount == 0) { GInetSocketAddress *saddr = G_INET_SOCKET_ADDRESS (client->addr); GInetAddress *addr = g_inet_socket_address_get_address (saddr); GSocketFamily family = g_socket_address_get_family (G_SOCKET_ADDRESS (saddr)); GSocket *socket; /* Select socket to send from for this address */ if (family == G_SOCKET_FAMILY_IPV6 || !sink->used_socket) socket = sink->used_socket_v6; else socket = sink->used_socket; GST_DEBUG_OBJECT (sink, "remove client with host %s, port %d", host, port); g_get_current_time (&now); client->disconnect_time = GST_TIMEVAL_TO_TIME (now); if (socket && sink->auto_multicast && g_inet_address_get_is_multicast (addr)) { GError *err = NULL; if (!g_socket_leave_multicast_group (socket, addr, FALSE, sink->multi_iface, &err)) { GST_DEBUG_OBJECT (sink, "Failed to leave multicast group: %s", err->message); g_clear_error (&err); } } /* Unlock to emit signal before we delete the actual client */ g_mutex_unlock (&sink->client_lock); g_signal_emit (G_OBJECT (sink), gst_multiudpsink_signals[SIGNAL_CLIENT_REMOVED], 0, host, port); g_mutex_lock (&sink->client_lock); sink->clients = g_list_delete_link (sink->clients, find); free_client (client); } g_mutex_unlock (&sink->client_lock); return; /* ERRORS */ not_found: { g_mutex_unlock (&sink->client_lock); GST_WARNING_OBJECT (sink, "client at host %s, port %d not found", host, port); return; } }