mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
module-rtp: fix sender timestamps
This commit is contained in:
parent
7c04b42e38
commit
dda5ed696b
3 changed files with 78 additions and 23 deletions
|
|
@ -279,8 +279,8 @@ static void send_apple_midi_cmd_in(struct session *sess, bool ctrl)
|
|||
|
||||
iov[0].iov_base = &hdr;
|
||||
iov[0].iov_len = sizeof(hdr);
|
||||
iov[1].iov_base = sess->name;
|
||||
iov[1].iov_len = strlen(sess->name);
|
||||
iov[1].iov_base = impl->session_name;
|
||||
iov[1].iov_len = strlen(impl->session_name)+1;
|
||||
|
||||
spa_zero(msg);
|
||||
msg.msg_name = ctrl ? &sess->ctrl_addr : &sess->data_addr;
|
||||
|
|
@ -476,6 +476,7 @@ static struct session *find_session_by_addr_name(struct impl *impl,
|
|||
{
|
||||
struct session *sess;
|
||||
spa_list_for_each(sess, &impl->sessions, link) {
|
||||
pw_log_info("'%s' '%s'", sess->name, name);
|
||||
if (cmp_ip(sa, &sess->ctrl_addr) &&
|
||||
spa_streq(sess->name, name))
|
||||
return sess;
|
||||
|
|
@ -511,10 +512,13 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
|||
struct rtp_apple_midi reply;
|
||||
struct session *sess;
|
||||
bool success = true;
|
||||
uint32_t initiator = ntohl(hdr->initiator);
|
||||
uint32_t initiator, ssrc;
|
||||
char addr[128];
|
||||
uint16_t port = 0;
|
||||
|
||||
initiator = ntohl(hdr->initiator);
|
||||
ssrc = ntohl(hdr->ssrc);
|
||||
|
||||
get_ip(sa, addr, sizeof(addr), &port);
|
||||
pw_log_info("IN from %s:%d %s", addr, port, hdr->name);
|
||||
|
||||
|
|
@ -529,13 +533,14 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
|||
success = false;
|
||||
}
|
||||
} else {
|
||||
struct pw_properties *props;
|
||||
|
||||
props = pw_properties_new("sess.name", hdr->name, NULL);
|
||||
pw_properties_setf(props, "rtp.initiator", "%u", initiator);
|
||||
pw_properties_setf(props, "rtp.receiver-ssrc", "%u", ssrc);
|
||||
|
||||
pw_log_info("got control IN request %08x", initiator);
|
||||
sess = make_session(impl,
|
||||
pw_properties_new(
|
||||
"sess.name", hdr->name,
|
||||
"rtp.initiator", initiator,
|
||||
"rtp.receiver-ssrc", ntohl(hdr->ssrc),
|
||||
NULL));
|
||||
sess = make_session(impl, props);
|
||||
if (sess == NULL) {
|
||||
pw_log_warn("failed to make session: %m");
|
||||
success = false;
|
||||
|
|
@ -553,6 +558,7 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
|||
success = false;
|
||||
} else {
|
||||
pw_log_info("got data IN request %08x", initiator);
|
||||
sess->remote_ssrc = ssrc;
|
||||
sess->data_addr = *sa;
|
||||
sess->data_len = salen;
|
||||
sess->data_ready = true;
|
||||
|
|
@ -568,8 +574,8 @@ static void parse_apple_midi_cmd_in(struct impl *impl, bool ctrl, uint8_t *buffe
|
|||
|
||||
iov[0].iov_base = &reply;
|
||||
iov[0].iov_len = sizeof(reply);
|
||||
iov[1].iov_base = sess->name;
|
||||
iov[1].iov_len = strlen(sess->name);
|
||||
iov[1].iov_base = impl->session_name;
|
||||
iov[1].iov_len = strlen(impl->session_name)+1;
|
||||
|
||||
spa_zero(msg);
|
||||
msg.msg_name = sa;
|
||||
|
|
@ -602,6 +608,7 @@ static void parse_apple_midi_cmd_ok(struct impl *impl, bool ctrl, uint8_t *buffe
|
|||
send_apple_midi_cmd_in(sess, false);
|
||||
} else {
|
||||
pw_log_info("got data OK %08x", initiator);
|
||||
sess->remote_ssrc = ntohl(hdr->ssrc);
|
||||
sess->data_ready = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
src/modules/module-rtp/apple-midi.h
Normal file
43
src/modules/module-rtp/apple-midi.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* PipeWire */
|
||||
/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans <wim.taymans@gmail.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef PIPEWIRE_APPLE_MIDI_H
|
||||
#define PIPEWIRE_APPLE_MIDI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtp_apple_midi {
|
||||
uint32_t cmd;
|
||||
uint32_t protocol;
|
||||
uint32_t initiator;
|
||||
uint32_t ssrc;
|
||||
char name[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rtp_apple_midi_ck {
|
||||
uint32_t cmd;
|
||||
uint32_t ssrc;
|
||||
uint8_t count;
|
||||
uint8_t padding[3];
|
||||
uint32_t ts1_h;
|
||||
uint32_t ts1_l;
|
||||
uint32_t ts2_h;
|
||||
uint32_t ts2_l;
|
||||
uint32_t ts3_h;
|
||||
uint32_t ts3_l;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define APPLE_MIDI_CMD_IN ((0xffff << 16) | 'I'<<8 | 'N')
|
||||
#define APPLE_MIDI_CMD_NO ((0xffff << 16) | 'N'<<8 | 'O')
|
||||
#define APPLE_MIDI_CMD_OK ((0xffff << 16) | 'O'<<8 | 'K')
|
||||
#define APPLE_MIDI_CMD_CK ((0xffff << 16) | 'C'<<8 | 'K')
|
||||
#define APPLE_MIDI_CMD_BY ((0xffff << 16) | 'B'<<8 | 'Y')
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PIPEWIRE_APPLE_MIDI_H */
|
||||
|
|
@ -337,7 +337,7 @@ static int write_event(uint8_t *p, uint32_t value, void *ev, uint32_t size)
|
|||
}
|
||||
|
||||
static void flush_midi_packets(struct impl *impl,
|
||||
struct spa_pod_sequence *sequence, uint32_t timestamp)
|
||||
struct spa_pod_sequence *sequence, uint32_t timestamp, uint32_t rate)
|
||||
{
|
||||
struct spa_pod_control *c;
|
||||
struct rtp_header header;
|
||||
|
|
@ -363,7 +363,7 @@ static void flush_midi_packets(struct impl *impl,
|
|||
|
||||
SPA_POD_SEQUENCE_FOREACH(sequence, c) {
|
||||
void *ev;
|
||||
uint32_t size, delta;
|
||||
uint32_t size, delta, offset;
|
||||
|
||||
if (c->type != SPA_CONTROL_Midi)
|
||||
continue;
|
||||
|
|
@ -371,8 +371,10 @@ static void flush_midi_packets(struct impl *impl,
|
|||
ev = SPA_POD_BODY(&c->value),
|
||||
size = SPA_POD_BODY_SIZE(&c->value);
|
||||
|
||||
offset = c->offset * impl->rate / rate;
|
||||
|
||||
if (len > 0 && (len + size > impl->mtu ||
|
||||
c->offset - base > impl->psamples)) {
|
||||
offset - base > impl->psamples)) {
|
||||
/* flush packet when we have one and when it's either
|
||||
* too large or has too much data. */
|
||||
if (len < 16) {
|
||||
|
|
@ -389,7 +391,7 @@ static void flush_midi_packets(struct impl *impl,
|
|||
|
||||
pw_log_debug("sending %d timestamp:%d %u %u",
|
||||
len, timestamp + base,
|
||||
c->offset, impl->psamples);
|
||||
offset, impl->psamples);
|
||||
rtp_stream_emit_send_packet(impl, iov, 3);
|
||||
|
||||
impl->seq++;
|
||||
|
|
@ -397,15 +399,15 @@ static void flush_midi_packets(struct impl *impl,
|
|||
}
|
||||
if (len == 0) {
|
||||
/* start new packet */
|
||||
base = prev_offset = c->offset;
|
||||
base = prev_offset = offset;
|
||||
header.sequence_number = htons(impl->seq);
|
||||
header.timestamp = htonl(impl->ts_offset + timestamp + base);
|
||||
|
||||
memcpy(&impl->buffer[len], ev, size);
|
||||
len += size;
|
||||
} else {
|
||||
delta = c->offset - prev_offset;
|
||||
prev_offset = c->offset;
|
||||
delta = offset - prev_offset;
|
||||
prev_offset = offset;
|
||||
len += write_event(&impl->buffer[len], delta, ev, size);
|
||||
}
|
||||
}
|
||||
|
|
@ -434,7 +436,7 @@ static void process_midi_capture(void *data)
|
|||
struct impl *impl = data;
|
||||
struct pw_buffer *buf;
|
||||
struct spa_data *d;
|
||||
uint32_t offs, size, timestamp;
|
||||
uint32_t offs, size, timestamp, rate;
|
||||
struct spa_pod *pod;
|
||||
void *ptr;
|
||||
|
||||
|
|
@ -447,10 +449,13 @@ static void process_midi_capture(void *data)
|
|||
offs = SPA_MIN(d[0].chunk->offset, d[0].maxsize);
|
||||
size = SPA_MIN(d[0].chunk->size, d[0].maxsize - offs);
|
||||
|
||||
if (SPA_LIKELY(impl->io_position))
|
||||
timestamp = impl->io_position->clock.position;
|
||||
else
|
||||
if (SPA_LIKELY(impl->io_position)) {
|
||||
rate = impl->io_position->clock.rate.denom;
|
||||
timestamp = impl->io_position->clock.position * impl->rate / rate;
|
||||
} else {
|
||||
rate = 10000;
|
||||
timestamp = 0;
|
||||
}
|
||||
|
||||
ptr = SPA_PTROFF(d[0].data, offs, void);
|
||||
|
||||
|
|
@ -465,7 +470,7 @@ static void process_midi_capture(void *data)
|
|||
impl->have_sync = true;
|
||||
}
|
||||
|
||||
flush_midi_packets(impl, (struct spa_pod_sequence*)pod, timestamp);
|
||||
flush_midi_packets(impl, (struct spa_pod_sequence*)pod, timestamp, rate);
|
||||
|
||||
done:
|
||||
pw_stream_queue_buffer(impl->stream, buf);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue