Implement RAOP retransmission

This commit is contained in:
Julien BLACHE 2010-10-05 20:19:08 +02:00
parent 10a0b16573
commit 3abf62179e

View File

@ -2227,6 +2227,10 @@ raop_v2_control_send_sync(uint64_t next_pkt, struct timespec *init)
}
}
/* Forward */
static void
raop_v2_resend_range(struct raop_session *rs, uint16_t seqnum, uint16_t len);
static void
raop_v2_control_cb(int fd, short what, void *arg)
{
@ -2322,6 +2326,8 @@ raop_v2_control_cb(int fd, short what, void *arg)
DPRINTF(E_DBG, L_RAOP, "Got retransmit request, seq_start %u len %u\n", seq_start, seq_len);
raop_v2_resend_range(rs, seq_start, seq_len);
readd:
ret = event_add(&svc->ev, NULL);
if (ret < 0)
@ -2656,6 +2662,68 @@ raop_v2_write(uint8_t *buf, uint64_t rtptime)
return;
}
static void
raop_v2_resend_range(struct raop_session *rs, uint16_t seqnum, uint16_t len)
{
struct raop_v2_packet *pktbuf;
int ret;
uint16_t distance;
/* Check that seqnum is in the retransmit buffer */
if ((seqnum > pktbuf_head->seqnum) && (seqnum < pktbuf_tail->seqnum))
{
DPRINTF(E_LOG, L_RAOP, "RAOP device %s asking for seqnum %u; not in buffer (h %u t %u)\n", rs->devname, seqnum, pktbuf_head->seqnum, pktbuf_tail->seqnum);
return;
}
if (seqnum > pktbuf_head->seqnum)
{
distance = seqnum - pktbuf_tail->seqnum;
if (distance > (RETRANSMIT_BUFFER_SIZE / 2))
pktbuf = pktbuf_head;
else
pktbuf = pktbuf_tail;
}
else
{
distance = pktbuf_head->seqnum - seqnum;
if (distance > (RETRANSMIT_BUFFER_SIZE / 2))
pktbuf = pktbuf_tail;
else
pktbuf = pktbuf_head;
}
if (pktbuf == pktbuf_head)
{
while (seqnum != pktbuf->seqnum)
pktbuf = pktbuf->next;
}
else
{
while (seqnum != pktbuf->seqnum)
pktbuf = pktbuf->prev;
}
while (len && pktbuf)
{
ret = raop_v2_send_packet(rs, pktbuf);
if (ret < 0)
{
DPRINTF(E_LOG, L_RAOP, "Error retransmit packet, aborting retransmission\n");
return;
}
pktbuf = pktbuf->prev;
len--;
}
if (len != 0)
DPRINTF(E_LOG, L_RAOP, "WARNING: len non-zero at end of retransmission\n");
}
static int
raop_v2_stream_open(struct raop_session *rs)
{