Browse code

Add an RTSP muxer

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

Martin Storsjö authored on 2010/02/23 06:28:19
Showing 8 changed files
... ...
@@ -60,6 +60,7 @@ version <next>:
60 60
 - WMAVoice decoder
61 61
 - FFprobe tool
62 62
 - AMR-NB decoder
63
+- RTSP muxer
63 64
 
64 65
 
65 66
 
... ...
@@ -1351,6 +1351,8 @@ mxf_d10_muxer_select="mxf_muxer"
1351 1351
 ogg_demuxer_select="golomb"
1352 1352
 psp_muxer_select="mov_muxer"
1353 1353
 rtsp_demuxer_deps="sdp_demuxer"
1354
+rtsp_muxer_deps="sdp_demuxer"
1355
+rtsp_muxer_select="rtp_muxer"
1354 1356
 sdp_demuxer_deps="rtp_protocol mpegts_demuxer"
1355 1357
 spdif_muxer_select="aac_parser"
1356 1358
 tg2_muxer_select="mov_muxer"
... ...
@@ -210,7 +210,7 @@ library:
210 210
 @item RTMP                      @tab X @tab X
211 211
     @tab Output is performed by publishing stream to RTMP server
212 212
 @item RTP                       @tab   @tab X
213
-@item RTSP                      @tab   @tab X
213
+@item RTSP                      @tab X @tab X
214 214
 @item SDP                       @tab   @tab X
215 215
 @item Sega FILM/CPK             @tab   @tab X
216 216
     @tab Used in many Sega Saturn console games.
... ...
@@ -210,6 +210,7 @@ OBJS-$(CONFIG_RTP_MUXER)                 += rtp.o         \
210 210
                                             rtpenc_h264.o \
211 211
                                             avc.o
212 212
 OBJS-$(CONFIG_RTSP_DEMUXER)              += rtsp.o
213
+OBJS-$(CONFIG_RTSP_MUXER)                += rtsp.o rtspenc.o
213 214
 OBJS-$(CONFIG_SDP_DEMUXER)               += rtsp.o        \
214 215
                                             rdt.o         \
215 216
                                             rtp.o         \
... ...
@@ -172,7 +172,7 @@ void av_register_all(void)
172 172
     REGISTER_MUXDEMUX (ROQ, roq);
173 173
     REGISTER_DEMUXER  (RPL, rpl);
174 174
     REGISTER_MUXER    (RTP, rtp);
175
-    REGISTER_DEMUXER  (RTSP, rtsp);
175
+    REGISTER_MUXDEMUX (RTSP, rtsp);
176 176
     REGISTER_DEMUXER  (SDP, sdp);
177 177
 #if CONFIG_SDP_DEMUXER
178 178
     av_register_rtp_dynamic_payload_handlers();
... ...
@@ -22,7 +22,7 @@
22 22
 #define AVFORMAT_AVFORMAT_H
23 23
 
24 24
 #define LIBAVFORMAT_VERSION_MAJOR 52
25
-#define LIBAVFORMAT_VERSION_MINOR 52
25
+#define LIBAVFORMAT_VERSION_MINOR 53
26 26
 #define LIBAVFORMAT_VERSION_MICRO  0
27 27
 
28 28
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
... ...
@@ -691,7 +691,7 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
691 691
     return 0;
692 692
 }
693 693
 
694
-#if CONFIG_RTSP_DEMUXER
694
+#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
695 695
 static int rtsp_probe(AVProbeData *p)
696 696
 {
697 697
     if (av_strstart(p->filename, "rtsp:", NULL))
... ...
@@ -1533,7 +1533,9 @@ redirect:
1533 1533
     }
1534 1534
     return err;
1535 1535
 }
1536
+#endif
1536 1537
 
1538
+#if CONFIG_RTSP_DEMUXER
1537 1539
 static int rtsp_read_header(AVFormatContext *s,
1538 1540
                             AVFormatParameters *ap)
