]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtpproto.c
rtspenc: Check the return value from ffio_open_dyn_packet_buf
[ffmpeg] / libavformat / rtpproto.c
index 024c69ba595f98fce647e6162d0e9a09f549dcc6..974aa351a5194a7c8abd0371e088b31ef4aefd5b 100644 (file)
@@ -28,7 +28,8 @@
 #include "libavutil/avstring.h"
 #include "avformat.h"
 #include "avio_internal.h"
-#include "rtpdec.h"
+#include "rtp.h"
+#include "rtpproto.h"
 #include "url.h"
 
 #include <stdarg.h>
@@ -60,18 +61,27 @@ int ff_rtp_set_remote_url(URLContext *h, const char *uri)
 {
     RTPContext *s = h->priv_data;
     char hostname[256];
-    int port;
+    int port, rtcp_port;
+    const char *p;
 
     char buf[1024];
     char path[1024];
 
     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port,
                  path, sizeof(path), uri);
+    rtcp_port = port + 1;
+
+    p = strchr(uri, '?');
+    if (p) {
+        if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
+            rtcp_port = strtol(buf, NULL, 10);
+        }
+    }
 
     ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port, "%s", path);
     ff_udp_set_remote_url(s->rtp_hd, buf);
 
-    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, port + 1, "%s", path);
+    ff_url_join(buf, sizeof(buf), "udp", NULL, hostname, rtcp_port, "%s", path);
     ff_udp_set_remote_url(s->rtcp_hd, buf);
     return 0;
 }
@@ -324,35 +334,21 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
     RTPContext *s = h->priv_data;
     struct sockaddr_storage from;
     socklen_t from_len;
-    int len, n;
+    int len, n, i;
     struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}};
     int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100;
 
     for(;;) {
         if (ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
-        /* build fdset to listen to RTP and RTCP packets */
         n = poll(p, 2, poll_delay);
         if (n > 0) {
-            /* first try RTCP */
-            if (p[1].revents & POLLIN) {
-                from_len = sizeof(from);
-                len = recvfrom (s->rtcp_fd, buf, size, 0,
-                                (struct sockaddr *)&from, &from_len);
-                if (len < 0) {
-                    if (ff_neterrno() == AVERROR(EAGAIN) ||
-                        ff_neterrno() == AVERROR(EINTR))
-                        continue;
-                    return AVERROR(EIO);
-                }
-                if (rtp_check_source_lists(s, &from))
+            /* first try RTCP, then RTP */
+            for (i = 1; i >= 0; i--) {
+                if (!(p[i].revents & POLLIN))
                     continue;
-                break;
-            }
-            /* then RTP */
-            if (p[0].revents & POLLIN) {
                 from_len = sizeof(from);
-                len = recvfrom (s->rtp_fd, buf, size, 0,
+                len = recvfrom(p[i].fd, buf, size, 0,
                                 (struct sockaddr *)&from, &from_len);
                 if (len < 0) {
                     if (ff_neterrno() == AVERROR(EAGAIN) ||
@@ -362,7 +358,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
                 }
                 if (rtp_check_source_lists(s, &from))
                     continue;
-                break;
+                return len;
             }
         } else if (n < 0) {
             if (ff_neterrno() == AVERROR(EINTR))
@@ -381,6 +377,9 @@ static int rtp_write(URLContext *h, const uint8_t *buf, int size)
     int ret;
     URLContext *hd;
 
+    if (size < 2)
+        return AVERROR(EINVAL);
+
     if (RTP_PT_IS_RTCP(buf[1])) {
         /* RTCP payload type */
         hd = s->rtcp_hd;