mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-20 06:50:03 +01:00
module-avb: milan: introducing full entity model for mlian v1.2
This commit is contained in:
parent
b22e442b10
commit
bb1ef8ea5e
4 changed files with 1303 additions and 252 deletions
|
|
@ -749,6 +749,7 @@ if build_module_avb
|
||||||
'module-avb/aecp-aem-cmds-resps/reply-unsol-helpers.c',
|
'module-avb/aecp-aem-cmds-resps/reply-unsol-helpers.c',
|
||||||
'module-avb/es-builder.c',
|
'module-avb/es-builder.c',
|
||||||
'module-avb/avdecc.c',
|
'module-avb/avdecc.c',
|
||||||
|
'module-avb/descriptors.c',
|
||||||
'module-avb/maap.c',
|
'module-avb/maap.c',
|
||||||
'module-avb/mmrp.c',
|
'module-avb/mmrp.c',
|
||||||
'module-avb/mrp.c',
|
'module-avb/mrp.c',
|
||||||
|
|
|
||||||
824
src/modules/module-avb/descriptors.c
Normal file
824
src/modules/module-avb/descriptors.c
Normal file
|
|
@ -0,0 +1,824 @@
|
||||||
|
/* PipeWire */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2022 Wim Taymans */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki (alexandre.malki@kebag-logic.com) */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Simon Gapp <simon.gapp@kebag-logic.com> */
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include "adp.h"
|
||||||
|
#include "aecp-aem.h"
|
||||||
|
#include "aecp-aem-types.h"
|
||||||
|
#include "aecp-aem-descriptors.h"
|
||||||
|
#include "aecp-aem-controls.h"
|
||||||
|
#include "es-builder.h"
|
||||||
|
|
||||||
|
#include "entity-model-milan-v12.h"
|
||||||
|
|
||||||
|
static void init_descriptor_legacy_avb(struct server *server)
|
||||||
|
{
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STRINGS, 0,
|
||||||
|
sizeof(struct avb_aem_desc_strings),
|
||||||
|
&(struct avb_aem_desc_strings)
|
||||||
|
{
|
||||||
|
.string_0 = "PipeWire",
|
||||||
|
.string_1 = "Configuration 1",
|
||||||
|
.string_2 = "Wim Taymans",
|
||||||
|
});
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_LOCALE, 0,
|
||||||
|
sizeof(struct avb_aem_desc_locale),
|
||||||
|
&(struct avb_aem_desc_locale)
|
||||||
|
{
|
||||||
|
.locale_identifier = "en-EN",
|
||||||
|
.number_of_strings = htons(1),
|
||||||
|
.base_strings = htons(0)
|
||||||
|
});
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_ENTITY, 0,
|
||||||
|
sizeof(struct avb_aem_desc_entity),
|
||||||
|
&(struct avb_aem_desc_entity)
|
||||||
|
{
|
||||||
|
.entity_id = htobe64(server->entity_id),
|
||||||
|
.entity_model_id = htobe64(0),
|
||||||
|
.entity_capabilities = htonl(
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED |
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED |
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED |
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID |
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID),
|
||||||
|
|
||||||
|
.talker_stream_sources = htons(8),
|
||||||
|
.talker_capabilities = htons(
|
||||||
|
AVB_ADP_TALKER_CAPABILITY_IMPLEMENTED |
|
||||||
|
AVB_ADP_TALKER_CAPABILITY_AUDIO_SOURCE),
|
||||||
|
.listener_stream_sinks = htons(8),
|
||||||
|
.listener_capabilities = htons(
|
||||||
|
AVB_ADP_LISTENER_CAPABILITY_IMPLEMENTED |
|
||||||
|
AVB_ADP_LISTENER_CAPABILITY_AUDIO_SINK),
|
||||||
|
.controller_capabilities = htons(0),
|
||||||
|
.available_index = htonl(0),
|
||||||
|
.association_id = htobe64(0),
|
||||||
|
.entity_name = "PipeWire",
|
||||||
|
.vendor_name_string = htons(2),
|
||||||
|
.model_name_string = htons(0),
|
||||||
|
.firmware_version = "0.3.48",
|
||||||
|
.group_name = "",
|
||||||
|
.serial_number = "",
|
||||||
|
.configurations_count = htons(1),
|
||||||
|
.current_configuration = htons(0)
|
||||||
|
});
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_configuration desc;
|
||||||
|
struct avb_aem_desc_descriptor_count descriptor_counts[8];
|
||||||
|
} __attribute__ ((__packed__)) config =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = "Configuration 1",
|
||||||
|
.localized_description = htons(1),
|
||||||
|
.descriptor_counts_count = htons(8),
|
||||||
|
.descriptor_counts_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_configuration)),
|
||||||
|
},
|
||||||
|
.descriptor_counts = {
|
||||||
|
{ htons(AVB_AEM_DESC_AUDIO_UNIT), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_INPUT), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_OUTPUT), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_AVB_INTERFACE), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_SOURCE), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_CONTROL), htons(2) },
|
||||||
|
{ htons(AVB_AEM_DESC_LOCALE), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_DOMAIN), htons(1) }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CONFIGURATION, 0,
|
||||||
|
sizeof(config), &config);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_audio_unit desc;
|
||||||
|
struct avb_aem_desc_sampling_rate sampling_rates[6];
|
||||||
|
} __attribute__ ((__packed__)) audio_unit =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = "PipeWire",
|
||||||
|
.localized_description = htons(0),
|
||||||
|
.clock_domain_index = htons(0),
|
||||||
|
.number_of_stream_input_ports = htons(1),
|
||||||
|
.base_stream_input_port = htons(0),
|
||||||
|
.number_of_stream_output_ports = htons(1),
|
||||||
|
.base_stream_output_port = htons(0),
|
||||||
|
.number_of_external_input_ports = htons(8),
|
||||||
|
.base_external_input_port = htons(0),
|
||||||
|
.number_of_external_output_ports = htons(8),
|
||||||
|
.base_external_output_port = htons(0),
|
||||||
|
.number_of_internal_input_ports = htons(0),
|
||||||
|
.base_internal_input_port = htons(0),
|
||||||
|
.number_of_internal_output_ports = htons(0),
|
||||||
|
.base_internal_output_port = htons(0),
|
||||||
|
.number_of_controls = htons(0),
|
||||||
|
.base_control = htons(0),
|
||||||
|
.number_of_signal_selectors = htons(0),
|
||||||
|
.base_signal_selector = htons(0),
|
||||||
|
.number_of_mixers = htons(0),
|
||||||
|
.base_mixer = htons(0),
|
||||||
|
.number_of_matrices = htons(0),
|
||||||
|
.base_matrix = htons(0),
|
||||||
|
.number_of_splitters = htons(0),
|
||||||
|
.base_splitter = htons(0),
|
||||||
|
.number_of_combiners = htons(0),
|
||||||
|
.base_combiner = htons(0),
|
||||||
|
.number_of_demultiplexers = htons(0),
|
||||||
|
.base_demultiplexer = htons(0),
|
||||||
|
.number_of_multiplexers = htons(0),
|
||||||
|
.base_multiplexer = htons(0),
|
||||||
|
.number_of_transcoders = htons(0),
|
||||||
|
.base_transcoder = htons(0),
|
||||||
|
.number_of_control_blocks = htons(0),
|
||||||
|
.base_control_block = htons(0),
|
||||||
|
.current_sampling_rate = htonl(48000),
|
||||||
|
.sampling_rates_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_audio_unit)),
|
||||||
|
.sampling_rates_count = htons(6),
|
||||||
|
},
|
||||||
|
.sampling_rates = {
|
||||||
|
{ .pull_frequency = htonl(44100) },
|
||||||
|
{ .pull_frequency = htonl(48000) },
|
||||||
|
{ .pull_frequency = htonl(88200) },
|
||||||
|
{ .pull_frequency = htonl(96000) },
|
||||||
|
{ .pull_frequency = htonl(176400) },
|
||||||
|
{ .pull_frequency = htonl(192000) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_UNIT, 0,
|
||||||
|
sizeof(audio_unit), &audio_unit);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_stream desc;
|
||||||
|
uint64_t stream_formats[6];
|
||||||
|
} __attribute__ ((__packed__)) stream_input_0 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = "Stream Input 1",
|
||||||
|
.localized_description = htons(0xffff),
|
||||||
|
.clock_domain_index = htons(0),
|
||||||
|
.stream_flags = htons(
|
||||||
|
AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE |
|
||||||
|
AVB_AEM_DESC_STREAM_FLAG_CLASS_A),
|
||||||
|
.current_format = htobe64(0x00a0020840000800ULL),
|
||||||
|
.formats_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_stream)),
|
||||||
|
.number_of_formats = htons(6),
|
||||||
|
.backup_talker_entity_id_0 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_0 = htons(0),
|
||||||
|
.backup_talker_entity_id_1 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_1 = htons(0),
|
||||||
|
.backup_talker_entity_id_2 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_2 = htons(0),
|
||||||
|
.backedup_talker_entity_id = htobe64(0),
|
||||||
|
.backedup_talker_unique = htons(0),
|
||||||
|
.avb_interface_index = htons(0),
|
||||||
|
.buffer_length = htons(8)
|
||||||
|
},
|
||||||
|
.stream_formats = {
|
||||||
|
htobe64(0x00a0010860000800ULL),
|
||||||
|
htobe64(0x00a0020860000800ULL),
|
||||||
|
htobe64(0x00a0030860000800ULL),
|
||||||
|
htobe64(0x00a0040860000800ULL),
|
||||||
|
htobe64(0x00a0050860000800ULL),
|
||||||
|
htobe64(0x00a0060860000800ULL),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_INPUT, 0,
|
||||||
|
sizeof(stream_input_0), &stream_input_0);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_stream desc;
|
||||||
|
uint64_t stream_formats[6];
|
||||||
|
} __attribute__ ((__packed__)) stream_output_0 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = "Stream Output 1",
|
||||||
|
.localized_description = htons(0xffff),
|
||||||
|
.clock_domain_index = htons(0),
|
||||||
|
.stream_flags = htons(
|
||||||
|
AVB_AEM_DESC_STREAM_FLAG_CLASS_A),
|
||||||
|
.current_format = htobe64(0x00a0020840000800ULL),
|
||||||
|
.formats_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_stream)),
|
||||||
|
.number_of_formats = htons(6),
|
||||||
|
.backup_talker_entity_id_0 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_0 = htons(0),
|
||||||
|
.backup_talker_entity_id_1 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_1 = htons(0),
|
||||||
|
.backup_talker_entity_id_2 = htobe64(0),
|
||||||
|
.backup_talker_unique_id_2 = htons(0),
|
||||||
|
.backedup_talker_entity_id = htobe64(0),
|
||||||
|
.backedup_talker_unique = htons(0),
|
||||||
|
.avb_interface_index = htons(0),
|
||||||
|
.buffer_length = htons(8)
|
||||||
|
},
|
||||||
|
.stream_formats = {
|
||||||
|
htobe64(0x00a0010860000800ULL),
|
||||||
|
htobe64(0x00a0020860000800ULL),
|
||||||
|
htobe64(0x00a0030860000800ULL),
|
||||||
|
htobe64(0x00a0040860000800ULL),
|
||||||
|
htobe64(0x00a0050860000800ULL),
|
||||||
|
htobe64(0x00a0060860000800ULL),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_OUTPUT, 0,
|
||||||
|
sizeof(stream_output_0), &stream_output_0);
|
||||||
|
|
||||||
|
struct avb_aem_desc_avb_interface avb_interface = {
|
||||||
|
.localized_description = htons(0xffff),
|
||||||
|
.interface_flags = htons(
|
||||||
|
AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED),
|
||||||
|
.clock_identity = htobe64(0),
|
||||||
|
.priority1 = 0,
|
||||||
|
.clock_class = 0,
|
||||||
|
.offset_scaled_log_variance = htons(0),
|
||||||
|
.clock_accuracy = 0,
|
||||||
|
.priority2 = 0,
|
||||||
|
.domain_number = 0,
|
||||||
|
.log_sync_interval = 0,
|
||||||
|
.log_announce_interval = 0,
|
||||||
|
.log_pdelay_interval = 0,
|
||||||
|
.port_number = 0,
|
||||||
|
};
|
||||||
|
strncpy(avb_interface.object_name, server->ifname, 63);
|
||||||
|
memcpy(avb_interface.mac_address, server->mac_addr, 6);
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0,
|
||||||
|
sizeof(avb_interface), &avb_interface);
|
||||||
|
|
||||||
|
struct avb_aem_desc_clock_source clock_source = {
|
||||||
|
.object_name = "Stream Clock",
|
||||||
|
.localized_description = htons(0xffff),
|
||||||
|
.clock_source_flags = htons(0),
|
||||||
|
.clock_source_type = htons(
|
||||||
|
AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM),
|
||||||
|
.clock_source_identifier = htobe64(0),
|
||||||
|
.clock_source_location_type = htons(AVB_AEM_DESC_STREAM_INPUT),
|
||||||
|
.clock_source_location_index = htons(0),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 0,
|
||||||
|
sizeof(clock_source), &clock_source);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_descriptor_milan_v12(struct server *server)
|
||||||
|
{
|
||||||
|
// TODO PERSISTENCE: retrieve the saved buffers.
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.12 - STRINGS Descriptor
|
||||||
|
* Up to 7 localized strings
|
||||||
|
*/
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STRINGS, 0,
|
||||||
|
sizeof(struct avb_aem_desc_strings),
|
||||||
|
&(struct avb_aem_desc_strings)
|
||||||
|
{
|
||||||
|
.string_0 = DSC_STRINGS_0_DEVICE_NAME,
|
||||||
|
.string_1 = DSC_STRINGS_1_CONFIGURATION_NAME,
|
||||||
|
.string_2 = DSC_STRINGS_2_MANUFACTURER_NAME,
|
||||||
|
.string_3 = DSC_STRINGS_3_GROUP_NAME,
|
||||||
|
.string_4 = DSC_STRINGS_4_MAINTAINER_0,
|
||||||
|
.string_5 = DSC_STRINGS_4_MAINTAINER_1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.11 - LOCALE Descriptor */
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_LOCALE, 0,
|
||||||
|
sizeof(struct avb_aem_desc_locale),
|
||||||
|
&(struct avb_aem_desc_locale)
|
||||||
|
{
|
||||||
|
.locale_identifier = DSC_LOCALE_LANGUAGE_CODE,
|
||||||
|
.number_of_strings = htons(DSC_LOCALE_NO_OF_STRINGS),
|
||||||
|
.base_strings = htons(DSC_LOCALE_BASE_STRINGS)
|
||||||
|
});
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.1 - ENTITY Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.1 */
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_ENTITY, 0,
|
||||||
|
sizeof(struct avb_aem_desc_entity),
|
||||||
|
&(struct avb_aem_desc_entity)
|
||||||
|
{
|
||||||
|
.entity_id = htobe64(DSC_ENTITY_MODEL_ENTITY_ID),
|
||||||
|
.entity_model_id = htobe64(DSC_ENTITY_MODEL_ID),
|
||||||
|
.entity_capabilities = htonl(DSC_ENTITY_MODEL_ENTITY_CAPABILITIES),
|
||||||
|
|
||||||
|
.talker_stream_sources = htons(DSC_ENTITY_MODEL_TALKER_STREAM_SOURCES),
|
||||||
|
.talker_capabilities = htons(DSC_ENTITY_MODEL_TALKER_CAPABILITIES),
|
||||||
|
|
||||||
|
.listener_stream_sinks = htons(DSC_ENTITY_MODEL_LISTENER_STREAM_SINKS),
|
||||||
|
.listener_capabilities = htons(DSC_ENTITY_MODEL_LISTENER_CAPABILITIES),
|
||||||
|
|
||||||
|
.controller_capabilities = htons(DSC_ENTITY_MODEL_CONTROLLER_CAPABILITIES),
|
||||||
|
|
||||||
|
.available_index = htonl(DSC_ENTITY_MODEL_AVAILABLE_INDEX),
|
||||||
|
.association_id = htobe64(DSC_ENTITY_MODEL_ASSOCIATION_ID),
|
||||||
|
|
||||||
|
.entity_name = DSC_ENTITY_MODEL_ENTITY_NAME,
|
||||||
|
.vendor_name_string = htons(DSC_ENTITY_MODEL_VENDOR_NAME_STRING),
|
||||||
|
.model_name_string = htons(DSC_ENTITY_MODEL_MODEL_NAME_STRING),
|
||||||
|
.firmware_version = DSC_ENTITY_MODEL_FIRMWARE_VERSION,
|
||||||
|
.group_name = DSC_ENTITY_MODEL_GROUP_NAME,
|
||||||
|
.serial_number = DSC_ENTITY_MODEL_SERIAL_NUMBER,
|
||||||
|
.configurations_count = htons(DSC_ENTITY_MODEL_CONFIGURATIONS_COUNT),
|
||||||
|
.current_configuration = htons(DSC_ENTITY_MODEL_CURRENT_CONFIGURATION)
|
||||||
|
});
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.2 - CONFIGURATION Descriptor*/
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.2 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_configuration desc;
|
||||||
|
struct avb_aem_desc_descriptor_count descriptor_counts[DSC_CONFIGURATION_DESCRIPTOR_COUNTS_COUNT];
|
||||||
|
} __attribute__ ((__packed__)) config =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_CONFIGURATION_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CONFIGURATION_LOCALIZED_DESCRIPTION),
|
||||||
|
.descriptor_counts_count = htons(DSC_CONFIGURATION_DESCRIPTOR_COUNTS_COUNT),
|
||||||
|
// TODO: Does it work? Was the commented out lines, now replaced with hard coded value from IEEE.
|
||||||
|
// .descriptor_counts_offset = htons(
|
||||||
|
// 4 + sizeof(struct avb_aem_desc_configuration)),
|
||||||
|
// },
|
||||||
|
.descriptor_counts_offset = htons(DSC_CONFIGURATION_DESCRIPTOR_COUNTS_OFFSET),
|
||||||
|
},
|
||||||
|
.descriptor_counts = {
|
||||||
|
{ htons(AVB_AEM_DESC_AUDIO_UNIT), htons(DSC_CONFIGURATION_NO_OF_AUDIO_UNITS) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_INPUT), htons(DSC_CONFIGURATION_NO_OF_STREAM_INPUTS) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_OUTPUT), htons(DSC_CONFIGURATION_NO_OF_STREAM_OUTPUTS) },
|
||||||
|
{ htons(AVB_AEM_DESC_AVB_INTERFACE), htons(DSC_CONFIGURATION_NO_OF_AVB_INTERFACES) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_DOMAIN), htons(DSC_CONFIGURATION_NO_OF_CLOCK_DOMAINS) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_SOURCE), htons(DSC_CONFIGURATION_NO_OF_CLOCK_SOURCES) },
|
||||||
|
{ htons(AVB_AEM_DESC_CONTROL), htons(DSC_CONFIGURATION_NO_OF_CONTROLS) },
|
||||||
|
{ htons(AVB_AEM_DESC_LOCALE), htons(DSC_CONFIGURATION_NO_OF_LOCALES) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CONFIGURATION, 0,
|
||||||
|
sizeof(config), &config);
|
||||||
|
|
||||||
|
/* Second configuration for tests*/
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_configuration desc;
|
||||||
|
struct avb_aem_desc_descriptor_count descriptor_counts[8];
|
||||||
|
} __attribute__ ((__packed__)) config1 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = "Non - redundant - 96kHz",
|
||||||
|
.localized_description = htons(1),
|
||||||
|
.descriptor_counts_count = htons(8),
|
||||||
|
.descriptor_counts_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_configuration)),
|
||||||
|
},
|
||||||
|
.descriptor_counts = {
|
||||||
|
{ htons(AVB_AEM_DESC_AUDIO_UNIT), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_INPUT), htons(2) },
|
||||||
|
{ htons(AVB_AEM_DESC_STREAM_OUTPUT), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_AVB_INTERFACE), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_DOMAIN), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_CLOCK_SOURCE), htons(3) },
|
||||||
|
{ htons(AVB_AEM_DESC_CONTROL), htons(1) },
|
||||||
|
{ htons(AVB_AEM_DESC_LOCALE), htons(1) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CONFIGURATION, 1,
|
||||||
|
sizeof(config), &config1);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.22 CONTROL Descriptor*/
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.10 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_control desc;
|
||||||
|
struct avb_aem_desc_value_format value_inf;
|
||||||
|
} __attribute__ ((__packed__)) ctrl =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_CONTROL_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CONTROL_LOCALIZED_DESCRIPTION),
|
||||||
|
|
||||||
|
.block_latency = htons(DSC_CONTROL_BLOCK_LATENCY),
|
||||||
|
.control_latency = htons(DSC_CONTROL_CONTROL_LATENCY),
|
||||||
|
.control_domain = htons(DSC_CONTROL_CONTROL_DOMAIN),
|
||||||
|
.control_value_type = htons(DSC_CONTROL_CONTROL_VALUE_TYPE),
|
||||||
|
.control_type = htobe64(DSC_CONTROL_CONTROL_TYPE),
|
||||||
|
.reset_time = htonl(DSC_CONTROL_RESET_TIME),
|
||||||
|
// TODO: This is not specified in Table 7-38
|
||||||
|
.descriptor_counts_offset = htons(
|
||||||
|
4 + sizeof(struct avb_aem_desc_control)),
|
||||||
|
.number_of_values = htons(1),
|
||||||
|
.signal_type = htons(0xffff),
|
||||||
|
.signal_index = htons(0),
|
||||||
|
.signal_output = htons(0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.minimum = DSC_CONTROL_IDENTIFY_MIN,
|
||||||
|
.maximum = DSC_CONTROL_IDENTIFY_MAX,
|
||||||
|
.step = DSC_CONTROL_IDENTIFY_STEP,
|
||||||
|
.default_value = DSC_CONTROL_IDENTIFY_DEFAULT_VALUE,
|
||||||
|
.current_value = DSC_CONTROL_IDENTIFY_CURRENT_VALUE,
|
||||||
|
.localized_description = htons(DSC_CONTROL_LOCALIZED_DESCRIPTION),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CONTROL, 0,
|
||||||
|
sizeof(ctrl), &ctrl);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.19 AUDIO_MAP Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.9 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_audio_map desc;
|
||||||
|
struct avb_aem_audio_mapping_format maps[DSC_AUDIO_MAPS_NO_OF_MAPPINGS];
|
||||||
|
} __attribute__((__packed__)) maps_input = {
|
||||||
|
.desc = {
|
||||||
|
.mapping_offset = htons(AVB_AEM_AUDIO_MAPPING_FORMAT_OFFSET),
|
||||||
|
.number_of_mappings = htons(DSC_AUDIO_MAPS_NO_OF_MAPPINGS),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t map_idx = 0; map_idx < DSC_AUDIO_MAPS_NO_OF_MAPPINGS; map_idx++) {
|
||||||
|
maps_input.maps[map_idx].mapping_stream_index = htons(DSC_AUDIO_MAPS_MAPPING_STREAM_INDEX);
|
||||||
|
maps_input.maps[map_idx].mapping_cluster_channel = htons(DSC_AUDIO_MAPS_MAPPING_CLUSTER_CHANNEL);
|
||||||
|
maps_input.maps[map_idx].mapping_cluster_offset = htons(map_idx);
|
||||||
|
maps_input.maps[map_idx].mapping_stream_channel = htons(map_idx);
|
||||||
|
}
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_MAP, 0,
|
||||||
|
sizeof(maps_input), &maps_input);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_audio_map desc;
|
||||||
|
struct avb_aem_audio_mapping_format maps[DSC_AUDIO_MAPS_NO_OF_MAPPINGS];
|
||||||
|
} __attribute__((__packed__)) maps_output= {
|
||||||
|
.desc = {
|
||||||
|
.mapping_offset = htons(AVB_AEM_AUDIO_MAPPING_FORMAT_OFFSET),
|
||||||
|
.number_of_mappings = htons(DSC_AUDIO_MAPS_NO_OF_MAPPINGS),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t map_idx = 0; map_idx < DSC_AUDIO_MAPS_NO_OF_MAPPINGS; map_idx++) {
|
||||||
|
maps_output.maps[map_idx].mapping_stream_index = htons(DSC_AUDIO_MAPS_MAPPING_STREAM_INDEX);
|
||||||
|
maps_output.maps[map_idx].mapping_cluster_channel = htons(DSC_AUDIO_MAPS_MAPPING_CLUSTER_CHANNEL);
|
||||||
|
maps_output.maps[map_idx].mapping_cluster_offset = htons(DSC_AUDIO_MAPS_NO_OF_MAPPINGS+map_idx);
|
||||||
|
maps_output.maps[map_idx].mapping_stream_channel = htons(DSC_AUDIO_MAPS_NO_OF_MAPPINGS+map_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_MAP, 1,
|
||||||
|
sizeof(maps_output), &maps_output);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.16 AUDIO_CLUSTER Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.8 */
|
||||||
|
|
||||||
|
struct avb_aem_desc_audio_cluster clusters[DSC_AUDIO_CLUSTER_NO_OF_CLUSTERS];
|
||||||
|
|
||||||
|
for (uint32_t cluster_idx = 0; cluster_idx < DSC_AUDIO_CLUSTER_NO_OF_CLUSTERS; cluster_idx++) {
|
||||||
|
memset(clusters[cluster_idx].object_name, 0,
|
||||||
|
sizeof(clusters[cluster_idx].object_name));
|
||||||
|
// TODO: Make this scale automatically
|
||||||
|
if (cluster_idx < 8) {
|
||||||
|
snprintf(clusters[cluster_idx].object_name, DSC_AUDIO_CLUSTER_OBJECT_NAME_LEN_IN_OCTET-1,
|
||||||
|
"Input %2u", cluster_idx);
|
||||||
|
} else {
|
||||||
|
snprintf(clusters[cluster_idx].object_name, DSC_AUDIO_CLUSTER_OBJECT_NAME_LEN_IN_OCTET-1,
|
||||||
|
"Output %2u", cluster_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
clusters[cluster_idx].localized_description = htons(DSC_AUDIO_CLUSTER_LOCALIZED_DESCRIPTION);
|
||||||
|
clusters[cluster_idx].signal_type = htons(DSC_AUDIO_CLUSTER_SIGNAL_TYPE);
|
||||||
|
clusters[cluster_idx].signal_index = htons(DSC_AUDIO_CLUSTER_SIGNAL_INDEX);
|
||||||
|
clusters[cluster_idx].signal_output = htons(DSC_AUDIO_CLUSTER_SIGNAL_OUTPUT);
|
||||||
|
clusters[cluster_idx].path_latency = htonl(DSC_AUDIO_CLUSTER_PATH_LATENCY_IN_NS);
|
||||||
|
clusters[cluster_idx].block_latency = htonl(DSC_AUDIO_CLUSTER_BLOCK_LATENCY_IN_NS);
|
||||||
|
clusters[cluster_idx].channel_count = htons(DSC_AUDIO_CLUSTER_CHANNEL_COUNT);
|
||||||
|
clusters[cluster_idx].format = DSC_AUDIO_CLUSTER_FORMAT;
|
||||||
|
clusters[cluster_idx].aes3_data_type_ref = DSC_AUDIO_CLUSTER_AES3_DATA_TYPE_REF;
|
||||||
|
clusters[cluster_idx].aes3_data_type = htons(DSC_AUDIO_CLUSTER_AES3_DATA_TYPE);
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_CLUSTER, cluster_idx,
|
||||||
|
sizeof(clusters[0]), &clusters[cluster_idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.13 STREAM_PORT_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.7 */
|
||||||
|
|
||||||
|
struct avb_aem_desc_stream_port stream_port_input0 = {
|
||||||
|
.clock_domain_index = htons(DSC_STREAM_PORT_INPUT_CLOCK_DOMAIN_INDEX),
|
||||||
|
.port_flags = htons(DSC_STREAM_PORT_INPUT_PORT_FLAGS),
|
||||||
|
.number_of_controls = htons(DSC_STREAM_PORT_INPUT_NUMBER_OF_CONTROLS),
|
||||||
|
.base_control = htons(DSC_STREAM_PORT_INPUT_BASE_CONTROL),
|
||||||
|
.number_of_clusters = htons(DSC_STREAM_PORT_INPUT_NUMBER_OF_CLUSTERS),
|
||||||
|
.base_cluster = htons(DSC_STREAM_PORT_INPUT_BASE_CLUSTER),
|
||||||
|
.number_of_maps = htons(DSC_STREAM_PORT_INPUT_NUMBER_OF_MAPS),
|
||||||
|
.base_map = htons(DSC_STREAM_PORT_INPUT_BASE_MAP),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_PORT_INPUT, 0,
|
||||||
|
sizeof(stream_port_input0), &stream_port_input0);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.13 STREAM_PORT_OUTPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.7 */
|
||||||
|
struct avb_aem_desc_stream_port stream_port_output0 = {
|
||||||
|
.clock_domain_index = htons(DSC_STREAM_PORT_OUTPUT_CLOCK_DOMAIN_INDEX),
|
||||||
|
.port_flags = htons(DSC_STREAM_PORT_OUTPUT_PORT_FLAGS),
|
||||||
|
.number_of_controls = htons(DSC_STREAM_PORT_OUTPUT_NUMBER_OF_CONTROLS),
|
||||||
|
.base_control = htons(DSC_STREAM_PORT_OUTPUT_BASE_CONTROL),
|
||||||
|
.number_of_clusters = htons(DSC_STREAM_PORT_OUTPUT_NUMBER_OF_CLUSTERS),
|
||||||
|
.base_cluster = htons(DSC_STREAM_PORT_OUTPUT_BASE_CLUSTER),
|
||||||
|
.number_of_maps = htons(DSC_STREAM_PORT_OUTPUT_NUMBER_OF_MAPS),
|
||||||
|
.base_map = htons(DSC_STREAM_PORT_OUTPUT_BASE_MAP),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_PORT_OUTPUT, 0,
|
||||||
|
sizeof(stream_port_output0), &stream_port_output0);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.3 AUDIO_UNIT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.3 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_audio_unit desc;
|
||||||
|
struct avb_aem_desc_sampling_rate sampling_rates[DSC_AUDIO_UNIT_SUPPORTED_SAMPLING_RATE_COUNT];
|
||||||
|
} __attribute__ ((__packed__)) audio_unit =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_AUDIO_UNIT_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_AUDIO_UNIT_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_domain_index = htons(DSC_AUDIO_UNIT_CLOCK_DOMAIN_INDEX),
|
||||||
|
.number_of_stream_input_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_STREAM_INPUT_PORTS),
|
||||||
|
.base_stream_input_port = htons(DSC_AUDIO_UNIT_BASE_STREAM_INPUT_PORT),
|
||||||
|
.number_of_stream_output_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_STREAM_OUTPUT_PORTS),
|
||||||
|
.base_stream_output_port = htons(DSC_AUDIO_UNIT_BASE_STREAM_OUTPUT_PORT),
|
||||||
|
.number_of_external_input_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_EXTERNAL_INPUT_PORTS),
|
||||||
|
.base_external_input_port = htons(DSC_AUDIO_UNIT_BASE_EXTERNAL_INPUT_PORT),
|
||||||
|
.number_of_external_output_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_EXTERNAL_OUTPUT_PORTS),
|
||||||
|
.base_external_output_port = htons(DSC_AUDIO_UNIT_BASE_EXTERNAL_OUTPUT_PORT),
|
||||||
|
.number_of_internal_input_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_INTERNAL_INPUT_PORTS),
|
||||||
|
.base_internal_input_port = htons(DSC_AUDIO_UNIT_BASE_INTERNAL_INPUT_PORT),
|
||||||
|
.number_of_internal_output_ports = htons(DSC_AUDIO_UNIT_NUMBER_OF_INTERNAL_OUTPUT_PORTS),
|
||||||
|
.base_internal_output_port = htons(DSC_AUDIO_UNIT_BASE_INTERNAL_OUTPUT_PORT),
|
||||||
|
.number_of_controls = htons(DSC_AUDIO_UNIT_NUMBER_OF_CONTROLS),
|
||||||
|
.base_control = htons(DSC_AUDIO_UNIT_BASE_CONTROL),
|
||||||
|
.number_of_signal_selectors = htons(DSC_AUDIO_UNIT_NUMBER_OF_SIGNAL_SELECTORS),
|
||||||
|
.base_signal_selector = htons(DSC_AUDIO_UNIT_BASE_SIGNAL_SELECTOR),
|
||||||
|
.number_of_mixers = htons(DSC_AUDIO_UNIT_NUMBER_OF_MIXERS),
|
||||||
|
.base_mixer = htons(DSC_AUDIO_UNIT_BASE_MIXER),
|
||||||
|
.number_of_matrices = htons(DSC_AUDIO_UNIT_NUMBER_OF_MATRICES),
|
||||||
|
.base_matrix = htons(DSC_AUDIO_UNIT_BASE_MATRIX),
|
||||||
|
.number_of_splitters = htons(DSC_AUDIO_UNIT_NUMBER_OF_SPLITTERS),
|
||||||
|
.base_splitter = htons(DSC_AUDIO_UNIT_BASE_SPLITTER),
|
||||||
|
.number_of_combiners = htons(DSC_AUDIO_UNIT_NUMBER_OF_COMBINERS),
|
||||||
|
.base_combiner = htons(DSC_AUDIO_UNIT_BASE_COMBINER),
|
||||||
|
.number_of_demultiplexers = htons(DSC_AUDIO_UNIT_NUMBER_OF_DEMULTIPLEXERS),
|
||||||
|
.base_demultiplexer = htons(DSC_AUDIO_UNIT_BASE_DEMULTIPLEXER),
|
||||||
|
.number_of_multiplexers = htons(DSC_AUDIO_UNIT_NUMBER_OF_MULTIPLEXERS),
|
||||||
|
.base_multiplexer = htons(DSC_AUDIO_UNIT_BASE_MULTIPLEXER),
|
||||||
|
.number_of_transcoders = htons(DSC_AUDIO_UNIT_NUMBER_OF_TRANSCODERS),
|
||||||
|
.base_transcoder = htons(DSC_AUDIO_UNIT_BASE_TRANSCODER),
|
||||||
|
.number_of_control_blocks = htons(DSC_AUDIO_UNIT_NUMBER_OF_CONTROL_BLOCKS),
|
||||||
|
.base_control_block = htons(DSC_AUDIO_UNIT_BASE_CONTROL_BLOCK),
|
||||||
|
.current_sampling_rate = htonl(DSC_AUDIO_UNIT_CURRENT_SAMPLING_RATE_IN_HZ),
|
||||||
|
.sampling_rates_offset = htons(DSC_AUDIO_UNIT_SAMPLING_RATES_OFFSET),
|
||||||
|
.sampling_rates_count = htons(DSC_AUDIO_UNIT_SUPPORTED_SAMPLING_RATE_COUNT),
|
||||||
|
},
|
||||||
|
.sampling_rates = {
|
||||||
|
// Set the list of supported audio unit sample rate
|
||||||
|
{ .pull_frequency = htonl(DSC_AUDIO_UNIT_SUPPORTED_SAMPLING_RATE_IN_HZ_0) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_UNIT, 0,
|
||||||
|
sizeof(audio_unit), &audio_unit);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
|
||||||
|
// TODO: 1722.1 lists redundant parameters that are not mentioned here.
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_stream desc;
|
||||||
|
uint64_t stream_formats[DSC_STREAM_INPUT_NUMBER_OF_FORMATS];
|
||||||
|
} __attribute__ ((__packed__)) stream_input_0 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_STREAM_INPUT_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_STREAM_INPUT_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_domain_index = htons(DSC_STREAM_INPUT_CLOCK_DOMAIN_INDEX),
|
||||||
|
.stream_flags = htons(DSC_STREAM_INPUT_STREAM_FLAGS),
|
||||||
|
.current_format = htobe64(DSC_STREAM_INPUT_CURRENT_FORMAT),
|
||||||
|
.formats_offset = htons(DSC_STREAM_INPUT_FORMATS_OFFSET),
|
||||||
|
.number_of_formats = htons(DSC_STREAM_INPUT_NUMBER_OF_FORMATS),
|
||||||
|
.backup_talker_entity_id_0 = htobe64(DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_0),
|
||||||
|
.backup_talker_unique_id_0 = htons(DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_0),
|
||||||
|
.backup_talker_entity_id_1 = htobe64(DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_1),
|
||||||
|
.backup_talker_unique_id_1 = htons(DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_1),
|
||||||
|
.backup_talker_entity_id_2 = htobe64(DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_2),
|
||||||
|
.backup_talker_unique_id_2 = htons(DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_2),
|
||||||
|
.backedup_talker_entity_id = htobe64(DSC_STREAM_INPUT_BACKEDUP_TALKER_ENTITY_ID),
|
||||||
|
.backedup_talker_unique = htons(DSC_STREAM_INPUT_BACKEDUP_TALKER_UNIQUE_ID),
|
||||||
|
.avb_interface_index = htons(DSC_STREAM_INPUT_AVB_INTERFACE_INDEX),
|
||||||
|
.buffer_length = htonl(DSC_STREAM_INPUT_BUFFER_LENGTH_IN_NS)
|
||||||
|
},
|
||||||
|
.stream_formats = {
|
||||||
|
htobe64(DSC_STREAM_INPUT_FORMATS_0),
|
||||||
|
htobe64(DSC_STREAM_INPUT_FORMATS_1),
|
||||||
|
htobe64(DSC_STREAM_INPUT_FORMATS_2),
|
||||||
|
htobe64(DSC_STREAM_INPUT_FORMATS_3),
|
||||||
|
htobe64(DSC_STREAM_INPUT_FORMATS_4),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_INPUT, 0,
|
||||||
|
sizeof(stream_input_0), &stream_input_0);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_stream desc;
|
||||||
|
uint64_t stream_formats[DSC_STREAM_INPUT_CRF_NUMBER_OF_FORMATS];
|
||||||
|
} __attribute__ ((__packed__)) stream_input_crf_0 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_STREAM_INPUT_CRF_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_STREAM_INPUT_CRF_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_domain_index = htons(DSC_STREAM_INPUT_CRF_CLOCK_DOMAIN_INDEX),
|
||||||
|
.stream_flags = htons(DSC_STREAM_INPUT_CRF_STREAM_FLAGS),
|
||||||
|
.current_format = htobe64(DSC_STREAM_INPUT_CRF_CURRENT_FORMAT),
|
||||||
|
.formats_offset = htons(DSC_STREAM_INPUT_CRF_FORMATS_OFFSET),
|
||||||
|
.number_of_formats = htons(DSC_STREAM_INPUT_CRF_NUMBER_OF_FORMATS),
|
||||||
|
.backup_talker_entity_id_0 = htobe64(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_0),
|
||||||
|
.backup_talker_unique_id_0 = htons(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_0),
|
||||||
|
.backup_talker_entity_id_1 = htobe64(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_1),
|
||||||
|
.backup_talker_unique_id_1 = htons(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_1),
|
||||||
|
.backup_talker_entity_id_2 = htobe64(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_2),
|
||||||
|
.backup_talker_unique_id_2 = htons(DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_2),
|
||||||
|
.backedup_talker_entity_id = htobe64(DSC_STREAM_INPUT_CRF_BACKEDUP_TALKER_ENTITY_ID),
|
||||||
|
.backedup_talker_unique = htons(DSC_STREAM_INPUT_CRF_BACKEDUP_TALKER_UNIQUE_ID),
|
||||||
|
.avb_interface_index = htons(DSC_STREAM_INPUT_CRF_AVB_INTERFACE_INDEX),
|
||||||
|
.buffer_length = htonl(DSC_STREAM_INPUT_CRF_BUFFER_LENGTH_IN_NS)
|
||||||
|
},
|
||||||
|
.stream_formats = {
|
||||||
|
htobe64(DSC_STREAM_INPUT_CRF_FORMATS_0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_INPUT, 1,
|
||||||
|
sizeof(stream_input_crf_0), &stream_input_crf_0);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_OUTPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_stream desc;
|
||||||
|
uint64_t stream_formats[DSC_STREAM_OUTPUT_NUMBER_OF_FORMATS];
|
||||||
|
} __attribute__ ((__packed__)) stream_output_0 =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.object_name = DSC_STREAM_OUTPUT_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_STREAM_OUTPUT_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_domain_index = htons(DSC_STREAM_OUTPUT_CLOCK_DOMAIN_INDEX),
|
||||||
|
.stream_flags = htons(DSC_STREAM_OUTPUT_STREAM_FLAGS),
|
||||||
|
.current_format = htobe64(DSC_STREAM_OUTPUT_CURRENT_FORMAT),
|
||||||
|
.formats_offset = htons(DSC_STREAM_OUTPUT_FORMATS_OFFSET),
|
||||||
|
.number_of_formats = htons(DSC_STREAM_OUTPUT_NUMBER_OF_FORMATS),
|
||||||
|
.backup_talker_entity_id_0 = htobe64(DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_0),
|
||||||
|
.backup_talker_unique_id_0 = htons(DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_0),
|
||||||
|
.backup_talker_entity_id_1 = htobe64(DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_1),
|
||||||
|
.backup_talker_unique_id_1 = htons(DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_1),
|
||||||
|
.backup_talker_entity_id_2 = htobe64(DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_2),
|
||||||
|
.backup_talker_unique_id_2 = htons(DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_2),
|
||||||
|
.backedup_talker_entity_id = htobe64(DSC_STREAM_OUTPUT_BACKEDUP_TALKER_ENTITY_ID),
|
||||||
|
.backedup_talker_unique = htons(DSC_STREAM_OUTPUT_BACKEDUP_TALKER_UNIQUE_ID),
|
||||||
|
.avb_interface_index = htons(DSC_STREAM_OUTPUT_AVB_INTERFACE_INDEX),
|
||||||
|
.buffer_length = htons(DSC_STREAM_OUTPUT_BUFFER_LENGTH_IN_NS)
|
||||||
|
},
|
||||||
|
.stream_formats = {
|
||||||
|
htobe64(DSC_STREAM_OUTPUT_FORMATS_0),
|
||||||
|
htobe64(DSC_STREAM_OUTPUT_FORMATS_1),
|
||||||
|
htobe64(DSC_STREAM_OUTPUT_FORMATS_2),
|
||||||
|
htobe64(DSC_STREAM_OUTPUT_FORMATS_3),
|
||||||
|
htobe64(DSC_STREAM_OUTPUT_FORMATS_4),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_OUTPUT, 0,
|
||||||
|
sizeof(stream_output_0), &stream_output_0);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.8 AVB Interface Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.5 */
|
||||||
|
|
||||||
|
struct avb_aem_desc_avb_interface avb_interface = {
|
||||||
|
.localized_description = htons(DSC_AVB_INTERFACE_LOCALIZED_DESCRIPTION),
|
||||||
|
.interface_flags = htons(DSC_AVB_INTERFACE_INTERFACE_FLAGS),
|
||||||
|
.clock_identity = htobe64(DSC_AVB_INTERFACE_CLOCK_IDENTITY),
|
||||||
|
.priority1 = DSC_AVB_INTERFACE_PRIORITY1,
|
||||||
|
.clock_class = DSC_AVB_INTERFACE_CLOCK_CLASS,
|
||||||
|
.offset_scaled_log_variance = htons(DSC_AVB_INTERFACE_OFFSET_SCALED_LOG_VARIANCE),
|
||||||
|
.clock_accuracy = DSC_AVB_INTERFACE_CLOCK_ACCURACY,
|
||||||
|
.priority2 = DSC_AVB_INTERFACE_PRIORITY2,
|
||||||
|
.domain_number = DSC_AVB_INTERFACE_DOMAIN_NUMBER,
|
||||||
|
.log_sync_interval = DSC_AVB_INTERFACE_LOG_SYNC_INTERVAL,
|
||||||
|
.log_announce_interval = DSC_AVB_INTERFACE_LOG_ANNOUNCE_INTERVAL,
|
||||||
|
.log_pdelay_interval = DSC_AVB_INTERFACE_PDELAY_INTERVAL,
|
||||||
|
.port_number = DSC_AVB_INTERFACE_PORT_NUMBER,
|
||||||
|
};
|
||||||
|
|
||||||
|
memset(avb_interface.object_name, 0, sizeof(avb_interface.object_name));
|
||||||
|
strncpy(avb_interface.object_name, "", 63);
|
||||||
|
memcpy(avb_interface.mac_address, server->mac_addr, 6);
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0,
|
||||||
|
sizeof(avb_interface), &avb_interface);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.9 CLOCK_SOURCE Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.6 */
|
||||||
|
|
||||||
|
// Internal Clock Descriptor
|
||||||
|
struct avb_aem_desc_clock_source clock_source_internal = {
|
||||||
|
.object_name = DSC_CLOCK_SOURCE_INTERNAL_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CLOCK_SOURCE_INTERNAL_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_source_flags = htons(DSC_CLOCK_SOURCE_INTERNAL_FLAGS),
|
||||||
|
.clock_source_type = htons(DSC_CLOCK_SOURCE_INTERNAL_TYPE),
|
||||||
|
.clock_source_identifier = htobe64(DSC_CLOCK_SOURCE_INTERNAL_IDENTIFIER),
|
||||||
|
.clock_source_location_type = htons(DSC_CLOCK_SOURCE_INTERNAL_LOCATION_TYPE),
|
||||||
|
.clock_source_location_index = htons(DSC_CLOCK_SOURCE_INTERNAL_LOCATION_INDEX),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 0,
|
||||||
|
sizeof(clock_source_internal), &clock_source_internal);
|
||||||
|
|
||||||
|
// AAF Clock Descriptor
|
||||||
|
struct avb_aem_desc_clock_source clock_source_aaf = {
|
||||||
|
.object_name = DSC_CLOCK_SOURCE_AAF_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CLOCK_SOURCE_AAF_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_source_flags = htons(DSC_CLOCK_SOURCE_AAF_FLAGS),
|
||||||
|
.clock_source_type = htons(DSC_CLOCK_SOURCE_AAF_TYPE),
|
||||||
|
.clock_source_identifier = htobe64(DSC_CLOCK_SOURCE_AAF_IDENTIFIER),
|
||||||
|
.clock_source_location_type = htons(DSC_CLOCK_SOURCE_AAF_LOCATION_TYPE),
|
||||||
|
.clock_source_location_index = htons(DSC_CLOCK_SOURCE_AAF_LOCATION_INDEX),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 1,
|
||||||
|
sizeof(clock_source_aaf), &clock_source_aaf);
|
||||||
|
|
||||||
|
// CRF Clock Descriptor
|
||||||
|
struct avb_aem_desc_clock_source clock_source_crf = {
|
||||||
|
.object_name = DSC_CLOCK_SOURCE_CRF_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CLOCK_SOURCE_CRF_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_source_flags = htons(DSC_CLOCK_SOURCE_CRF_FLAGS),
|
||||||
|
.clock_source_type = htons(DSC_CLOCK_SOURCE_CRF_TYPE),
|
||||||
|
.clock_source_identifier = htobe64(DSC_CLOCK_SOURCE_CRF_IDENTIFIER),
|
||||||
|
.clock_source_location_type = htons(DSC_CLOCK_SOURCE_CRF_LOCATION_TYPE),
|
||||||
|
.clock_source_location_index = htons(DSC_CLOCK_SOURCE_CRF_LOCATION_INDEX),
|
||||||
|
};
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 2,
|
||||||
|
sizeof(clock_source_crf), &clock_source_crf);
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.32 CLOCK_DOMAIN Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.11 */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct avb_aem_desc_clock_domain desc;
|
||||||
|
uint16_t clock_sources_idx[DSC_CLOCK_DOMAIN_CLOCK_SOURCES_COUNT];
|
||||||
|
} __attribute__ ((__packed__)) clock_domain = {
|
||||||
|
.desc = {
|
||||||
|
.object_name = DSC_CLOCK_DOMAIN_OBJECT_NAME,
|
||||||
|
.localized_description = htons(DSC_CLOCK_DOMAIN_LOCALIZED_DESCRIPTION),
|
||||||
|
.clock_source_index = htons(DSC_CLOCK_DOMAIN_CLOCK_SOURCE_INDEX),
|
||||||
|
.descriptor_counts_offset = htons(DSC_CLOCK_DOMAIN_DESCRIPTOR_COUNTS_OFFSET),
|
||||||
|
.clock_sources_count = htons(DSC_CLOCK_DOMAIN_CLOCK_SOURCES_COUNT),
|
||||||
|
},
|
||||||
|
.clock_sources_idx = {
|
||||||
|
htons(DSC_CLOCK_DOMAIN_SOURCES_0),
|
||||||
|
htons(DSC_CLOCK_DOMAIN_SOURCES_1),
|
||||||
|
htons(DSC_CLOCK_DOMAIN_SOURCES_2),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_DOMAIN, 0,
|
||||||
|
sizeof(clock_domain), &clock_domain);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_descriptors(struct server *server)
|
||||||
|
{
|
||||||
|
if (!server) {
|
||||||
|
pw_log_error("No server");
|
||||||
|
spa_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (server->avb_mode) {
|
||||||
|
case AVB_MODE_LEGACY:
|
||||||
|
init_descriptor_legacy_avb(server);
|
||||||
|
break;
|
||||||
|
case AVB_MODE_MILAN_V12:
|
||||||
|
init_descriptor_milan_v12(server);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pw_log_error("Unknown AVB mode");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,12 +3,6 @@
|
||||||
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki (alexandre.malki@kebag-logic.com) */
|
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki (alexandre.malki@kebag-logic.com) */
|
||||||
/* SPDX-License-Identifier: MIT */
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
#include "adp.h"
|
|
||||||
#include "aecp-aem.h"
|
|
||||||
#include "aecp-aem-descriptors.h"
|
|
||||||
#include "es-builder.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \todo This whole code needs to be re-factore,
|
* \todo This whole code needs to be re-factore,
|
||||||
* configuring the entity using such a "HARDCODED"
|
* configuring the entity using such a "HARDCODED"
|
||||||
|
|
@ -25,249 +19,4 @@
|
||||||
* Having the YANG would allow directly to know the
|
* Having the YANG would allow directly to know the
|
||||||
* capabilites/limits of the protocol
|
* capabilites/limits of the protocol
|
||||||
*/
|
*/
|
||||||
static inline void init_descriptors(struct server *server)
|
void init_descriptors(struct server *server);
|
||||||
{
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_STRINGS, 0,
|
|
||||||
sizeof(struct avb_aem_desc_strings),
|
|
||||||
&(struct avb_aem_desc_strings)
|
|
||||||
{
|
|
||||||
.string_0 = "PipeWire",
|
|
||||||
.string_1 = "Configuration 1",
|
|
||||||
.string_2 = "Wim Taymans",
|
|
||||||
});
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_LOCALE, 0,
|
|
||||||
sizeof(struct avb_aem_desc_locale),
|
|
||||||
&(struct avb_aem_desc_locale)
|
|
||||||
{
|
|
||||||
.locale_identifier = "en-EN",
|
|
||||||
.number_of_strings = htons(1),
|
|
||||||
.base_strings = htons(0)
|
|
||||||
});
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_ENTITY, 0,
|
|
||||||
sizeof(struct avb_aem_desc_entity),
|
|
||||||
&(struct avb_aem_desc_entity)
|
|
||||||
{
|
|
||||||
.entity_id = htobe64(server->entity_id),
|
|
||||||
.entity_model_id = htobe64(0),
|
|
||||||
.entity_capabilities = htonl(
|
|
||||||
AVB_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED |
|
|
||||||
AVB_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED |
|
|
||||||
AVB_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED |
|
|
||||||
AVB_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID |
|
|
||||||
AVB_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID),
|
|
||||||
|
|
||||||
.talker_stream_sources = htons(8),
|
|
||||||
.talker_capabilities = htons(
|
|
||||||
AVB_ADP_TALKER_CAPABILITY_IMPLEMENTED |
|
|
||||||
AVB_ADP_TALKER_CAPABILITY_AUDIO_SOURCE),
|
|
||||||
.listener_stream_sinks = htons(8),
|
|
||||||
.listener_capabilities = htons(
|
|
||||||
AVB_ADP_LISTENER_CAPABILITY_IMPLEMENTED |
|
|
||||||
AVB_ADP_LISTENER_CAPABILITY_AUDIO_SINK),
|
|
||||||
.controller_capabilities = htons(0),
|
|
||||||
.available_index = htonl(0),
|
|
||||||
.association_id = htobe64(0),
|
|
||||||
.entity_name = "PipeWire",
|
|
||||||
.vendor_name_string = htons(2),
|
|
||||||
.model_name_string = htons(0),
|
|
||||||
.firmware_version = "0.3.48",
|
|
||||||
.group_name = "",
|
|
||||||
.serial_number = "",
|
|
||||||
.configurations_count = htons(1),
|
|
||||||
.current_configuration = htons(0)
|
|
||||||
});
|
|
||||||
struct {
|
|
||||||
struct avb_aem_desc_configuration desc;
|
|
||||||
struct avb_aem_desc_descriptor_count descriptor_counts[8];
|
|
||||||
} __attribute__ ((__packed__)) config =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
.object_name = "Configuration 1",
|
|
||||||
.localized_description = htons(1),
|
|
||||||
.descriptor_counts_count = htons(8),
|
|
||||||
.descriptor_counts_offset = htons(
|
|
||||||
4 + sizeof(struct avb_aem_desc_configuration)),
|
|
||||||
},
|
|
||||||
.descriptor_counts = {
|
|
||||||
{ htons(AVB_AEM_DESC_AUDIO_UNIT), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_STREAM_INPUT), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_STREAM_OUTPUT), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_AVB_INTERFACE), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_CLOCK_SOURCE), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_CONTROL), htons(2) },
|
|
||||||
{ htons(AVB_AEM_DESC_LOCALE), htons(1) },
|
|
||||||
{ htons(AVB_AEM_DESC_CLOCK_DOMAIN), htons(1) }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_CONFIGURATION, 0,
|
|
||||||
sizeof(config), &config);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct avb_aem_desc_audio_unit desc;
|
|
||||||
struct avb_aem_desc_sampling_rate sampling_rates[6];
|
|
||||||
} __attribute__ ((__packed__)) audio_unit =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
.object_name = "PipeWire",
|
|
||||||
.localized_description = htons(0),
|
|
||||||
.clock_domain_index = htons(0),
|
|
||||||
.number_of_stream_input_ports = htons(1),
|
|
||||||
.base_stream_input_port = htons(0),
|
|
||||||
.number_of_stream_output_ports = htons(1),
|
|
||||||
.base_stream_output_port = htons(0),
|
|
||||||
.number_of_external_input_ports = htons(8),
|
|
||||||
.base_external_input_port = htons(0),
|
|
||||||
.number_of_external_output_ports = htons(8),
|
|
||||||
.base_external_output_port = htons(0),
|
|
||||||
.number_of_internal_input_ports = htons(0),
|
|
||||||
.base_internal_input_port = htons(0),
|
|
||||||
.number_of_internal_output_ports = htons(0),
|
|
||||||
.base_internal_output_port = htons(0),
|
|
||||||
.number_of_controls = htons(0),
|
|
||||||
.base_control = htons(0),
|
|
||||||
.number_of_signal_selectors = htons(0),
|
|
||||||
.base_signal_selector = htons(0),
|
|
||||||
.number_of_mixers = htons(0),
|
|
||||||
.base_mixer = htons(0),
|
|
||||||
.number_of_matrices = htons(0),
|
|
||||||
.base_matrix = htons(0),
|
|
||||||
.number_of_splitters = htons(0),
|
|
||||||
.base_splitter = htons(0),
|
|
||||||
.number_of_combiners = htons(0),
|
|
||||||
.base_combiner = htons(0),
|
|
||||||
.number_of_demultiplexers = htons(0),
|
|
||||||
.base_demultiplexer = htons(0),
|
|
||||||
.number_of_multiplexers = htons(0),
|
|
||||||
.base_multiplexer = htons(0),
|
|
||||||
.number_of_transcoders = htons(0),
|
|
||||||
.base_transcoder = htons(0),
|
|
||||||
.number_of_control_blocks = htons(0),
|
|
||||||
.base_control_block = htons(0),
|
|
||||||
.current_sampling_rate = htonl(48000),
|
|
||||||
.sampling_rates_offset = htons(
|
|
||||||
4 + sizeof(struct avb_aem_desc_audio_unit)),
|
|
||||||
.sampling_rates_count = htons(6),
|
|
||||||
},
|
|
||||||
.sampling_rates = {
|
|
||||||
{ .pull_frequency = htonl(44100) },
|
|
||||||
{ .pull_frequency = htonl(48000) },
|
|
||||||
{ .pull_frequency = htonl(88200) },
|
|
||||||
{ .pull_frequency = htonl(96000) },
|
|
||||||
{ .pull_frequency = htonl(176400) },
|
|
||||||
{ .pull_frequency = htonl(192000) },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_AUDIO_UNIT, 0,
|
|
||||||
sizeof(audio_unit), &audio_unit);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct avb_aem_desc_stream desc;
|
|
||||||
uint64_t stream_formats[6];
|
|
||||||
} __attribute__ ((__packed__)) stream_input_0 =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
.object_name = "Stream Input 1",
|
|
||||||
.localized_description = htons(0xffff),
|
|
||||||
.clock_domain_index = htons(0),
|
|
||||||
.stream_flags = htons(
|
|
||||||
AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE |
|
|
||||||
AVB_AEM_DESC_STREAM_FLAG_CLASS_A),
|
|
||||||
.current_format = htobe64(0x00a0020840000800ULL),
|
|
||||||
.formats_offset = htons(
|
|
||||||
4 + sizeof(struct avb_aem_desc_stream)),
|
|
||||||
.number_of_formats = htons(6),
|
|
||||||
.backup_talker_entity_id_0 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_0 = htons(0),
|
|
||||||
.backup_talker_entity_id_1 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_1 = htons(0),
|
|
||||||
.backup_talker_entity_id_2 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_2 = htons(0),
|
|
||||||
.backedup_talker_entity_id = htobe64(0),
|
|
||||||
.backedup_talker_unique = htons(0),
|
|
||||||
.avb_interface_index = htons(0),
|
|
||||||
.buffer_length = htons(8)
|
|
||||||
},
|
|
||||||
.stream_formats = {
|
|
||||||
htobe64(0x00a0010860000800ULL),
|
|
||||||
htobe64(0x00a0020860000800ULL),
|
|
||||||
htobe64(0x00a0030860000800ULL),
|
|
||||||
htobe64(0x00a0040860000800ULL),
|
|
||||||
htobe64(0x00a0050860000800ULL),
|
|
||||||
htobe64(0x00a0060860000800ULL),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_INPUT, 0,
|
|
||||||
sizeof(stream_input_0), &stream_input_0);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct avb_aem_desc_stream desc;
|
|
||||||
uint64_t stream_formats[6];
|
|
||||||
} __attribute__ ((__packed__)) stream_output_0 =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
.object_name = "Stream Output 1",
|
|
||||||
.localized_description = htons(0xffff),
|
|
||||||
.clock_domain_index = htons(0),
|
|
||||||
.stream_flags = htons(
|
|
||||||
AVB_AEM_DESC_STREAM_FLAG_CLASS_A),
|
|
||||||
.current_format = htobe64(0x00a0020840000800ULL),
|
|
||||||
.formats_offset = htons(
|
|
||||||
4 + sizeof(struct avb_aem_desc_stream)),
|
|
||||||
.number_of_formats = htons(6),
|
|
||||||
.backup_talker_entity_id_0 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_0 = htons(0),
|
|
||||||
.backup_talker_entity_id_1 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_1 = htons(0),
|
|
||||||
.backup_talker_entity_id_2 = htobe64(0),
|
|
||||||
.backup_talker_unique_id_2 = htons(0),
|
|
||||||
.backedup_talker_entity_id = htobe64(0),
|
|
||||||
.backedup_talker_unique = htons(0),
|
|
||||||
.avb_interface_index = htons(0),
|
|
||||||
.buffer_length = htons(8)
|
|
||||||
},
|
|
||||||
.stream_formats = {
|
|
||||||
htobe64(0x00a0010860000800ULL),
|
|
||||||
htobe64(0x00a0020860000800ULL),
|
|
||||||
htobe64(0x00a0030860000800ULL),
|
|
||||||
htobe64(0x00a0040860000800ULL),
|
|
||||||
htobe64(0x00a0050860000800ULL),
|
|
||||||
htobe64(0x00a0060860000800ULL),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_STREAM_OUTPUT, 0,
|
|
||||||
sizeof(stream_output_0), &stream_output_0);
|
|
||||||
|
|
||||||
struct avb_aem_desc_avb_interface avb_interface = {
|
|
||||||
.localized_description = htons(0xffff),
|
|
||||||
.interface_flags = htons(
|
|
||||||
AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED),
|
|
||||||
.clock_identity = htobe64(0),
|
|
||||||
.priority1 = 0,
|
|
||||||
.clock_class = 0,
|
|
||||||
.offset_scaled_log_variance = htons(0),
|
|
||||||
.clock_accuracy = 0,
|
|
||||||
.priority2 = 0,
|
|
||||||
.domain_number = 0,
|
|
||||||
.log_sync_interval = 0,
|
|
||||||
.log_announce_interval = 0,
|
|
||||||
.log_pdelay_interval = 0,
|
|
||||||
.port_number = 0,
|
|
||||||
};
|
|
||||||
strncpy(avb_interface.object_name, server->ifname, 63);
|
|
||||||
memcpy(avb_interface.mac_address, server->mac_addr, 6);
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0,
|
|
||||||
sizeof(avb_interface), &avb_interface);
|
|
||||||
|
|
||||||
struct avb_aem_desc_clock_source clock_source = {
|
|
||||||
.object_name = "Stream Clock",
|
|
||||||
.localized_description = htons(0xffff),
|
|
||||||
.clock_source_flags = htons(0),
|
|
||||||
.clock_source_type = htons(
|
|
||||||
AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM),
|
|
||||||
.clock_source_identifier = htobe64(0),
|
|
||||||
.clock_source_location_type = htons(AVB_AEM_DESC_STREAM_INPUT),
|
|
||||||
.clock_source_location_index = htons(0),
|
|
||||||
};
|
|
||||||
es_builder_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 0,
|
|
||||||
sizeof(clock_source), &clock_source);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
477
src/modules/module-avb/entity-model-milan-v12.h
Normal file
477
src/modules/module-avb/entity-model-milan-v12.h
Normal file
|
|
@ -0,0 +1,477 @@
|
||||||
|
/* PipeWire */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Kebag-Logic */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Simon Gapp <simon.gapp@kebag-logic.com> */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#ifndef __DESCRIPTOR_ENTITY_MODEL_MILAN_H__
|
||||||
|
#define __DESCRIPTOR_ENTITY_MODEL_MILAN_H__
|
||||||
|
|
||||||
|
#define TALKER_ENABLE 1
|
||||||
|
|
||||||
|
// TODO: Make defines as long as specified length
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.12 - STRINGS Descriptor
|
||||||
|
* Up to 7 localized strings
|
||||||
|
*/
|
||||||
|
#define DSC_STRINGS_0_DEVICE_NAME "PipeWire"
|
||||||
|
#define DSC_STRINGS_1_CONFIGURATION_NAME "NON - redundant - 48kHz"
|
||||||
|
#define DSC_STRINGS_2_MANUFACTURER_NAME "Kebag Logic"
|
||||||
|
#define DSC_STRINGS_3_GROUP_NAME "Kebag Logic"
|
||||||
|
#define DSC_STRINGS_4_MAINTAINER_0 "Alexandre Malki"
|
||||||
|
#define DSC_STRINGS_4_MAINTAINER_1 "Simon Gapp"
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.11 - LOCALE Descriptor */
|
||||||
|
#define DSC_LOCALE_LANGUAGE_CODE "en-EN"
|
||||||
|
#define DSC_LOCALE_NO_OF_STRINGS 1
|
||||||
|
#define DSC_LOCALE_BASE_STRINGS 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.1 - ENTITY Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.1 */
|
||||||
|
|
||||||
|
#define DSC_ENTITY_MODEL_ENTITY_ID 0xDEAD00BEEF00FEED
|
||||||
|
#define DSC_ENTITY_MODEL_ID 0
|
||||||
|
#define DSC_ENTITY_MODEL_ENTITY_CAPABILITIES (AVB_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED | \
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED | \
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED | \
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID | \
|
||||||
|
AVB_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID)
|
||||||
|
/* IEEE 1722.1-2021, Table 7-2 - ENTITY Descriptor
|
||||||
|
* This is the maximum number of STREAM_OUTPUT
|
||||||
|
* descriptors the ATDECC Entity has for
|
||||||
|
* Output Streams in any of its Configurations */
|
||||||
|
|
||||||
|
#if TALKER_ENABLE
|
||||||
|
#define DSC_ENTITY_MODEL_TALKER_STREAM_SOURCES 8
|
||||||
|
#define DSC_ENTITY_MODEL_TALKER_CAPABILITIES (AVB_ADP_TALKER_CAPABILITY_IMPLEMENTED | \
|
||||||
|
AVB_ADP_TALKER_CAPABILITY_AUDIO_SOURCE)
|
||||||
|
#else
|
||||||
|
#define DSC_ENTITY_MODEL_TALKER_STREAM_SOURCES 0
|
||||||
|
#define DSC_ENTITY_MODEL_TALKER_CAPABILITIES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define DSC_ENTITY_MODEL_LISTENER_STREAM_SINKS 8
|
||||||
|
#define DSC_ENTITY_MODEL_LISTENER_CAPABILITIES (AVB_ADP_LISTENER_CAPABILITY_IMPLEMENTED | \
|
||||||
|
AVB_ADP_LISTENER_CAPABILITY_AUDIO_SINK)
|
||||||
|
#define DSC_ENTITY_MODEL_CONTROLLER_CAPABILITIES 0
|
||||||
|
/* IEEE 1722.1-2021, Table 7-2 ENTITY Descriptor
|
||||||
|
* The available index of the ATDECC Entity.
|
||||||
|
* This is the same as the available_index field
|
||||||
|
* in ATDECC Discovery Protocol.*/
|
||||||
|
#define DSC_ENTITY_MODEL_AVAILABLE_INDEX 0
|
||||||
|
/* IEEE 1722.1-2021, Table 7-2 ENTITY Descriptor
|
||||||
|
* The association ID for the ATDECC Entity.
|
||||||
|
* This is the same as association_id field
|
||||||
|
* in ATDECC Discovery Protocol*/
|
||||||
|
#define DSC_ENTITY_MODEL_ASSOCIATION_ID 0
|
||||||
|
#define DSC_ENTITY_MODEL_ENTITY_NAME DSC_STRINGS_0_DEVICE_NAME
|
||||||
|
/* IEEE 1722.1-2021, Table 7-2 - ENTITY Descriptor
|
||||||
|
* The localized string reference pointing to the
|
||||||
|
* localized vendor name. See 7.3.7. */
|
||||||
|
#define DSC_ENTITY_MODEL_VENDOR_NAME_STRING 2
|
||||||
|
/* IEEE 1722.1-2021, Table 7-2 - ENTITY Descriptor
|
||||||
|
* The localized string reference pointing to the
|
||||||
|
* localized model name. See 7.3.7. */
|
||||||
|
#define DSC_ENTITY_MODEL_MODEL_NAME_STRING 0
|
||||||
|
#define DSC_ENTITY_MODEL_FIRMWARE_VERSION "0.3.48"
|
||||||
|
#define DSC_ENTITY_MODEL_GROUP_NAME DSC_STRINGS_3_GROUP_NAME
|
||||||
|
#define DSC_ENTITY_MODEL_SERIAL_NUMBER "0xBEBEDEAD"
|
||||||
|
#define DSC_ENTITY_MODEL_CONFIGURATIONS_COUNT 2
|
||||||
|
#define DSC_ENTITY_MODEL_CURRENT_CONFIGURATION 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.2 - CONFIGURATION Descriptor*/
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.2 */
|
||||||
|
#define DSC_CONFIGURATION_DESCRIPTOR_COUNTS_COUNT 8
|
||||||
|
#define DSC_CONFIGURATION_OBJECT_NAME DSC_STRINGS_1_CONFIGURATION_NAME
|
||||||
|
/* IEEE 1722.1-2021, Table 7-3 CONFIGURATION Descriptor
|
||||||
|
* The localized string reference pointing to the
|
||||||
|
* localized Configuration name. */
|
||||||
|
#define DSC_CONFIGURATION_LOCALIZED_DESCRIPTION 1
|
||||||
|
/* IEEE 1722.1-2021, Table 7-3 CONFIGURATION Descriptor
|
||||||
|
* The offset to the descriptor_counts field from the
|
||||||
|
* start of the descriptor. This field is set to 74 for
|
||||||
|
* this version of AEM. */
|
||||||
|
#define DSC_CONFIGURATION_DESCRIPTOR_COUNTS_OFFSET 74
|
||||||
|
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_AUDIO_UNITS 1
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_STREAM_INPUTS 2
|
||||||
|
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_STREAM_OUTPUTS 1
|
||||||
|
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_AVB_INTERFACES 1
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_CLOCK_DOMAINS 1
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_CLOCK_SOURCES 3
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_CONTROLS 1
|
||||||
|
#define DSC_CONFIGURATION_NO_OF_LOCALES 1
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.22 CONTROL Descriptor*/
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.10 */
|
||||||
|
|
||||||
|
#define DSC_CONTROL_OBJECT_NAME "Identify"
|
||||||
|
#define DSC_CONTROL_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CONTROL_BLOCK_LATENCY 500
|
||||||
|
#define DSC_CONTROL_CONTROL_LATENCY 500
|
||||||
|
#define DSC_CONTROL_CONTROL_DOMAIN 0
|
||||||
|
#define DSC_CONTROL_CONTROL_VALUE_TYPE AECP_AEM_CTRL_LINEAR_UINT8
|
||||||
|
#define DSC_CONTROL_CONTROL_TYPE AEM_CTRL_TYPE_IDENTIFY
|
||||||
|
/* IEEE 1722.1-2021, Table 7-39 - CONTROL Descriptor
|
||||||
|
* The time period in microseconds from when a control
|
||||||
|
* is set with the SET_CONTROL command till it automatically
|
||||||
|
* resets to its default values.
|
||||||
|
* When this is set to zero (0) automatic resets do not happen. */
|
||||||
|
// TODO: Milan v1.2: The PAAD remains in identification mode until the value of the “IDENTIFY” CONTROL descriptor is set back to 0.
|
||||||
|
#define DSC_CONTROL_RESET_TIME 3
|
||||||
|
#define DSC_CONTROL_NUMBER_OF_VALUES 1
|
||||||
|
#define DSC_CONTROL_SIGNAL_TYPE AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CONTROL_SIGNAL_INDEX 0
|
||||||
|
#define DSC_CONTROL_SIGNAL_OUTPUT 0
|
||||||
|
|
||||||
|
#define DSC_CONTROL_IDENTIFY_MIN 0
|
||||||
|
#define DSC_CONTROL_IDENTIFY_MAX 255
|
||||||
|
#define DSC_CONTROL_IDENTIFY_STEP 255
|
||||||
|
#define DSC_CONTROL_IDENTIFY_DEFAULT_VALUE 0
|
||||||
|
#define DSC_CONTROL_IDENTIFY_CURRENT_VALUE 0
|
||||||
|
#define DSC_CONTROL_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.19 AUDIO_MAP Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.9 */
|
||||||
|
|
||||||
|
// TODO: Prepared for for loop over total number of audio maps
|
||||||
|
#define DSC_AUDIO_MAPS_TOTAL_NO_OF_MAPS 2
|
||||||
|
|
||||||
|
#define DSC_AUDIO_MAPS_NO_OF_MAPPINGS 8
|
||||||
|
#define DSC_AUDIO_MAPS_MAPPING_STREAM_INDEX 0
|
||||||
|
#define DSC_AUDIO_MAPS_MAPPING_CLUSTER_CHANNEL 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.16 AUDIO_CLUSTER Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.8 */
|
||||||
|
#define DSC_AUDIO_CLUSTER_NO_OF_CLUSTERS 16
|
||||||
|
#define DSC_AUDIO_CLUSTER_OBJECT_NAME_LEN_IN_OCTET 64
|
||||||
|
#define DSC_AUDIO_CLUSTER_OBJECT_NAME_INPUT "Input"
|
||||||
|
#define DSC_AUDIO_CLUSTER_OBJECT_NAME_OUTPUT "Output"
|
||||||
|
|
||||||
|
#define DSC_AUDIO_CLUSTER_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
|
||||||
|
/* The signal_type and signal_index fields indicate the
|
||||||
|
* object providing the signal destined for the channels
|
||||||
|
* of the streams mapped to the port. For a signal which
|
||||||
|
* is sourced internally from the Unit, the signal_type
|
||||||
|
* is set to AUDIO_UNIT and signal_index is set to the
|
||||||
|
* index of the Unit. For a Cluster attached to a
|
||||||
|
* STREAM_PORT_INPUT the signal_type and signal_index
|
||||||
|
* fields is set to INVALID and zero (0) respectively. */
|
||||||
|
#define DSC_AUDIO_CLUSTER_SIGNAL_TYPE 0
|
||||||
|
#define DSC_AUDIO_CLUSTER_SIGNAL_INDEX 0
|
||||||
|
/* The index of the output of the signal source of the
|
||||||
|
* cluster. For a signal_type of SIGNAL_SPLITTER or
|
||||||
|
* SIGNAL_DEMULTIPLEXER this is which output of the
|
||||||
|
* object it is being sourced from, for a signal_type
|
||||||
|
* of MATRIX this is the column the signal is from
|
||||||
|
* and for any other signal_type this is zero (0). */
|
||||||
|
#define DSC_AUDIO_CLUSTER_SIGNAL_OUTPUT 0
|
||||||
|
#define DSC_AUDIO_CLUSTER_PATH_LATENCY_IN_NS 500
|
||||||
|
#define DSC_AUDIO_CLUSTER_BLOCK_LATENCY_IN_NS 500
|
||||||
|
#define DSC_AUDIO_CLUSTER_CHANNEL_COUNT 1
|
||||||
|
#define DSC_AUDIO_CLUSTER_FORMAT AVB_AEM_AUDIO_CLUSTER_TYPE_MBLA
|
||||||
|
#define DSC_AUDIO_CLUSTER_AES3_DATA_TYPE_REF 0
|
||||||
|
#define DSC_AUDIO_CLUSTER_AES3_DATA_TYPE 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.13 STREAM_PORT_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.7 */
|
||||||
|
|
||||||
|
#define DSC_STREAM_PORT_INPUT_CLOCK_DOMAIN_INDEX 0x0000
|
||||||
|
#define DSC_STREAM_PORT_INPUT_PORT_FLAGS AVB_AEM_PORT_FLAG_CLOCK_SYNC_SOURCE
|
||||||
|
/* The number of clusters within the Port. This corresponds to the number of
|
||||||
|
* AUDIO_CLUSTER, VIDEO_CLUSTER or SENSOR_CLUSTER descriptors which represent
|
||||||
|
* these clusters. */
|
||||||
|
// TODO: Validate value
|
||||||
|
#define DSC_STREAM_PORT_INPUT_NUMBER_OF_CONTROLS 0
|
||||||
|
#define DSC_STREAM_PORT_INPUT_BASE_CONTROL 0
|
||||||
|
// TODO: Validate value
|
||||||
|
#define DSC_STREAM_PORT_INPUT_NUMBER_OF_CLUSTERS 8
|
||||||
|
#define DSC_STREAM_PORT_INPUT_BASE_CLUSTER 0
|
||||||
|
#define DSC_STREAM_PORT_INPUT_NUMBER_OF_MAPS 1
|
||||||
|
#define DSC_STREAM_PORT_INPUT_BASE_MAP 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.13 STREAM_PORT_OUTPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.7 */
|
||||||
|
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_CLOCK_DOMAIN_INDEX 0
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_PORT_FLAGS AVB_AEM_PORT_FLAG_NO_FLAG
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_NUMBER_OF_CONTROLS 0
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_BASE_CONTROL 0
|
||||||
|
// TODO: Verify
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_NUMBER_OF_CLUSTERS 8
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_BASE_CLUSTER 8
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_NUMBER_OF_MAPS 1
|
||||||
|
#define DSC_STREAM_PORT_OUTPUT_BASE_MAP 1
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.3 AUDIO_UNIT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.3 */
|
||||||
|
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.3.1
|
||||||
|
* A sampling rate consists of a 3 bit pull field
|
||||||
|
* representing a multiplier and a 29 bit
|
||||||
|
* base_frequency in hertz, as detailed in Figure 7-2.
|
||||||
|
* The pull field specifies the multiplier modifier
|
||||||
|
* of the base_frequency field which is required to
|
||||||
|
* calculate the appropriate nominal sampling rate.
|
||||||
|
* The pull field may have one of the values defined
|
||||||
|
* in Table 7-70:
|
||||||
|
* The base_frequency field defines the nominal base
|
||||||
|
* sampling rate in Hz, from 1 Hz to 536 870 911 Hz.
|
||||||
|
* The value of this field is augmented by the
|
||||||
|
* pull field value.*/
|
||||||
|
#define BUILD_SAMPLING_RATE(pull, base_freq_hz) \
|
||||||
|
(((uint32_t)(pull) << 29) | ((uint32_t)(base_freq_hz) & 0x1FFFFFFF))
|
||||||
|
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_OBJECT_NAME ""
|
||||||
|
#define DSC_AUDIO_UNIT_LOCALIZED_DESCRIPTION 0xFFFF
|
||||||
|
#define DSC_AUDIO_UNIT_CLOCK_DOMAIN_INDEX 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_STREAM_INPUT_PORTS 0x0001
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_STREAM_INPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#if TALKER_ENABLE
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_STREAM_OUTPUT_PORTS 0x0001
|
||||||
|
#else
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_STREAM_OUTPUT_PORTS 0x0000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_STREAM_OUTPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_EXTERNAL_INPUT_PORTS 0x0008
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_EXTERNAL_INPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_EXTERNAL_OUTPUT_PORTS 0x0008
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_EXTERNAL_OUTPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_INTERNAL_INPUT_PORTS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_INTERNAL_INPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_INTERNAL_OUTPUT_PORTS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_INTERNAL_OUTPUT_PORT 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_CONTROLS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_CONTROL 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_SIGNAL_SELECTORS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_SIGNAL_SELECTOR 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_MIXERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_MIXER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_MATRICES 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_MATRIX 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_SPLITTERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_SPLITTER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_COMBINERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_COMBINER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_DEMULTIPLEXERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_DEMULTIPLEXER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_MULTIPLEXERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_MULTIPLEXER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_TRANSCODERS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_TRANSCODER 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_NUMBER_OF_CONTROL_BLOCKS 0x0000
|
||||||
|
#define DSC_AUDIO_UNIT_BASE_CONTROL_BLOCK 0x0000
|
||||||
|
|
||||||
|
#define DSC_AUDIO_UNIT_SAMPLING_RATE_PULL 0
|
||||||
|
#define DSC_AUDIO_UNIT_SAMPLING_RATE_BASE_FREQ_IN_HZ 48000
|
||||||
|
#define DSC_AUDIO_UNIT_CURRENT_SAMPLING_RATE_IN_HZ \
|
||||||
|
BUILD_SAMPLING_RATE(DSC_AUDIO_UNIT_SAMPLING_RATE_PULL, DSC_AUDIO_UNIT_SAMPLING_RATE_BASE_FREQ_IN_HZ)
|
||||||
|
/* The offset to the sample_rates field from the start of the descriptor.
|
||||||
|
* This field is 144 for this version of AEM.*/
|
||||||
|
#define DSC_AUDIO_UNIT_SAMPLING_RATES_OFFSET 144
|
||||||
|
#define DSC_AUDIO_UNIT_SUPPORTED_SAMPLING_RATE_COUNT 0x0001
|
||||||
|
#define DSC_AUDIO_UNIT_SUPPORTED_SAMPLING_RATE_IN_HZ_0 \
|
||||||
|
BUILD_SAMPLING_RATE(DSC_AUDIO_UNIT_SAMPLING_RATE_PULL, DSC_AUDIO_UNIT_SAMPLING_RATE_BASE_FREQ_IN_HZ)
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
|
||||||
|
// TODO: 1722.1 lists redundant parameters that are not mentioned here.
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_OBJECT_NAME "Stream 1"
|
||||||
|
#define DSC_STREAM_INPUT_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_STREAM_INPUT_CLOCK_DOMAIN_INDEX 0
|
||||||
|
#define DSC_STREAM_INPUT_STREAM_FLAGS (AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE | AVB_AEM_DESC_STREAM_FLAG_CLASS_A)
|
||||||
|
// To match my talker
|
||||||
|
// TODO: Define based on AUDIO_UNIT etc.
|
||||||
|
#define DSC_STREAM_INPUT_CURRENT_FORMAT 0x0205022001006000ULL
|
||||||
|
|
||||||
|
// TODO: Is 132 here, should be 138 according to spec
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_OFFSET (4 + sizeof(struct avb_aem_desc_stream))
|
||||||
|
#define DSC_STREAM_INPUT_NUMBER_OF_FORMATS 5
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_0 0
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_0 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_1 0
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_1 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_ENTITY_ID_2 0
|
||||||
|
#define DSC_STREAM_INPUT_BACKUP_TALKER_UNIQUE_ID_2 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_BACKEDUP_TALKER_ENTITY_ID 0
|
||||||
|
#define DSC_STREAM_INPUT_BACKEDUP_TALKER_UNIQUE_ID 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_AVB_INTERFACE_INDEX 0
|
||||||
|
#define DSC_STREAM_INPUT_BUFFER_LENGTH_IN_NS 2126000
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_0 DSC_STREAM_INPUT_CURRENT_FORMAT
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_1 0x0205022000406000ULL
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_2 0x0205022000806000ULL
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_3 0x0205022001806000ULL
|
||||||
|
#define DSC_STREAM_INPUT_FORMATS_4 0x0205022002006000ULL
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_INPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_OBJECT_NAME "CRF"
|
||||||
|
#define DSC_STREAM_INPUT_CRF_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_STREAM_INPUT_CRF_CLOCK_DOMAIN_INDEX 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_STREAM_FLAGS (AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE | AVB_AEM_DESC_STREAM_FLAG_CLASS_A)
|
||||||
|
#define DSC_STREAM_INPUT_CRF_CURRENT_FORMAT 0x041060010000BB80ULL
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_FORMATS_OFFSET (4 + sizeof(struct avb_aem_desc_stream))
|
||||||
|
#define DSC_STREAM_INPUT_CRF_NUMBER_OF_FORMATS 1
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_0 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_0 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_1 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_1 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_ENTITY_ID_2 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKUP_TALKER_UNIQUE_ID_2 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKEDUP_TALKER_ENTITY_ID 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BACKEDUP_TALKER_UNIQUE_ID 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_AVB_INTERFACE_INDEX 0
|
||||||
|
#define DSC_STREAM_INPUT_CRF_BUFFER_LENGTH_IN_NS 2126000
|
||||||
|
|
||||||
|
#define DSC_STREAM_INPUT_CRF_FORMATS_0 DSC_STREAM_INPUT_CRF_CURRENT_FORMAT
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.6 STREAM_OUTPUT Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.4 */
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_OBJECT_NAME "Stream output 1"
|
||||||
|
#define DSC_STREAM_OUTPUT_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_STREAM_OUTPUT_CLOCK_DOMAIN_INDEX 0
|
||||||
|
#define DSC_STREAM_OUTPUT_STREAM_FLAGS (AVB_AEM_DESC_STREAM_FLAG_CLASS_A)
|
||||||
|
#define DSC_STREAM_OUTPUT_CURRENT_FORMAT 0x0205022002006000ULL
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_OFFSET (4 + sizeof(struct avb_aem_desc_stream))
|
||||||
|
#define DSC_STREAM_OUTPUT_NUMBER_OF_FORMATS 5
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_0 0
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_0 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_1 0
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_1 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_ENTITY_ID_2 0
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKUP_TALKER_UNIQUE_ID_2 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKEDUP_TALKER_ENTITY_ID 0
|
||||||
|
#define DSC_STREAM_OUTPUT_BACKEDUP_TALKER_UNIQUE_ID 0
|
||||||
|
|
||||||
|
#define DSC_STREAM_OUTPUT_AVB_INTERFACE_INDEX 0
|
||||||
|
#define DSC_STREAM_OUTPUT_BUFFER_LENGTH_IN_NS 8
|
||||||
|
|
||||||
|
// TODO: No hardcoded values!
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_0 0x0205022000406000ULL
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_1 0x0205022000806000ULL
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_2 0x0205022001006000ULL
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_3 0x0205022001806000ULL
|
||||||
|
#define DSC_STREAM_OUTPUT_FORMATS_4 DSC_STREAM_OUTPUT_CURRENT_FORMAT
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.8 AVB Interface Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.5 */
|
||||||
|
|
||||||
|
#define DSC_AVB_INTERFACE_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_AVB_INTERFACE_INTERFACE_FLAGS (AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED | \
|
||||||
|
AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_SUPPORTED | \
|
||||||
|
AVB_AEM_DESC_AVB_INTERFACE_FLAG_SRP_SUPPORTED)
|
||||||
|
// TODO: This is a dynamic parameter
|
||||||
|
#define DSC_AVB_INTERFACE_CLOCK_IDENTITY 0x3cc0c6FFFE0002CB
|
||||||
|
#define DSC_AVB_INTERFACE_PRIORITY1 0xF8
|
||||||
|
#define DSC_AVB_INTERFACE_CLOCK_CLASS 0xF8
|
||||||
|
#define DSC_AVB_INTERFACE_OFFSET_SCALED_LOG_VARIANCE 0x436A
|
||||||
|
#define DSC_AVB_INTERFACE_CLOCK_ACCURACY 0x21
|
||||||
|
#define DSC_AVB_INTERFACE_PRIORITY2 0xF8
|
||||||
|
#define DSC_AVB_INTERFACE_DOMAIN_NUMBER 0
|
||||||
|
#define DSC_AVB_INTERFACE_LOG_SYNC_INTERVAL 0
|
||||||
|
#define DSC_AVB_INTERFACE_LOG_ANNOUNCE_INTERVAL 0
|
||||||
|
#define DSC_AVB_INTERFACE_PDELAY_INTERVAL 0
|
||||||
|
#define DSC_AVB_INTERFACE_PORT_NUMBER 0
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.9 CLOCK_SOURCE Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.6 */
|
||||||
|
|
||||||
|
// Internal Clock Source
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_OBJECT_NAME "Internal"
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_FLAGS 0x0002
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_TYPE AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INTERNAL
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_IDENTIFIER 0
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_LOCATION_TYPE AVB_AEM_DESC_CLOCK_SOURCE
|
||||||
|
#define DSC_CLOCK_SOURCE_INTERNAL_LOCATION_INDEX 0
|
||||||
|
|
||||||
|
// AAF Stream Clock Source
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_OBJECT_NAME "Stream Clock"
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_FLAGS 0x0002
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_TYPE AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_IDENTIFIER 0
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_LOCATION_TYPE AVB_AEM_DESC_STREAM_INPUT
|
||||||
|
#define DSC_CLOCK_SOURCE_AAF_LOCATION_INDEX 0
|
||||||
|
|
||||||
|
// CRF Clock Source
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_OBJECT_NAME "CRF Clock"
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_FLAGS 0x0002
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_TYPE AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_IDENTIFIER 0
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_LOCATION_TYPE AVB_AEM_DESC_STREAM_INPUT
|
||||||
|
#define DSC_CLOCK_SOURCE_CRF_LOCATION_INDEX 1
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
/* IEEE 1722.1-2021, Sec. 7.2.32 CLOCK_DOMAIN Descriptor */
|
||||||
|
/* Milan v1.2, Sec. 5.3.3.11 */
|
||||||
|
|
||||||
|
#define DSC_CLOCK_DOMAIN_OBJECT_NAME "Clock Reference Format"
|
||||||
|
#define DSC_CLOCK_DOMAIN_LOCALIZED_DESCRIPTION AVB_AEM_DESC_INVALID
|
||||||
|
#define DSC_CLOCK_DOMAIN_CLOCK_SOURCE_INDEX 0
|
||||||
|
#define DSC_CLOCK_DOMAIN_DESCRIPTOR_COUNTS_OFFSET (4 + sizeof(struct avb_aem_desc_clock_domain))
|
||||||
|
#define DSC_CLOCK_DOMAIN_CLOCK_SOURCES_COUNT 3
|
||||||
|
|
||||||
|
#define DSC_CLOCK_DOMAIN_SOURCES_0 0 // Internal
|
||||||
|
#define DSC_CLOCK_DOMAIN_SOURCES_1 1 // AAF
|
||||||
|
#define DSC_CLOCK_DOMAIN_SOURCES_2 2 // CRF
|
||||||
|
|
||||||
|
#endif // __DESCRIPTOR_ENTITY_MODEL_MILAN_H__
|
||||||
Loading…
Add table
Reference in a new issue