mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	media-session: improve cleanup
This commit is contained in:
		
							parent
							
								
									2a4c57798d
								
							
						
					
					
						commit
						147f488514
					
				
					 11 changed files with 301 additions and 162 deletions
				
			
		| 
						 | 
					@ -404,7 +404,7 @@ static void proxy_destroy(void *data)
 | 
				
			||||||
	pw_properties_free(endpoint->props);
 | 
						pw_properties_free(endpoint->props);
 | 
				
			||||||
	spa_list_remove(&endpoint->link);
 | 
						spa_list_remove(&endpoint->link);
 | 
				
			||||||
	spa_hook_remove(&endpoint->proxy_listener);
 | 
						spa_hook_remove(&endpoint->proxy_listener);
 | 
				
			||||||
	spa_hook_remove(&endpoint->listener);
 | 
						spa_hook_remove(&endpoint->client_endpoint_listener);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void proxy_bound(void *data, uint32_t id)
 | 
					static void proxy_bound(void *data, uint32_t id)
 | 
				
			||||||
| 
						 | 
					@ -693,10 +693,11 @@ handle_device(struct impl *impl, struct sm_object *obj)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_device(struct device *device)
 | 
					static void destroy_device(struct impl *impl, struct device *device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	deactivate_device(device);
 | 
						deactivate_device(device);
 | 
				
			||||||
	spa_hook_remove(&device->listener);
 | 
						spa_hook_remove(&device->listener);
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)device->device, SESSION_KEY);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_create(void *data, struct sm_object *object)
 | 
					static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