1539 1541
 {
1540 1542
new file mode 100644
... ...
@@ -0,0 +1,131 @@
0
+/*
1
+ * RTSP muxer
2
+ * Copyright (c) 2010 Martin Storsjo
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avformat.h"
22
+
23
+#include <sys/time.h>
24
+#if HAVE_SYS_SELECT_H
25
+#include <sys/select.h>
26
+#endif
27
+#include "network.h"
28
+#include "rtsp.h"
29
+
30
+static int rtsp_write_record(AVFormatContext *s)
31
+{
32
+    RTSPState *rt = s->priv_data;
33
+    RTSPMessageHeader reply1, *reply = &reply1;
34
+    char cmd[1024];
35
+
36
+    snprintf(cmd, sizeof(cmd),
37
+             "RECORD %s RTSP/1.0\r\n"
38
+             "Range: npt=%0.3f-\r\n",
39
+             s->filename,
40
+             (double) 0);
41
+    rtsp_send_cmd(s, cmd, reply, NULL);
42
+    if (reply->status_code != RTSP_STATUS_OK)
43
+        return -1;
44
+    rt->state = RTSP_STATE_STREAMING;
45
+    return 0;
46
+}
47
+
48
+static int rtsp_write_header(AVFormatContext *s)
49
+{
50
+    RTSPState *rt = s->priv_data;
51
+    int ret;
52
+
53
+    ret = rtsp_connect(s);
54
+    if (ret)
55
+        return ret;
56
+
57
+    if (rtsp_write_record(s) < 0) {
58
+        rtsp_close_streams(s);
59
+        url_close(rt->rtsp_hd);
60
+        return AVERROR_INVALIDDATA;
61
+    }
62
+    return 0;
63
+}
64
+
65
+static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
66
+{
67
+    RTSPState *rt = s->priv_data;
68
+    RTSPStream *rtsp_st;
69
+    fd_set rfds;
70
+    int n, tcp_fd;
71
+    struct timeval tv;
72
+    AVFormatContext *rtpctx;
73
+
74
+    FD_ZERO(&rfds);
75
+    tcp_fd = url_get_file_handle(rt->rtsp_hd);
76
+    FD_SET(tcp_fd, &rfds);
77
+
78
+    tv.tv_sec = 0;
79
+    tv.tv_usec = 0;
80
+    n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv);
81
+    if (n > 0) {
82
+        if (FD_ISSET(tcp_fd, &rfds)) {
83
+            RTSPMessageHeader reply;
84
+
85
+            if (rtsp_read_reply(s, &reply, NULL, 0) < 0)
86
+                return AVERROR(EPIPE);
87
+            /* XXX: parse message */
88
+            if (rt->state != RTSP_STATE_STREAMING)
89
+                return AVERROR(EPIPE);
90
+        }
91
+    }
92
+
93
+    if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams)
94
+        return AVERROR_INVALIDDATA;
95
+    rtsp_st = rt->rtsp_streams[pkt->stream_index];
96
+    rtpctx = rtsp_st->transport_priv;
97
+
98
+    pkt->stream_index = 0;
99
+    return av_write_frame(rtpctx, pkt);
100
+}
101
+
102
+static int rtsp_write_close(AVFormatContext *s)
103
+{
104
+    RTSPState *rt = s->priv_data;
105
+    char cmd[1024];
106
+
107
+    snprintf(cmd, sizeof(cmd),
108
+             "TEARDOWN %s RTSP/1.0\r\n",
109
+             s->filename);
110
+    rtsp_send_cmd_async(s, cmd);
111
+
112
+    rtsp_close_streams(s);
113
+    url_close(rt->rtsp_hd);
114
+    return 0;
115
+}
116
+
117
+AVOutputFormat rtsp_muxer = {
118
+    "rtsp",
119
+    NULL_IF_CONFIG_SMALL("RTSP output format"),
120
+    NULL,
121
+    NULL,
122
+    sizeof(RTSPState),
123
+    CODEC_ID_PCM_MULAW,
124
+    CODEC_ID_NONE,
125
+    rtsp_write_header,
126
+    rtsp_write_packet,
127
+    rtsp_write_close,
128
+    .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER,
129
+};
130
+