mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-20 16:10:04 +01:00
Merge branch '5017-implement-get-set-stream-format' into 'master'
module-avb: aecp-aem: introduce SET/GET STREAM_FORMAT See merge request pipewire/pipewire!2628
This commit is contained in:
commit
c18a0c6513
5 changed files with 179 additions and 3 deletions
|
|
@ -736,11 +736,13 @@ if build_module_avb
|
||||||
'module-avb/acmp.c',
|
'module-avb/acmp.c',
|
||||||
'module-avb/aecp.c',
|
'module-avb/aecp.c',
|
||||||
'module-avb/aecp-aem.c',
|
'module-avb/aecp-aem.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c',
|
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-available.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-available.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-get-set-name.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-get-set-name.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-get-set-stream-format.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c',
|
||||||
'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',
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ static int send_unsol_name(struct aecp *aecp,
|
||||||
{
|
{
|
||||||
uint8_t unsol_buf[512];
|
uint8_t unsol_buf[512];
|
||||||
struct avb_ethernet_header *h_unsol = (void*)unsol_buf;
|
struct avb_ethernet_header *h_unsol = (void*)unsol_buf;
|
||||||
struct avb_packet_aecp_aem *p_unsol = SPA_PTROFF(h_unsol, sizeof(*h_unsol), void);
|
|
||||||
struct aecp_aem_base_info info = { 0 };
|
struct aecp_aem_base_info info = { 0 };
|
||||||
|
|
||||||
memcpy(unsol_buf, msg, len);
|
memcpy(unsol_buf, msg, len);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* AVB support */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "../aecp.h"
|
||||||
|
#include "../aecp-aem.h"
|
||||||
|
#include "../aecp-aem-state.h"
|
||||||
|
#include "../aecp-aem-descriptors.h"
|
||||||
|
#include "../aecp-aem-types.h"
|
||||||
|
|
||||||
|
#include "cmd-get-set-stream-format.h"
|
||||||
|
#include "cmd-resp-helpers.h"
|
||||||
|
#include "reply-unsol-helpers.h"
|
||||||
|
|
||||||
|
static int send_unsol_stream_format(struct aecp *aecp, void *msg, int len)
|
||||||
|
{
|
||||||
|
struct avb_ethernet_header *h_unsol = (void*)msg;
|
||||||
|
struct avb_packet_aecp_aem *p_unsol = SPA_PTROFF(h_unsol, sizeof(*h_unsol), void);
|
||||||
|
struct aecp_aem_base_info info = { 0 };
|
||||||
|
|
||||||
|
/* Set the originator controller ID to avoid echo */
|
||||||
|
info.controller_entity_id = htobe64(p_unsol->aecp.controller_guid);
|
||||||
|
info.expire_timeout = INT64_MAX;
|
||||||
|
|
||||||
|
return reply_unsolicited_notifications(aecp, &info, msg, len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \see IEEE 1722.1-2021 7.4.10
|
||||||
|
* \see Milan V1.2 5.4.2.8 GET_STREAM_FORMAT
|
||||||
|
*/
|
||||||
|
int handle_cmd_get_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len)
|
||||||
|
{
|
||||||
|
uint8_t buf[2048];
|
||||||
|
struct server *server = aecp->server;
|
||||||
|
const struct avb_ethernet_header *h = m;
|
||||||
|
const struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||||
|
const struct avb_packet_aecp_aem_setget_stream_format *get_cmd;
|
||||||
|
struct avb_ethernet_header *h_reply;
|
||||||
|
struct avb_packet_aecp_aem *p_reply;
|
||||||
|
struct avb_packet_aecp_aem_setget_stream_format *get_reply;
|
||||||
|
struct descriptor *desc;
|
||||||
|
struct avb_aem_desc_stream *stream_desc;
|
||||||
|
uint16_t desc_type, desc_id;
|
||||||
|
|
||||||
|
get_cmd = (const struct avb_packet_aecp_aem_setget_stream_format *)p->payload;
|
||||||
|
desc_type = ntohs(get_cmd->descriptor_type);
|
||||||
|
desc_id = ntohs(get_cmd->descriptor_id);
|
||||||
|
|
||||||
|
desc = server_find_descriptor(server, desc_type, desc_id);
|
||||||
|
if (desc == NULL)
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||||
|
|
||||||
|
if (desc_type != AVB_AEM_DESC_STREAM_INPUT &&
|
||||||
|
desc_type != AVB_AEM_DESC_STREAM_OUTPUT)
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||||
|
|
||||||
|
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
|
||||||
|
|
||||||
|
memcpy(buf, m, len);
|
||||||
|
h_reply = (struct avb_ethernet_header *)buf;
|
||||||
|
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||||
|
get_reply = (struct avb_packet_aecp_aem_setget_stream_format *)p_reply->payload;
|
||||||
|
|
||||||
|
get_reply->stream_format = stream_desc->current_format;
|
||||||
|
|
||||||
|
return reply_success(aecp, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \see IEEE 1722.1-2021 7.4.9
|
||||||
|
* \see Milan V1.2 5.4.2.7 SET_STREAM_FORMAT
|
||||||
|
*/
|
||||||
|
int handle_cmd_set_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len)
|
||||||
|
{
|
||||||
|
uint8_t buf[2048];
|
||||||
|
struct server *server = aecp->server;
|
||||||
|
const struct avb_ethernet_header *h = m;
|
||||||
|
const struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||||
|
const struct avb_packet_aecp_aem_setget_stream_format *set_cmd;
|
||||||
|
struct avb_ethernet_header *h_reply;
|
||||||
|
struct avb_packet_aecp_aem *p_reply;
|
||||||
|
struct avb_packet_aecp_aem_setget_stream_format *set_reply;
|
||||||
|
struct descriptor *desc;
|
||||||
|
struct avb_aem_desc_stream *stream_desc;
|
||||||
|
uint16_t desc_type, desc_id;
|
||||||
|
uint64_t new_format;
|
||||||
|
int i;
|
||||||
|
int rc;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
set_cmd = (const struct avb_packet_aecp_aem_setget_stream_format *)p->payload;
|
||||||
|
desc_type = ntohs(set_cmd->descriptor_type);
|
||||||
|
desc_id = ntohs(set_cmd->descriptor_id);
|
||||||
|
new_format = set_cmd->stream_format;
|
||||||
|
|
||||||
|
desc = server_find_descriptor(server, desc_type, desc_id);
|
||||||
|
if (desc == NULL)
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||||
|
|
||||||
|
if (desc_type == AVB_AEM_DESC_STREAM_INPUT) {
|
||||||
|
struct aecp_aem_stream_input_state *state =
|
||||||
|
(struct aecp_aem_stream_input_state *)desc->ptr;
|
||||||
|
stream = &state->stream;
|
||||||
|
// TODO check if the stream is bound
|
||||||
|
} else if (desc_type == AVB_AEM_DESC_STREAM_OUTPUT) {
|
||||||
|
struct aecp_aem_stream_output_state *state =
|
||||||
|
(struct aecp_aem_stream_output_state *)desc->ptr;
|
||||||
|
stream = &state->stream;
|
||||||
|
// TODO check if the stream is STREAM_RUNNING
|
||||||
|
} else {
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
|
||||||
|
for (i = 0; i < ntohs(stream_desc->number_of_formats); i++) {
|
||||||
|
if (stream_desc->stream_formats[i] == new_format) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memcpy(buf, m, len);
|
||||||
|
h_reply = (struct avb_ethernet_header *)buf;
|
||||||
|
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||||
|
set_reply = (struct avb_packet_aecp_aem_setget_stream_format*)p_reply->payload;
|
||||||
|
|
||||||
|
/** If this not found, return the current format */
|
||||||
|
if (!found) {
|
||||||
|
set_reply->stream_format = stream_desc->current_format;
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_desc->current_format = new_format;
|
||||||
|
rc = reply_success(aecp, buf, len);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return send_unsol_stream_format(aecp, buf, len);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* AVB support */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#ifndef __AVB_AECP_AEM_CMD_GET_SET_STREAM_FORMAT_H__
|
||||||
|
#define __AVB_AECP_AEM_CMD_GET_SET_STREAM_FORMAT_H__
|
||||||
|
|
||||||
|
#include "../aecp-aem.h"
|
||||||
|
|
||||||
|
int handle_cmd_set_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len);
|
||||||
|
|
||||||
|
int handle_cmd_get_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len);
|
||||||
|
|
||||||
|
#endif //__AVB_AECP_AEM_CMD_GET_SET_STREAM_FORMAT_H__
|
||||||
|
|
@ -10,10 +10,11 @@
|
||||||
|
|
||||||
/* The headers including the command and response of the system */
|
/* The headers including the command and response of the system */
|
||||||
#include "aecp-aem-cmds-resps/cmd-available.h"
|
#include "aecp-aem-cmds-resps/cmd-available.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-lock-entity.h"
|
|
||||||
#include "aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.h"
|
#include "aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.h"
|
#include "aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-get-set-name.h"
|
#include "aecp-aem-cmds-resps/cmd-get-set-name.h"
|
||||||
|
#include "aecp-aem-cmds-resps/cmd-get-set-stream-format.h"
|
||||||
|
#include "aecp-aem-cmds-resps/cmd-lock-entity.h"
|
||||||
|
|
||||||
|
|
||||||
/* ACQUIRE_ENTITY */
|
/* ACQUIRE_ENTITY */
|
||||||
|
|
@ -293,6 +294,12 @@ static const struct cmd_info cmd_info_milan_v12[] = {
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_ENTITY_AVAILABLE, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_ENTITY_AVAILABLE, true,
|
||||||
handle_cmd_entity_available_milan_v12),
|
handle_cmd_entity_available_milan_v12),
|
||||||
|
|
||||||
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_SET_STREAM_FORMAT, false,
|
||||||
|
handle_cmd_set_stream_format_milan_v12),
|
||||||
|
|
||||||
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_GET_STREAM_FORMAT, true,
|
||||||
|
handle_cmd_get_stream_format_milan_v12),
|
||||||
|
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
||||||
handle_read_descriptor_common),
|
handle_read_descriptor_common),
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue