]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtsp.c
Parse ID3 tags in Musepack SV7 files
[ffmpeg] / libavformat / rtsp.c
index 9a4b1e2c490597ed3b565ae54a0d074d802d6b83..320d45ce7f12d870592577b6ff51df3fd35600c1 100644 (file)
@@ -339,9 +339,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
     struct in_addr sdp_ip;
     int ttl;
 
-#ifdef DEBUG
-    printf("sdp: %c='%s'\n", letter, buf);
-#endif
+    dprintf(s, "sdp: %c='%s'\n", letter, buf);
 
     p = buf;
     if (s1->skip_media && letter != 'm')
@@ -702,23 +700,12 @@ void rtsp_parse_line(RTSPMessageHeader *reply, const char *buf)
     } else if (av_stristart(p, "Server:", &p)) {
         skip_spaces(&p);
         av_strlcpy(reply->server, p, sizeof(reply->server));
+    } else if (av_stristart(p, "Notice:", &p) ||
+               av_stristart(p, "X-Notice:", &p)) {
+        reply->notice = strtol(p, NULL, 10);
     }
 }
 
-static int url_readbuf(URLContext *h, unsigned char *buf, int size)
-{
-    int ret, len;
-
-    len = 0;
-    while (len < size) {
-        ret = url_read(h, buf+len, size-len);
-        if (ret < 1)
-            return ret;
-        len += ret;
-    }
-    return len;
-}
-
 /* skip a RTP/TCP interleaved packet */
 static void rtsp_skip_packet(AVFormatContext *s)
 {
@@ -726,19 +713,19 @@ static void rtsp_skip_packet(AVFormatContext *s)
     int ret, len, len1;
     uint8_t buf[1024];
 
-    ret = url_readbuf(rt->rtsp_hd, buf, 3);
+    ret = url_read_complete(rt->rtsp_hd, buf, 3);
     if (ret != 3)
         return;
     len = AV_RB16(buf + 1);
-#ifdef DEBUG
-    printf("skipping RTP packet len=%d\n", len);
-#endif
+
+    dprintf(s, "skipping RTP packet len=%d\n", len);
+
     /* skip payload */
     while (len > 0) {
         len1 = len;
         if (len1 > sizeof(buf))
             len1 = sizeof(buf);
-        ret = url_readbuf(rt->rtsp_hd, buf, len1);
+        ret = url_read_complete(rt->rtsp_hd, buf, len1);
         if (ret != len1)
             return;
         len -= len1;
@@ -784,9 +771,9 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
     for(;;) {
         q = buf;
         for(;;) {
-            ret = url_readbuf(rt->rtsp_hd, &ch, 1);
+            ret = url_read_complete(rt->rtsp_hd, &ch, 1);
 #ifdef DEBUG_RTP_TCP
-            printf("ret=%d c=%02x [%c]\n", ret, ch, ch);
+            dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
 #endif
             if (ret != 1)
                 return -1;
@@ -804,9 +791,9 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
             }
         }
         *q = '\0';
-#ifdef DEBUG
-        printf("line='%s'\n", buf);
-#endif
+
+        dprintf(s, "line='%s'\n", buf);
+
         /* test if last line */
         if (buf[0] == '\0')
             break;
@@ -831,7 +818,7 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
     if (content_length > 0) {
         /* leave some room for a trailing '\0' (useful for simple parsing) */
         content = av_malloc(content_length + 1);
-        (void)url_readbuf(rt->rtsp_hd, content, content_length);
+        (void)url_read_complete(rt->rtsp_hd, content, content_length);
         content[content_length] = '\0';
     }
     if (content_ptr)
@@ -839,6 +826,17 @@ rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,
     else
         av_free(content);
 
+    /* EOS */
+    if (reply->notice == 2101 /* End-of-Stream Reached */      ||
+        reply->notice == 2104 /* Start-of-Stream Reached */    ||
+        reply->notice == 2306 /* Continuous Feed Terminated */)
+        rt->state = RTSP_STATE_IDLE;
+    else if (reply->notice >= 4400 && reply->notice < 5500)
+        return AVERROR(EIO); /* data or server error */
+    else if (reply->notice == 2401 /* Ticket Expired */ ||
+             (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
+        return AVERROR(EPERM);
+
     return 0;
 }
 
@@ -858,9 +856,9 @@ static void rtsp_send_cmd_async (AVFormatContext *s,
         av_strlcat(buf, buf1, sizeof(buf));
     }
     av_strlcat(buf, "\r\n", sizeof(buf));
-#ifdef DEBUG
-    printf("Sending:\n%s--\n", buf);
-#endif
+
+    dprintf(s, "Sending:\n%s--\n", buf);
+
     url_write(rt->rtsp_hd, buf, strlen(buf));
     rt->last_cmd_time = av_gettime();
 }
@@ -1318,7 +1316,7 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
     RTSPStream *rtsp_st;
 
 #ifdef DEBUG_RTP_TCP
-    printf("tcp_read_packet:\n");
+    dprintf(s, "tcp_read_packet:\n");
 #endif
  redo:
     for(;;) {
@@ -1330,19 +1328,21 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
         if (ret == 1) /* received '$' */
             break;
         /* XXX: parse message */
+        if (rt->state != RTSP_STATE_PLAYING)
+            return 0;
     }
-    ret = url_readbuf(rt->rtsp_hd, buf, 3);
+    ret = url_read_complete(rt->rtsp_hd, buf, 3);
     if (ret != 3)
         return -1;
     id = buf[0];
     len = AV_RB16(buf + 1);
 #ifdef DEBUG_RTP_TCP
-    printf("id=%d len=%d\n", id, len);
+    dprintf(s, "id=%d len=%d\n", id, len);
 #endif
     if (len > buf_size || len < 12)
         goto redo;
     /* get the data */
-    ret = url_readbuf(rt->rtsp_hd, buf, len);
+    ret = url_read_complete(rt->rtsp_hd, buf, len);
     if (ret != len)
         return -1;
     if (rt->transport == RTSP_TRANSPORT_RDT &&
@@ -1375,8 +1375,13 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
         if (url_interrupt_cb())
             return AVERROR(EINTR);
         FD_ZERO(&rfds);
-        tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
-        FD_SET(tcp_fd, &rfds);
+        if (rt->rtsp_hd) {
+            tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
+            FD_SET(tcp_fd, &rfds);
+        } else {
+            fd_max = 0;
+            tcp_fd = -1;
+        }
         for(i = 0; i < rt->nb_rtsp_streams; i++) {
             rtsp_st = rt->rtsp_streams[i];
             if (rtsp_st->rtp_handle) {
@@ -1410,6 +1415,8 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
 
                 rtsp_read_reply(s, &reply, NULL, 0);
                 /* XXX: parse message */
+                if (rt->state != RTSP_STATE_PLAYING)
+                    return 0;
             }
         }
     }
@@ -1517,6 +1524,8 @@ static int rtsp_read_packet(AVFormatContext *s,
     }
     if (len < 0)
         return len;
+    if (len == 0)
+        return AVERROR_EOF;
     if (rt->transport == RTSP_TRANSPORT_RDT)
         ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
     else
@@ -1610,6 +1619,9 @@ static int rtsp_read_seek(AVFormatContext *s, int stream_index,
     case RTSP_STATE_IDLE:
         break;
     case RTSP_STATE_PLAYING:
+        if (rtsp_read_pause(s) != 0)
+            return -1;
+        rt->state = RTSP_STATE_SEEKING;
         if (rtsp_read_play(s) != 0)
             return -1;
         break;