mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
metadata: add support for initial metadata
Add a metadata.values property that is used to fill the metadata store with initial values. Fixes #3076
This commit is contained in:
parent
ccd118368e
commit
f318edb699
4 changed files with 85 additions and 2 deletions
|
|
@ -152,7 +152,15 @@ context.objects = [
|
||||||
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
|
||||||
|
|
||||||
# Make a default metadata store
|
# Make a default metadata store
|
||||||
{ factory = metadata args = { metadata.name = default } }
|
{ factory = metadata
|
||||||
|
args = {
|
||||||
|
metadata.name = default
|
||||||
|
# metadata.values = [
|
||||||
|
# { key = default.audio.sink value = { name = somesink } }
|
||||||
|
# { key = default.audio.source value = { name = somesource } }
|
||||||
|
# ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# A default dummy driver. This handles nodes marked with the "node.always-driver"
|
# A default dummy driver. This handles nodes marked with the "node.always-driver"
|
||||||
# property when no other driver is currently active. JACK clients need this.
|
# property when no other driver is currently active. JACK clients need this.
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,17 @@ context.objects = [
|
||||||
# audio.position = "FL,FR"
|
# audio.position = "FL,FR"
|
||||||
# }
|
# }
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
# Use the metadata factory to create metadata and some default values.
|
||||||
|
#{ factory = metadata
|
||||||
|
# args = {
|
||||||
|
# metadata.name = my-metadata
|
||||||
|
# metadata.values = [
|
||||||
|
# { key = default.audio.sink value = { name = somesink } }
|
||||||
|
# { key = default.audio.source value = { name = somesource } }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
#}
|
||||||
]
|
]
|
||||||
|
|
||||||
context.exec = [
|
context.exec = [
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <spa/utils/result.h>
|
#include <spa/utils/result.h>
|
||||||
|
#include <spa/utils/json.h>
|
||||||
|
|
||||||
#include <pipewire/impl.h>
|
#include <pipewire/impl.h>
|
||||||
#include <pipewire/extensions/metadata.h>
|
#include <pipewire/extensions/metadata.h>
|
||||||
|
|
@ -19,6 +20,12 @@
|
||||||
|
|
||||||
#define NAME "metadata"
|
#define NAME "metadata"
|
||||||
|
|
||||||
|
#define FACTORY_USAGE "("PW_KEY_METADATA_NAME" = <name> ) " \
|
||||||
|
"("PW_KEY_METADATA_VALUES" = [ " \
|
||||||
|
" { ( id = <int> ) key = <string> ( type = <string> ) value = <json> } " \
|
||||||
|
" ..." \
|
||||||
|
" ] )"
|
||||||
|
|
||||||
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
|
||||||
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
#define PW_LOG_TOPIC_DEFAULT mod_topic
|
||||||
|
|
||||||
|
|
@ -47,6 +54,56 @@ struct factory_data {
|
||||||
struct pw_export_type export_metadata;
|
struct pw_export_type export_metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [
|
||||||
|
* { ( "id" = <int>, ) "key" = <string> ("type" = <string>) "value" = <json> }
|
||||||
|
* ....
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
static int fill_metadata(struct pw_metadata *metadata, const char *str)
|
||||||
|
{
|
||||||
|
struct spa_json it[3];
|
||||||
|
|
||||||
|
spa_json_init(&it[0], str, strlen(str));
|
||||||
|
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (spa_json_enter_object(&it[1], &it[2]) > 0) {
|
||||||
|
char key[256], *k = NULL, *v = NULL, *t = NULL;
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
while (spa_json_get_string(&it[2], key, sizeof(key)) > 0) {
|
||||||
|
int len;
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
if ((len = spa_json_next(&it[2], &val)) <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (spa_streq(key, "id")) {
|
||||||
|
if (spa_json_parse_int(val, len, &id) <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (spa_streq(key, "key")) {
|
||||||
|
if ((k = malloc(len+1)) != NULL)
|
||||||
|
spa_json_parse_stringn(val, len, k, len+1);
|
||||||
|
} else if (spa_streq(key, "type")) {
|
||||||
|
if ((t = malloc(len+1)) != NULL)
|
||||||
|
spa_json_parse_stringn(val, len, t, len+1);
|
||||||
|
} else if (spa_streq(key, "value")) {
|
||||||
|
if (spa_json_is_container(val, len))
|
||||||
|
len = spa_json_container_len(&it[2], val, len);
|
||||||
|
if ((v = malloc(len+1)) != NULL)
|
||||||
|
spa_json_parse_stringn(val, len, v, len+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k != NULL && v != NULL)
|
||||||
|
pw_metadata_set_property(metadata, id, k, t, v);
|
||||||
|
free(k);
|
||||||
|
free(v);
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *create_object(void *_data,
|
static void *create_object(void *_data,
|
||||||
struct pw_resource *resource,
|
struct pw_resource *resource,
|
||||||
const char *type,
|
const char *type,
|
||||||
|
|
@ -59,6 +116,7 @@ static void *create_object(void *_data,
|
||||||
struct pw_metadata *result;
|
struct pw_metadata *result;
|
||||||
struct pw_resource *metadata_resource = NULL;
|
struct pw_resource *metadata_resource = NULL;
|
||||||
struct pw_impl_client *client = resource ? pw_resource_get_client(resource) : NULL;
|
struct pw_impl_client *client = resource ? pw_resource_get_client(resource) : NULL;
|
||||||
|
const char *str;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (properties == NULL)
|
if (properties == NULL)
|
||||||
|
|
@ -102,6 +160,9 @@ static void *create_object(void *_data,
|
||||||
pw_impl_metadata_register(impl, NULL);
|
pw_impl_metadata_register(impl, NULL);
|
||||||
result = pw_impl_metadata_get_implementation(impl);
|
result = pw_impl_metadata_get_implementation(impl);
|
||||||
}
|
}
|
||||||
|
if ((str = pw_properties_get(properties, PW_KEY_METADATA_VALUES)) != NULL)
|
||||||
|
fill_metadata(result, str);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
error_resource:
|
error_resource:
|
||||||
|
|
@ -192,7 +253,9 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
"metadata",
|
"metadata",
|
||||||
PW_TYPE_INTERFACE_Metadata,
|
PW_TYPE_INTERFACE_Metadata,
|
||||||
PW_VERSION_METADATA,
|
PW_VERSION_METADATA,
|
||||||
NULL,
|
pw_properties_new(
|
||||||
|
PW_KEY_FACTORY_USAGE, FACTORY_USAGE,
|
||||||
|
NULL),
|
||||||
sizeof(*data));
|
sizeof(*data));
|
||||||
if (factory == NULL)
|
if (factory == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ struct pw_metadata_methods {
|
||||||
#define pw_metadata_clear(c) pw_metadata_method(c,clear,0)
|
#define pw_metadata_clear(c) pw_metadata_method(c,clear,0)
|
||||||
|
|
||||||
#define PW_KEY_METADATA_NAME "metadata.name"
|
#define PW_KEY_METADATA_NAME "metadata.name"
|
||||||
|
#define PW_KEY_METADATA_VALUES "metadata.values"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \}
|
* \}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue