History

avformat/udp: make recv addr of each packet available

Timo Rothenpieler committed 1 year ago

Commit af04a271 parent 2c7e1172 files · +36 −18Browse files

Unified · Split

2 files
  1. libavformat/network.h +2 −0
  2. libavformat/udp.c +34 −18
libavformat/network.h+2−0
@@ -338,4 +338,6 @@ int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address, · 337 unmodified lines
338338 int parallel, URLContext *h, int *fd,
339339 int (*customize_fd)(void *, int, int), void *customize_ctx);
340340
341+void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len);
342+
341343 #endif /* AVFORMAT_NETWORK_H */
libavformat/udp.c+34−18
@@ -78,6 +78,12 @@ · 77 unmodified lines
7878 #define UDP_MAX_PKT_SIZE 65536
7979 #define UDP_HEADER_SIZE 8
8080
81+typedef struct UDPQueuedPacketHeader {
82+ int pkt_size;
83+ struct sockaddr_storage addr;
84+ socklen_t addr_len;
85+} UDPQueuedPacketHeader;
86+
8187 typedef struct UDPContext {
8288 const AVClass *class;
8389 int udp_fd;
@@ -107,7 +113,7 @@ typedef struct UDPContext { · 23 unmodified lines
107113 pthread_cond_t cond;
108114 int thread_started;
109115 #endif
110− uint8_t tmp[UDP_MAX_PKT_SIZE+4];
116+ uint8_t tmp[UDP_MAX_PKT_SIZE + sizeof(UDPQueuedPacketHeader)];
111117 int remaining_in_dg;
112118 char *localaddr;
113119 int timeout;
@@ -115,6 +121,8 @@ typedef struct UDPContext { · 1 unmodified line
115121 char *sources;
116122 char *block;
117123 IPSourceFilters filters;
124+ struct sockaddr_storage last_recv_addr;
125+ socklen_t last_recv_addr_len;
118126 } UDPContext;
119127
120128 #define OFFSET(x) offsetof(UDPContext, x)
@@ -467,6 +475,13 @@ int ff_udp_get_local_port(URLContext *h) · 346 unmodified lines
467475 return s->local_port;
468476 }
469477
478+void ff_udp_get_last_recv_addr(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len)
479+{
480+ UDPContext *s = h->priv_data;
481+ *addr = s->last_recv_addr;
482+ *addr_len = s->last_recv_addr_len;
483+}
484+
470485 /**
471486 * Return the udp file handle for select() usage to wait for several RTP
472487 * streams at the same time.
@@ -495,30 +510,28 @@ static void *circular_buffer_task_rx( void *_URLContext) · 22 unmodified lines
495510 goto end;
496511 }
497512 while(1) {
498− int len;
499− struct sockaddr_storage addr;
500− socklen_t addr_len = sizeof(addr);
513+ UDPQueuedPacketHeader pkt_header;
501514
502515 pthread_mutex_unlock(&s->mutex);
503516 /* Blocking operations are always cancellation points;
504517 see "General Information" / "Thread Cancelation Overview"
505518 in Single Unix. */
506519 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
507− len = recvfrom(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0, (struct sockaddr *)&addr, &addr_len);
520+ pkt_header.pkt_size = recvfrom(s->udp_fd, s->tmp + sizeof(pkt_header), sizeof(s->tmp) - sizeof(pkt_header), 0, (struct sockaddr *)&pkt_header.addr, &pkt_header.addr_len);
508521 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
509522 pthread_mutex_lock(&s->mutex);
510− if (len < 0) {
523+ if (pkt_header.pkt_size < 0) {
511524 if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
512525 s->circular_buffer_error = ff_neterrno();
513526 goto end;
514527 }
515528 continue;
516529 }
517− if (ff_ip_check_source_lists(&addr, &s->filters))
530+ if (ff_ip_check_source_lists(&pkt_header.addr, &s->filters))
518531 continue;
519− AV_WL32(s->tmp, len);
532+ memcpy(s->tmp, &pkt_header, sizeof(pkt_header));
520533
521− if (av_fifo_can_write(s->fifo) < len + 4) {
534+ if (av_fifo_can_write(s->fifo) < pkt_header.pkt_size + sizeof(pkt_header)) {
522535 /* No Space left */
523536 if (s->overrun_nonfatal) {
524537 av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
@@ -532,7 +545,7 @@ static void *circular_buffer_task_rx( void *_URLContext) · 7 unmodified lines
532545 goto end;
533546 }
534547 }
535− av_fifo_write(s->fifo, s->tmp, len + 4);
548+ av_fifo_write(s->fifo, s->tmp, pkt_header.pkt_size + sizeof(pkt_header));
536549 pthread_cond_signal(&s->cond);
537550 }
538551
@@ -991,8 +1004,6 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) · 452 unmodified lines
9911004 {
9921005 UDPContext *s = h->priv_data;
9931006 int ret;
994− struct sockaddr_storage addr;
995− socklen_t addr_len = sizeof(addr);
9961007 #if HAVE_PTHREAD_CANCEL
9971008 int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
9981009
@@ -1001,17 +1012,21 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) · 2 unmodified lines
10011012 do {
10021013 avail = av_fifo_can_read(s->fifo);
10031014 if (avail) { // >=size) {
1004− uint8_t tmp[4];
1015+ UDPQueuedPacketHeader header;
1016+
1017+ av_fifo_read(s->fifo, &header, sizeof(header));
1018+
1019+ s->last_recv_addr = header.addr;
1020+ s->last_recv_addr_len = header.addr_len;
10051021
1006− av_fifo_read(s->fifo, tmp, 4);
1007− avail = AV_RL32(tmp);
1022+ avail = header.pkt_size;
10081023 if(avail > size){
10091024 av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
10101025 avail = size;
10111026 }
10121027
10131028 av_fifo_read(s->fifo, buf, avail);
1014− av_fifo_drain2(s->fifo, AV_RL32(tmp) - avail);
1029+ av_fifo_drain2(s->fifo, header.pkt_size - avail);
10151030 pthread_mutex_unlock(&s->mutex);
10161031 return avail;
10171032 } else if(s->circular_buffer_error){
@@ -1043,10 +1058,11 @@ static int udp_read(URLContext *h, uint8_t *buf, int size) · 25 unmodified lines
10431058 if (ret < 0)
10441059 return ret;
10451060 }
1046− ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&addr, &addr_len);
1061+ s->last_recv_addr_len = sizeof(s->last_recv_addr);
1062+ ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&s->last_recv_addr, &s->last_recv_addr_len);
10471063 if (ret < 0)
10481064 return ff_neterrno();
1049− if (ff_ip_check_source_lists(&addr, &s->filters))
1065+ if (ff_ip_check_source_lists(&s->last_recv_addr, &s->filters))
10501066 return AVERROR(EINTR);
10511067 return ret;
10521068 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t