RTSP: Add a second URLContext for outgoing messages
authorJosh Allmann <joshua.allmann@gmail.com>
Sat, 5 Jun 2010 19:41:43 +0000 (19:41 +0000)
committerMartin Storsjö <martin@martin.st>
Sat, 5 Jun 2010 19:41:43 +0000 (19:41 +0000)
Done in preparation for RTSP over HTTP.
Patch by Josh Allmann, joshua dot allmann at gmail

Originally committed as revision 23494 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/rtsp.c
libavformat/rtsp.h
libavformat/rtspenc.c

index 6dbd796..abbb75a 100644 (file)
@@ -1032,9 +1032,9 @@ void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
 
     dprintf(s, "Sending:\n%s--\n", buf);
 
-    url_write(rt->rtsp_hd, buf, strlen(buf));
+    url_write(rt->rtsp_hd_out, buf, strlen(buf));
     if (send_content_length > 0 && send_content)
-        url_write(rt->rtsp_hd, send_content, send_content_length);
+        url_write(rt->rtsp_hd_out, send_content, send_content_length);
     rt->last_cmd_time = av_gettime();
 }
 
@@ -1454,12 +1454,19 @@ static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
     return 0;
 }
 
+void ff_rtsp_close_connections(AVFormatContext *s)
+{
+    RTSPState *rt = s->priv_data;
+    if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out);
+    url_close(rt->rtsp_hd);
+}
+
 int ff_rtsp_connect(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
     char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
     char *option_list, *option, *filename;
-    URLContext *rtsp_hd;
+    URLContext *rtsp_hd, *rtsp_hd_out;
     int port, err, tcp_fd;
     RTSPMessageHeader reply1 = {}, *reply = &reply1;
     int lower_transport_mask = 0;
@@ -1538,7 +1545,9 @@ redirect:
         err = AVERROR(EIO);
         goto fail;
     }
+    rtsp_hd_out = rtsp_hd;
     rt->rtsp_hd = rtsp_hd;
+    rt->rtsp_hd_out = rtsp_hd_out;
     rt->seq = 0;
 
     tcp_fd = url_get_file_handle(rtsp_hd);
@@ -1612,7 +1621,7 @@ redirect:
     return 0;
  fail:
     ff_rtsp_close_streams(s);
-    url_close(rt->rtsp_hd);
+    ff_rtsp_close_connections(s);
     if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
         av_strlcpy(s->filename, reply->location, sizeof(s->filename));
         av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
@@ -1641,7 +1650,7 @@ static int rtsp_read_header(AVFormatContext *s,
     } else {
          if (rtsp_read_play(s) < 0) {
             ff_rtsp_close_streams(s);
-            url_close(rt->rtsp_hd);
+            ff_rtsp_close_connections(s);
             return AVERROR_INVALIDDATA;
         }
     }
@@ -1986,7 +1995,7 @@ static int rtsp_read_close(AVFormatContext *s)
     ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
 
     ff_rtsp_close_streams(s);
-    url_close(rt->rtsp_hd);
+    ff_rtsp_close_connections(s);
     ff_network_close();
     return 0;
 }
index 342f825..9d8e53b 100644 (file)
@@ -278,6 +278,10 @@ typedef struct RTSPState {
 
     /** The synchronized start time of the output streams. */
     int64_t start_time;
+
+    /** Additional output handle, used when input and output are done
+     * separately, eg for HTTP tunneling. */
+    URLContext *rtsp_hd_out;
 } RTSPState;
 
 /**
@@ -434,4 +438,11 @@ int ff_rtsp_connect(AVFormatContext *s);
  */
 void ff_rtsp_close_streams(AVFormatContext *s);
 
+/**
+ * Close all connection handles within the RTSP (de)muxer
+ *
+ * @param rt RTSP (de)muxer context
+ */
+void ff_rtsp_close_connections(AVFormatContext *rt);
+
 #endif /* AVFORMAT_RTSP_H */
index 0761783..7dc6a83 100644 (file)
@@ -57,7 +57,7 @@ static int rtsp_write_header(AVFormatContext *s)
 
     if (rtsp_write_record(s) < 0) {
         ff_rtsp_close_streams(s);
-        url_close(rt->rtsp_hd);
+        ff_rtsp_close_connections(s);
         return AVERROR_INVALIDDATA;
     }
     return 0;
@@ -162,7 +162,7 @@ static int rtsp_write_close(AVFormatContext *s)
     ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
 
     ff_rtsp_close_streams(s);
-    url_close(rt->rtsp_hd);
+    ff_rtsp_close_connections(s);
     ff_network_close();
     return 0;
 }