| 
						 | 
					@ -721,12 +722,14 @@ static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_remove(void *data, struct sm_object *object)
 | 
					static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (object->type) {
 | 
						switch (object->type) {
 | 
				
			||||||
	case PW_TYPE_INTERFACE_Device:
 | 
						case PW_TYPE_INTERFACE_Device:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct device *device;
 | 
							struct device *device;
 | 
				
			||||||
		if ((device = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
							if ((device = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
			destroy_device(device);
 | 
								destroy_device(impl, device);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -734,28 +737,29 @@ static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sm_media_session_events session_events = {
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
	SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
	.create = session_create,
 | 
						.create = session_create,
 | 
				
			||||||
	.remove = session_remove,
 | 
						.remove = session_remove,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_alsa_endpoint_start(struct sm_media_session *session)
 | 
					int sm_alsa_endpoint_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
	sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
						sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return impl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_alsa_endpoint_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,26 +39,44 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct impl {
 | 
					struct impl {
 | 
				
			||||||
	struct sm_media_session *session;
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct pw_properties *props;
 | 
						struct pw_properties *props;
 | 
				
			||||||
	struct pw_proxy *proxy;
 | 
						struct pw_proxy *proxy;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void * sm_alsa_midi_start(struct sm_media_session *session)
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						pw_proxy_destroy(impl->proxy);
 | 
				
			||||||
 | 
						pw_properties_free(impl->props);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_alsa_midi_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
	impl->props = pw_properties_new(
 | 
						impl->props = pw_properties_new(
 | 
				
			||||||
			SPA_KEY_FACTORY_NAME, SPA_NAME_API_ALSA_SEQ_BRIDGE,
 | 
								SPA_KEY_FACTORY_NAME, SPA_NAME_API_ALSA_SEQ_BRIDGE,
 | 
				
			||||||
			SPA_KEY_NODE_NAME, "Midi-Bridge",
 | 
								SPA_KEY_NODE_NAME, "Midi-Bridge",
 | 
				
			||||||
			NULL);
 | 
								NULL);
 | 
				
			||||||
	if (impl->props == NULL)
 | 
						if (impl->props == NULL) {
 | 
				
			||||||
 | 
							res = -errno;
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->proxy = sm_media_session_create_object(session,
 | 
						impl->proxy = sm_media_session_create_object(session,
 | 
				
			||||||
				"spa-node-factory",
 | 
									"spa-node-factory",
 | 
				
			||||||
| 
						 | 
					@ -67,23 +85,17 @@ void * sm_alsa_midi_start(struct sm_media_session *session)
 | 
				
			||||||
				&impl->props->dict,
 | 
									&impl->props->dict,
 | 
				
			||||||
                                0);
 | 
					                                0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (impl->proxy == NULL)
 | 
						if (impl->proxy == NULL) {
 | 
				
			||||||
 | 
							res = -errno;
 | 
				
			||||||
		goto cleanup_props;
 | 
							goto cleanup_props;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cleanup_props:
 | 
					cleanup_props:
 | 
				
			||||||
	pw_properties_free(impl->props);
 | 
						pw_properties_free(impl->props);
 | 
				
			||||||
cleanup:
 | 
					cleanup:
 | 
				
			||||||
	free(impl);
 | 
						free(impl);
 | 
				
			||||||
	return NULL;
 | 
						return res;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_alsa_midi_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	pw_proxy_destroy(impl->proxy);
 | 
					 | 
				
			||||||
	pw_properties_free(impl->props);
 | 
					 | 
				
			||||||
	free(impl);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,6 +96,7 @@ struct device {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct impl {
 | 
					struct impl {
 | 
				
			||||||
	struct sm_media_session *session;
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook session_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DBusConnection *conn;
 | 
						DBusConnection *conn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -255,6 +256,7 @@ static void alsa_remove_node(struct device *device, struct node *node)
 | 
				
			||||||
	pw_log_debug("remove node %u", node->id);
 | 
						pw_log_debug("remove node %u", node->id);
 | 
				
			||||||
	spa_list_remove(&node->link);
 | 
						spa_list_remove(&node->link);
 | 
				
			||||||
	sm_object_destroy(&node->snode->obj);
 | 
						sm_object_destroy(&node->snode->obj);
 | 
				
			||||||
 | 
						pw_properties_free(node->props);
 | 
				
			||||||
	free(node);
 | 
						free(node);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -484,8 +486,16 @@ static void sync_complete_done(void *data, int seq)
 | 
				
			||||||
	add_jack_timeout(impl);
 | 
						add_jack_timeout(impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void sync_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct device *device = data;
 | 
				
			||||||
 | 
						if (device->seq != 0)
 | 
				
			||||||
 | 
							sync_complete_done(data, device->seq);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct pw_proxy_events sync_complete_release = {
 | 
					static const struct pw_proxy_events sync_complete_release = {
 | 
				
			||||||
	PW_VERSION_PROXY_EVENTS,
 | 
						PW_VERSION_PROXY_EVENTS,
 | 
				
			||||||
 | 
						.destroy = sync_destroy,
 | 
				
			||||||
	.done = sync_complete_done
 | 
						.done = sync_complete_done
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -656,6 +666,7 @@ static void alsa_remove_device(struct impl *impl, struct device *device)
 | 
				
			||||||
		sm_object_destroy(&device->sdevice->obj);
 | 
							sm_object_destroy(&device->sdevice->obj);
 | 
				
			||||||
	spa_hook_remove(&device->listener);
 | 
						spa_hook_remove(&device->listener);
 | 
				
			||||||
	pw_unload_spa_handle(device->handle);
 | 
						pw_unload_spa_handle(device->handle);
 | 
				
			||||||
 | 
						pw_properties_free(device->props);
 | 
				
			||||||
	free(device);
 | 
						free(device);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -710,7 +721,22 @@ static int alsa_start_jack_device(struct impl *impl)
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_alsa_monitor_start(struct sm_media_session *session)
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->session_listener);
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						pw_proxy_destroy(impl->jack_device);
 | 
				
			||||||
 | 
						pw_unload_spa_handle(impl->handle);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_alsa_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_context *context = session->context;
 | 
						struct pw_context *context = session->context;
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
| 
						 | 
					@ -719,7 +745,7 @@ void *sm_alsa_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -747,20 +773,13 @@ void *sm_alsa_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
	if ((res = alsa_start_jack_device(impl)) < 0)
 | 
						if ((res = alsa_start_jack_device(impl)) < 0)
 | 
				
			||||||
		goto out_unload;
 | 
							goto out_unload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
						sm_media_session_add_listener(session, &impl->session_listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_unload:
 | 
					out_unload:
 | 
				
			||||||
	pw_unload_spa_handle(impl->handle);
 | 
						pw_unload_spa_handle(impl->handle);
 | 
				
			||||||
out_free:
 | 
					out_free:
 | 
				
			||||||
	free(impl);
 | 
						free(impl);
 | 
				
			||||||
	errno = -res;
 | 
						return res;
 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_alsa_monitor_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	pw_unload_spa_handle(impl->handle);
 | 
					 | 
				
			||||||
	free(impl);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@
 | 
				
			||||||
#include <spa/monitor/device.h>
 | 
					#include <spa/monitor/device.h>
 | 
				
			||||||
#include <spa/node/node.h>
 | 
					#include <spa/node/node.h>
 | 
				
			||||||
#include <spa/utils/hook.h>
 | 
					#include <spa/utils/hook.h>
 | 
				
			||||||
 | 
					#include <spa/utils/result.h>
 | 
				
			||||||
#include <spa/utils/names.h>
 | 
					#include <spa/utils/names.h>
 | 
				
			||||||
#include <spa/param/audio/format-utils.h>
 | 
					#include <spa/param/audio/format-utils.h>
 | 
				
			||||||
#include <spa/param/props.h>
 | 
					#include <spa/param/props.h>
 | 
				
			||||||
| 
						 | 
					@ -72,6 +73,7 @@ struct bluez5_object {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct impl {
 | 
					struct impl {
 | 
				
			||||||
	struct sm_media_session *session;
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook session_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_handle *handle;
 | 
						struct spa_handle *handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -294,6 +296,7 @@ static struct bluez5_object *bluez5_create_object(struct impl *impl, uint32_t id
 | 
				
			||||||
	return obj;
 | 
						return obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean_object:
 | 
					clean_object:
 | 
				
			||||||
 | 
						pw_properties_free(obj->props);
 | 
				
			||||||
	free(obj);
 | 
						free(obj);
 | 
				
			||||||
unload_handle:
 | 
					unload_handle:
 | 
				
			||||||
	pw_unload_spa_handle(handle);
 | 
						pw_unload_spa_handle(handle);
 | 
				
			||||||
| 
						 | 
					@ -315,6 +318,7 @@ static void bluez5_remove_object(struct impl *impl, struct bluez5_object *obj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_proxy_destroy(obj->proxy);
 | 
						pw_proxy_destroy(obj->proxy);
 | 
				
			||||||
	pw_unload_spa_handle(obj->handle);
 | 
						pw_unload_spa_handle(obj->handle);
 | 
				
			||||||
 | 
						pw_properties_free(obj->props);
 | 
				
			||||||
	free(obj);
 | 
						free(obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -344,7 +348,21 @@ static const struct spa_device_events bluez5_enum_callbacks =
 | 
				
			||||||
	.object_info = bluez5_enum_object_info,
 | 
						.object_info = bluez5_enum_object_info,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_bluez5_monitor_start(struct sm_media_session *session)
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->session_listener);
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						pw_unload_spa_handle(impl->handle);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_bluez5_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_handle *handle;
 | 
						struct spa_handle *handle;
 | 
				
			||||||
	struct pw_context *context = session->context;
 | 
						struct pw_context *context = session->context;
 | 
				
			||||||
| 
						 | 
					@ -355,11 +373,12 @@ void *sm_bluez5_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
	handle = pw_context_load_spa_handle(context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, NULL);
 | 
						handle = pw_context_load_spa_handle(context, SPA_NAME_API_BLUEZ5_ENUM_DBUS, NULL);
 | 
				
			||||||
	if (handle == NULL) {
 | 
						if (handle == NULL) {
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
 | 
							pw_log_error("can't load %s: %m", SPA_NAME_API_BLUEZ5_ENUM_DBUS);
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0) {
 | 
						if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0) {
 | 
				
			||||||
		pw_log_error("can't get Device interface: %d", res);
 | 
							pw_log_error("can't get Device interface: %s", spa_strerror(res));
 | 
				
			||||||
		goto out_unload;
 | 
							goto out_unload;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -377,19 +396,13 @@ void *sm_bluez5_monitor_start(struct sm_media_session *session)
 | 
				
			||||||
	spa_device_add_listener(impl->monitor, &impl->listener,
 | 
						spa_device_add_listener(impl->monitor, &impl->listener,
 | 
				
			||||||
			&bluez5_enum_callbacks, impl);
 | 
								&bluez5_enum_callbacks, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
						sm_media_session_add_listener(session, &impl->session_listener,
 | 
				
			||||||
 | 
								&session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      out_unload:
 | 
					 | 
				
			||||||
	pw_unload_spa_handle(handle);
 | 
					 | 
				
			||||||
      out:
 | 
					 | 
				
			||||||
	errno = -res;
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_bluez5_monitor_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	pw_unload_spa_handle(impl->handle);
 | 
					 | 
				
			||||||
	free(impl);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out_unload:
 | 
				
			||||||
 | 
						pw_unload_spa_handle(handle);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,20 +53,21 @@
 | 
				
			||||||
#define sm_object_emit_update(s)		sm_object_emit(s, update, 0)
 | 
					#define sm_object_emit_update(s)		sm_object_emit(s, update, 0)
 | 
				
			||||||
#define sm_object_emit_destroy(s)		sm_object_emit(s, destroy, 0)
 | 
					#define sm_object_emit_destroy(s)		sm_object_emit(s, destroy, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define sm_media_session_emit(s,m,v,...) spa_hook_list_call(&s->hooks, struct sm_media_session_events, m, v, ##__VA_ARGS__)
 | 
					#define sm_media_session_emit(s,m,v,...) spa_hook_list_call(&(s)->hooks, struct sm_media_session_events, m, v, ##__VA_ARGS__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define sm_media_session_emit_create(s,obj)		sm_media_session_emit(s, create, 0, obj)
 | 
					#define sm_media_session_emit_create(s,obj)		sm_media_session_emit(s, create, 0, obj)
 | 
				
			||||||
#define sm_media_session_emit_remove(s,obj)		sm_media_session_emit(s, remove, 0, obj)
 | 
					#define sm_media_session_emit_remove(s,obj)		sm_media_session_emit(s, remove, 0, obj)
 | 
				
			||||||
#define sm_media_session_emit_rescan(s,seq)		sm_media_session_emit(s, rescan, 0, seq)
 | 
					#define sm_media_session_emit_rescan(s,seq)		sm_media_session_emit(s, rescan, 0, seq)
 | 
				
			||||||
 | 
					#define sm_media_session_emit_destroy(s)		sm_media_session_emit(s, destroy, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void * sm_stream_endpoint_start(struct sm_media_session *sess);
 | 
					int sm_stream_endpoint_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_metadata_start(struct sm_media_session *sess);
 | 
					int sm_metadata_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_alsa_midi_start(struct sm_media_session *sess);
 | 
					int sm_alsa_midi_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_v4l2_monitor_start(struct sm_media_session *sess);
 | 
					int sm_v4l2_monitor_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_v4l2_endpoint_start(struct sm_media_session *sess);
 | 
					int sm_v4l2_endpoint_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_bluez5_monitor_start(struct sm_media_session *sess);
 | 
					int sm_bluez5_monitor_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_alsa_monitor_start(struct sm_media_session *sess);
 | 
					int sm_alsa_monitor_start(struct sm_media_session *sess);
 | 
				
			||||||
void * sm_alsa_endpoint_start(struct sm_media_session *sess);
 | 
					int sm_alsa_endpoint_start(struct sm_media_session *sess);
 | 
				
			||||||
int sm_policy_ep_start(struct sm_media_session *sess);
 | 
					int sm_policy_ep_start(struct sm_media_session *sess);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** user data to add to an object */
 | 
					/** user data to add to an object */
 | 
				
			||||||
| 
						 | 
					@ -154,19 +155,25 @@ struct object_info {
 | 
				
			||||||
	void (*destroy) (void *object);
 | 
						void (*destroy) (void *object);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void add_object(struct impl *impl, struct sm_object *obj)
 | 
					static void add_object(struct impl *impl, struct sm_object *obj, uint32_t id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t size = pw_map_get_size(&impl->globals);
 | 
						size_t size = pw_map_get_size(&impl->globals);
 | 
				
			||||||
 | 
						obj->id = id;
 | 
				
			||||||
 | 
						pw_log_debug("add %u %p", obj->id, obj);
 | 
				
			||||||
	while (obj->id > size)
 | 
						while (obj->id > size)
 | 
				
			||||||
		pw_map_insert_at(&impl->globals, size++, NULL);
 | 
							pw_map_insert_at(&impl->globals, size++, NULL);
 | 
				
			||||||
	pw_map_insert_at(&impl->globals, obj->id, obj);
 | 
						pw_map_insert_at(&impl->globals, obj->id, obj);
 | 
				
			||||||
	spa_list_append(&impl->global_list, &obj->link);
 | 
						spa_list_append(&impl->global_list, &obj->link);
 | 
				
			||||||
 | 
						sm_media_session_emit_create(impl, obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void remove_object(struct impl *impl, struct sm_object *obj)
 | 
					static void remove_object(struct impl *impl, struct sm_object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						pw_log_debug("remove %u %p", obj->id, obj);
 | 
				
			||||||
	pw_map_insert_at(&impl->globals, obj->id, NULL);
 | 
						pw_map_insert_at(&impl->globals, obj->id, NULL);
 | 
				
			||||||
	spa_list_remove(&obj->link);
 | 
						spa_list_remove(&obj->link);
 | 
				
			||||||
 | 
						sm_media_session_emit_remove(impl, obj);
 | 
				
			||||||
 | 
						obj->id = SPA_ID_INVALID;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void *find_object(struct impl *impl, uint32_t id)
 | 
					static void *find_object(struct impl *impl, uint32_t id)
 | 
				
			||||||
| 
						 | 
					@ -637,15 +644,18 @@ static void session_destroy(void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sm_session *sess = object;
 | 
						struct sm_session *sess = object;
 | 
				
			||||||
	struct sm_endpoint *endpoint;
 | 
						struct sm_endpoint *endpoint;
 | 
				
			||||||
 | 
						struct pw_session_info *i = sess->info;
 | 
				
			||||||
	if (sess->info) {
 | 
					 | 
				
			||||||
		free(sess->info);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_consume(endpoint, &sess->endpoint_list, link) {
 | 
						spa_list_consume(endpoint, &sess->endpoint_list, link) {
 | 
				
			||||||
		endpoint->session = NULL;
 | 
							endpoint->session = NULL;
 | 
				
			||||||
		spa_list_remove(&endpoint->link);
 | 
							spa_list_remove(&endpoint->link);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (i) {
 | 
				
			||||||
 | 
							if (i->props)
 | 
				
			||||||
 | 
								pw_properties_free ((struct pw_properties *)i->props);
 | 
				
			||||||
 | 
							free(i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct object_info session_info = {
 | 
					static const struct object_info session_info = {
 | 
				
			||||||
| 
						 | 
					@ -725,12 +735,7 @@ static void endpoint_destroy(void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sm_endpoint *endpoint = object;
 | 
						struct sm_endpoint *endpoint = object;
 | 
				
			||||||
	struct sm_endpoint_stream *stream;
 | 
						struct sm_endpoint_stream *stream;
 | 
				
			||||||
 | 
						struct pw_endpoint_info *i = endpoint->info;
 | 
				
			||||||
	if (endpoint->info) {
 | 
					 | 
				
			||||||
		free(endpoint->info->name);
 | 
					 | 
				
			||||||
		free(endpoint->info->media_class);
 | 
					 | 
				
			||||||
		free(endpoint->info);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_consume(stream, &endpoint->stream_list, link) {
 | 
						spa_list_consume(stream, &endpoint->stream_list, link) {
 | 
				
			||||||
		stream->endpoint = NULL;
 | 
							stream->endpoint = NULL;
 | 
				
			||||||
| 
						 | 
					@ -740,6 +745,13 @@ static void endpoint_destroy(void *object)
 | 
				
			||||||
		endpoint->session = NULL;
 | 
							endpoint->session = NULL;
 | 
				
			||||||
		spa_list_remove(&endpoint->link);
 | 
							spa_list_remove(&endpoint->link);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (i) {
 | 
				
			||||||
 | 
							if (i->props)
 | 
				
			||||||
 | 
								pw_properties_free ((struct pw_properties *)i->props);
 | 
				
			||||||
 | 
							free(i->name);
 | 
				
			||||||
 | 
							free(i->media_class);
 | 
				
			||||||
 | 
							free(i);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct object_info endpoint_info = {
 | 
					static const struct object_info endpoint_info = {
 | 
				
			||||||
| 
						 | 
					@ -892,15 +904,27 @@ destroy_proxy(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sm_object *obj = data;
 | 
						struct sm_object *obj = data;
 | 
				
			||||||
	struct impl *impl = SPA_CONTAINER_OF(obj->session, struct impl, this);
 | 
						struct impl *impl = SPA_CONTAINER_OF(obj->session, struct impl, this);
 | 
				
			||||||
 | 
						struct data *d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sm_media_session_emit_remove(impl, obj);
 | 
						pw_log_debug("object %p: proxy:%p id:%d", obj, obj->proxy, obj->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_hook_remove(&obj->proxy_listener);
 | 
				
			||||||
 | 
						if (SPA_FLAG_IS_SET(obj->mask, SM_OBJECT_CHANGE_MASK_LISTENER))
 | 
				
			||||||
 | 
							spa_hook_remove(&obj->object_listener);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (obj->id != SPA_ID_INVALID)
 | 
				
			||||||
		remove_object(impl, obj);
 | 
							remove_object(impl, obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sm_object_emit_destroy(obj);
 | 
						sm_object_emit_destroy(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (obj->destroy)
 | 
						if (obj->destroy)
 | 
				
			||||||
		obj->destroy(obj);
 | 
							obj->destroy(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_properties_free(obj->props);
 | 
				
			||||||
 | 
						spa_list_consume(d, &obj->data, link) {
 | 
				
			||||||
 | 
							spa_list_remove(&d->link);
 | 
				
			||||||
 | 
							free(d);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void done_proxy(void *data, int seq)
 | 
					static void done_proxy(void *data, int seq)
 | 
				
			||||||
| 
						 | 
					@ -923,14 +947,10 @@ static void bound_proxy(void *data, uint32_t id)
 | 
				
			||||||
	struct sm_object *obj = data;
 | 
						struct sm_object *obj = data;
 | 
				
			||||||
	struct impl *impl = SPA_CONTAINER_OF(obj->session, struct impl, this);
 | 
						struct impl *impl = SPA_CONTAINER_OF(obj->session, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("bound %p proxy %p id:%d", obj, obj->proxy, id);
 | 
						pw_log_debug("bound %p proxy %p id:%d->%d", obj, obj->proxy, obj->id, id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (obj->id == SPA_ID_INVALID) {
 | 
						if (obj->id == SPA_ID_INVALID)
 | 
				
			||||||
		obj->id = id;
 | 
							add_object(impl, obj, id);
 | 
				
			||||||
		pw_log_debug("bound %p proxy %p id:%d", obj, obj->proxy, id);
 | 
					 | 
				
			||||||
		add_object(impl, obj);
 | 
					 | 
				
			||||||
		sm_media_session_emit_create(impl, obj);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct pw_proxy_events proxy_events = {
 | 
					static const struct pw_proxy_events proxy_events = {
 | 
				
			||||||
| 
						 | 
					@ -1011,10 +1031,9 @@ static struct sm_object *init_object(struct impl *impl, const struct object_info
 | 
				
			||||||
	if (info->init)
 | 
						if (info->init)
 | 
				
			||||||
		info->init(obj);
 | 
							info->init(obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (id != SPA_ID_INVALID) {
 | 
						if (id != SPA_ID_INVALID)
 | 
				
			||||||
		add_object(impl, obj);
 | 
							add_object(impl, obj, id);
 | 
				
			||||||
		sm_media_session_emit_create(impl, obj);
 | 
					
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return obj;
 | 
						return obj;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1082,6 +1101,7 @@ update_object(struct impl *impl, const struct object_info *info,
 | 
				
			||||||
	pw_log_debug(NAME" %p: update type:%d -> type:%d", impl, obj->type, type);
 | 
						pw_log_debug(NAME" %p: update type:%d -> type:%d", impl, obj->type, type);
 | 
				
			||||||
	obj->handle = obj->proxy;
 | 
						obj->handle = obj->proxy;
 | 
				
			||||||
	spa_hook_remove(&obj->proxy_listener);
 | 
						spa_hook_remove(&obj->proxy_listener);
 | 
				
			||||||
 | 
						pw_proxy_add_listener(obj->handle, &obj->handle_listener, &proxy_events, obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (SPA_FLAG_IS_SET(obj->mask, SM_OBJECT_CHANGE_MASK_LISTENER))
 | 
						if (SPA_FLAG_IS_SET(obj->mask, SM_OBJECT_CHANGE_MASK_LISTENER))
 | 
				
			||||||
		spa_hook_remove(&obj->object_listener);
 | 
							spa_hook_remove(&obj->object_listener);
 | 
				
			||||||
| 
						 | 
					@ -1641,13 +1661,15 @@ static int start_policy(struct impl *impl)
 | 
				
			||||||
	pw_proxy_add_listener((struct pw_proxy*)impl->policy_core,
 | 
						pw_proxy_add_listener((struct pw_proxy*)impl->policy_core,
 | 
				
			||||||
			&impl->proxy_policy_listener,
 | 
								&impl->proxy_policy_listener,
 | 
				
			||||||
			&proxy_core_events, impl);
 | 
								&proxy_core_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->registry = pw_core_get_registry(impl->policy_core,
 | 
						impl->registry = pw_core_get_registry(impl->policy_core,
 | 
				
			||||||
			PW_VERSION_REGISTRY, 0);
 | 
								PW_VERSION_REGISTRY, 0);
 | 
				
			||||||
	pw_registry_add_listener(impl->registry,
 | 
						pw_registry_add_listener(impl->registry,
 | 
				
			||||||
			&impl->registry_listener,
 | 
								&impl->registry_listener,
 | 
				
			||||||
			®istry_events, impl);
 | 
								®istry_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return sm_policy_ep_start(&impl->this);
 | 
						sm_policy_ep_start(&impl->this);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[])
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
| 
						 | 
					@ -1655,6 +1677,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	struct impl impl = { 0, };
 | 
						struct impl impl = { 0, };
 | 
				
			||||||
	const struct spa_support *support;
 | 
						const struct spa_support *support;
 | 
				
			||||||
	uint32_t n_support;
 | 
						uint32_t n_support;
 | 
				
			||||||
 | 
						int res = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_init(&argc, &argv);
 | 
						pw_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1685,15 +1708,20 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		pw_log_debug("got dbus connection %p", impl.this.dbus_connection);
 | 
							pw_log_debug("got dbus connection %p", impl.this.dbus_connection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (start_session(&impl) < 0)
 | 
						if ((res = start_session(&impl)) < 0)
 | 
				
			||||||
		return -1;
 | 
							goto exit;
 | 
				
			||||||
	if (start_policy(&impl) < 0)
 | 
						if ((res = start_policy(&impl)) < 0)
 | 
				
			||||||
		return -1;
 | 
							goto exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_main_loop_run(impl.loop);
 | 
						pw_main_loop_run(impl.loop);
 | 
				
			||||||
 | 
					exit:
 | 
				
			||||||
 | 
						sm_media_session_emit_destroy(&impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_context_destroy(impl.this.context);
 | 
						pw_context_destroy(impl.this.context);
 | 
				
			||||||
	pw_main_loop_destroy(impl.loop);
 | 
						pw_main_loop_destroy(impl.loop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						pw_map_clear(&impl.endpoint_links);
 | 
				
			||||||
 | 
						pw_map_clear(&impl.globals);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,7 @@ struct sm_object {
 | 
				
			||||||
	int pending;
 | 
						int pending;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct pw_proxy *handle;
 | 
						struct pw_proxy *handle;
 | 
				
			||||||
 | 
						struct spa_hook handle_listener;
 | 
				
			||||||
	struct spa_hook_list hooks;
 | 
						struct spa_hook_list hooks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_list data;
 | 
						struct spa_list data;
 | 
				
			||||||
| 
						 | 
					@ -200,6 +201,7 @@ struct sm_media_session_events {
 | 
				
			||||||
	void (*remove) (void *data, struct sm_object *object);
 | 
						void (*remove) (void *data, struct sm_object *object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void (*rescan) (void *data, int seq);
 | 
						void (*rescan) (void *data, int seq);
 | 
				
			||||||
 | 
						void (*destroy) (void *data);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct sm_media_session {
 | 
					struct sm_media_session {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,8 @@ struct metadata {
 | 
				
			||||||
	struct spa_interface iface;
 | 
						struct spa_interface iface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct sm_media_session *session;
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook session_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_hook_list hooks;
 | 
						struct spa_hook_list hooks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct pw_properties *properties;
 | 
						struct pw_properties *properties;
 | 
				
			||||||
| 
						 | 
					@ -180,11 +182,33 @@ struct pw_metadata_methods impl_metadata = {
 | 
				
			||||||
	.clear = impl_clear,
 | 
						.clear = impl_clear,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_metadata_start(struct sm_media_session *sess)
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct metadata *this = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_hook_remove(&this->session_listener);
 | 
				
			||||||
 | 
						pw_proxy_destroy(this->proxy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clear_items(this);
 | 
				
			||||||
 | 
						pw_array_clear(&this->metadata);
 | 
				
			||||||
 | 
						pw_properties_free(this->properties);
 | 
				
			||||||
 | 
						free(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_metadata_start(struct sm_media_session *sess)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct metadata *md;
 | 
						struct metadata *md;
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md = calloc(1, sizeof(*md));
 | 
						md = calloc(1, sizeof(*md));
 | 
				
			||||||
 | 
						if (md == NULL)
 | 
				
			||||||
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md->session = sess;
 | 
						md->session = sess;
 | 
				
			||||||
	md->properties = pw_properties_new(NULL, NULL);
 | 
						md->properties = pw_properties_new(NULL, NULL);
 | 
				
			||||||
	pw_array_init(&md->metadata, 4096);
 | 
						pw_array_init(&md->metadata, 4096);
 | 
				
			||||||
| 
						 | 
					@ -200,18 +224,18 @@ void *sm_metadata_start(struct sm_media_session *sess)
 | 
				
			||||||
			NULL,
 | 
								NULL,
 | 
				
			||||||
			md,
 | 
								md,
 | 
				
			||||||
			0);
 | 
								0);
 | 
				
			||||||
	return md;
 | 
						if (md->proxy == NULL) {
 | 
				
			||||||
}
 | 
							res = -errno;
 | 
				
			||||||
 | 
							goto error_free;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int sm_metadata_stop(void *data)
 | 
						sm_media_session_add_listener(sess, &md->session_listener,
 | 
				
			||||||
{
 | 
								&session_events, md);
 | 
				
			||||||
	struct metadata *this = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pw_proxy_destroy(this->proxy);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	clear_items(this);
 | 
					 | 
				
			||||||
	pw_array_clear(&this->metadata);
 | 
					 | 
				
			||||||
	pw_properties_free(this->properties);
 | 
					 | 
				
			||||||
	free(this);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_free:
 | 
				
			||||||
 | 
						pw_array_clear(&md->metadata);
 | 
				
			||||||
 | 
						pw_properties_free(md->properties);
 | 
				
			||||||
 | 
						free(md);
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,6 +179,13 @@ handle_endpoint(struct impl *impl, struct sm_object *object)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destroy_endpoint(struct impl *impl, struct endpoint *ep)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						spa_list_remove(&ep->link);
 | 
				
			||||||
 | 
						free(ep->media);
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)ep->obj, SESSION_KEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
handle_stream(struct impl *impl, struct sm_object *object)
 | 
					handle_stream(struct impl *impl, struct sm_object *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -202,6 +209,11 @@ handle_stream(struct impl *impl, struct sm_object *object)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destroy_stream(struct impl *impl, struct stream *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)s->obj, SESSION_KEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_create(void *data, struct sm_object *object)
 | 
					static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = data;
 | 
						struct impl *impl = data;
 | 
				
			||||||
| 
						 | 
					@ -236,10 +248,15 @@ static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
	case PW_TYPE_INTERFACE_Endpoint:
 | 
						case PW_TYPE_INTERFACE_Endpoint:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct endpoint *ep;
 | 
							struct endpoint *ep;
 | 
				
			||||||
		if ((ep = sm_object_get_data(object, SESSION_KEY)) != NULL) {
 | 
							if ((ep = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
			spa_list_remove(&ep->link);
 | 
								destroy_endpoint(impl, ep);
 | 
				
			||||||
			free(ep->media);
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						case PW_TYPE_INTERFACE_EndpointStream:
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct stream *s;
 | 
				
			||||||
 | 
							if ((s = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
 | 
								destroy_stream(impl, s);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -490,20 +507,28 @@ static void session_rescan(void *data, int seq)
 | 
				
			||||||
		rescan_endpoint(impl, ep);
 | 
							rescan_endpoint(impl, ep);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sm_media_session_events session_events = {
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
	SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
	.create = session_create,
 | 
						.create = session_create,
 | 
				
			||||||
	.remove = session_remove,
 | 
						.remove = session_remove,
 | 
				
			||||||
	.rescan = session_rescan,
 | 
						.rescan = session_rescan,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_policy_ep_start(struct sm_media_session *session)
 | 
					int sm_policy_ep_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
	impl->context = session->context;
 | 
						impl->context = session->context;
 | 
				
			||||||
| 
						 | 
					@ -512,12 +537,5 @@ void *sm_policy_ep_start(struct sm_media_session *session)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sm_media_session_add_listener(impl->session, &impl->listener, &session_events, impl);
 | 
						sm_media_session_add_listener(impl->session, &impl->listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_policy_ep_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	free(impl);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -543,12 +543,13 @@ handle_node(struct impl *impl, struct sm_object *obj)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_node(struct node *node)
 | 
					static void destroy_node(struct impl *impl, struct node *node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (node->endpoint)
 | 
						if (node->endpoint)
 | 
				
			||||||
		destroy_endpoint(node->endpoint);
 | 
							destroy_endpoint(node->endpoint);
 | 
				
			||||||
	free(node->media);
 | 
						free(node->media);
 | 
				
			||||||
	spa_hook_remove(&node->listener);
 | 
						spa_hook_remove(&node->listener);
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)node->obj, SESSION_KEY);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_create(void *data, struct sm_object *object)
 | 
					static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
| 
						 | 
					@ -573,12 +574,14 @@ static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_remove(void *data, struct sm_object *object)
 | 
					static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (object->type) {
 | 
						switch (object->type) {
 | 
				
			||||||
	case PW_TYPE_INTERFACE_Node:
 | 
						case PW_TYPE_INTERFACE_Node:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct node *node;
 | 
							struct node *node;
 | 
				
			||||||
		if ((node = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
							if ((node = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
			destroy_node(node);
 | 
								destroy_node(impl, node);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -586,29 +589,30 @@ static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sm_media_session_events session_events = {
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
	SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
	.create = session_create,
 | 
						.create = session_create,
 | 
				
			||||||
	.remove = session_remove,
 | 
						.remove = session_remove,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void * sm_stream_endpoint_start(struct sm_media_session *session)
 | 
					int sm_stream_endpoint_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
	sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
						sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_stream_endpoint_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	spa_hook_remove(&impl->listener);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,7 +354,7 @@ static void proxy_destroy(void *data)
 | 
				
			||||||
	pw_properties_free(endpoint->props);
 | 
						pw_properties_free(endpoint->props);
 | 
				
			||||||
	spa_list_remove(&endpoint->link);
 | 
						spa_list_remove(&endpoint->link);
 | 
				
			||||||
	spa_hook_remove(&endpoint->proxy_listener);
 | 
						spa_hook_remove(&endpoint->proxy_listener);
 | 
				
			||||||
	spa_hook_remove(&endpoint->listener);
 | 
						spa_hook_remove(&endpoint->client_endpoint_listener);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void proxy_bound(void *data, uint32_t id)
 | 
					static void proxy_bound(void *data, uint32_t id)
 | 
				
			||||||
| 
						 | 
					@ -575,10 +575,11 @@ handle_device(struct impl *impl, struct sm_object *obj)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_device(struct device *device)
 | 
					static void destroy_device(struct impl *impl, struct device *device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	deactivate_device(device);
 | 
						deactivate_device(device);
 | 
				
			||||||
	spa_hook_remove(&device->listener);
 | 
						spa_hook_remove(&device->listener);
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)device->device, SESSION_KEY);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_create(void *data, struct sm_object *object)
 | 
					static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
| 
						 | 
					@ -603,12 +604,14 @@ static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void session_remove(void *data, struct sm_object *object)
 | 
					static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (object->type) {
 | 
						switch (object->type) {
 | 
				
			||||||
	case PW_TYPE_INTERFACE_Device:
 | 
						case PW_TYPE_INTERFACE_Device:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		struct device *device;
 | 
							struct device *device;
 | 
				
			||||||
		if ((device = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
							if ((device = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
			destroy_device(device);
 | 
								destroy_device(impl, device);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
| 
						 | 
					@ -616,28 +619,30 @@ static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct sm_media_session_events session_events = {
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
	SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
	.create = session_create,
 | 
						.create = session_create,
 | 
				
			||||||
	.remove = session_remove,
 | 
						.remove = session_remove,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *sm_v4l2_endpoint_start(struct sm_media_session *session)
 | 
					int sm_v4l2_endpoint_start(struct sm_media_session *session)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = session;
 | 
						impl->session = session;
 | 
				
			||||||
	sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
						sm_media_session_add_listener(session, &impl->listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_v4l2_endpoint_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,6 +80,7 @@ struct device {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct impl {
 | 
					struct impl {
 | 
				
			||||||
	struct sm_media_session *session;
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook session_listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_handle *handle;
 | 
						struct spa_handle *handle;
 | 
				
			||||||
	struct spa_device *monitor;
 | 
						struct spa_device *monitor;
 | 
				
			||||||
| 
						 | 
					@ -181,6 +182,7 @@ static void v4l2_remove_node(struct device *dev, struct node *node)
 | 
				
			||||||
	pw_log_debug("remove node %u", node->id);
 | 
						pw_log_debug("remove node %u", node->id);
 | 
				
			||||||
	spa_list_remove(&node->link);
 | 
						spa_list_remove(&node->link);
 | 
				
			||||||
	pw_proxy_destroy(node->proxy);
 | 
						pw_proxy_destroy(node->proxy);
 | 
				
			||||||
 | 
						pw_properties_free(node->props);
 | 
				
			||||||
	free(node);
 | 
						free(node);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,6 +407,7 @@ static void v4l2_remove_device(struct impl *impl, struct device *dev)
 | 
				
			||||||
		sm_object_destroy(&dev->sdevice->obj);
 | 
							sm_object_destroy(&dev->sdevice->obj);
 | 
				
			||||||
	spa_hook_remove(&dev->listener);
 | 
						spa_hook_remove(&dev->listener);
 | 
				
			||||||
	pw_unload_spa_handle(dev->handle);
 | 
						pw_unload_spa_handle(dev->handle);
 | 
				
			||||||
 | 
						pw_properties_free(dev->props);
 | 
				
			||||||
	free(dev);
 | 
						free(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -434,7 +437,21 @@ static const struct spa_device_events v4l2_udev_callbacks =
 | 
				
			||||||
	.object_info = v4l2_udev_object_info,
 | 
						.object_info = v4l2_udev_object_info,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void * sm_v4l2_monitor_start(struct sm_media_session *sess)
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->session_listener);
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						pw_unload_spa_handle(impl->handle);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_v4l2_monitor_start(struct sm_media_session *sess)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_context *context = sess->context;
 | 
						struct pw_context *context = sess->context;
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
| 
						 | 
					@ -443,7 +460,7 @@ void * sm_v4l2_monitor_start(struct sm_media_session *sess)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = calloc(1, sizeof(struct impl));
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (impl == NULL)
 | 
						if (impl == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl->session = sess;
 | 
						impl->session = sess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -464,20 +481,13 @@ void * sm_v4l2_monitor_start(struct sm_media_session *sess)
 | 
				
			||||||
	spa_device_add_listener(impl->monitor, &impl->listener,
 | 
						spa_device_add_listener(impl->monitor, &impl->listener,
 | 
				
			||||||
			&v4l2_udev_callbacks, impl);
 | 
								&v4l2_udev_callbacks, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return impl;
 | 
						sm_media_session_add_listener(sess, &impl->session_listener, &session_events, impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_unload:
 | 
					out_unload:
 | 
				
			||||||
	pw_unload_spa_handle(impl->handle);
 | 
						pw_unload_spa_handle(impl->handle);
 | 
				
			||||||
out_free:
 | 
					out_free:
 | 
				
			||||||
	free(impl);
 | 
						free(impl);
 | 
				
			||||||
	errno = -res;
 | 
						return res;
 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int sm_v4l2_monitor_stop(void *data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct impl *impl = data;
 | 
					 | 
				
			||||||
	pw_unload_spa_handle(impl->handle);
 | 
					 | 
				
			||||||
	free(impl);
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue