diff options
author | Martin Storsjö <martin@martin.st> | 2010-02-22 21:28:19 +0000 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2010-02-22 21:28:19 +0000 |
commit | 6f5a3d0a7bb2a1e9deb09f8204e2b0eb7a922e02 (patch) | |
tree | 432001b95c368bbac77860dae81d4359d8912b48 | |
parent | f86f66562311f38b6b7864c19720727916fb0d19 (diff) | |
download | ffmpeg-6f5a3d0a7bb2a1e9deb09f8204e2b0eb7a922e02.tar.gz |
Add an RTSP muxer
Originally committed as revision 21971 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | Changelog | 1 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/general.texi | 2 | ||||
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/allformats.c | 2 | ||||
-rw-r--r-- | libavformat/avformat.h | 2 | ||||
-rw-r--r-- | libavformat/rtsp.c | 4 | ||||
-rw-r--r-- | libavformat/rtspenc.c | 131 |
8 files changed, 141 insertions, 4 deletions
@@ -60,6 +60,7 @@ version <next>: - WMAVoice decoder - FFprobe tool - AMR-NB decoder +- RTSP muxer @@ -1351,6 +1351,8 @@ mxf_d10_muxer_select="mxf_muxer" ogg_demuxer_select="golomb" psp_muxer_select="mov_muxer" rtsp_demuxer_deps="sdp_demuxer" +rtsp_muxer_deps="sdp_demuxer" +rtsp_muxer_select="rtp_muxer" sdp_demuxer_deps="rtp_protocol mpegts_demuxer" spdif_muxer_select="aac_parser" tg2_muxer_select="mov_muxer" diff --git a/doc/general.texi b/doc/general.texi index 816630011e..e4f4423191 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -210,7 +210,7 @@ library: @item RTMP @tab X @tab X @tab Output is performed by publishing stream to RTMP server @item RTP @tab @tab X -@item RTSP @tab @tab X +@item RTSP @tab X @tab X @item SDP @tab @tab X @item Sega FILM/CPK @tab @tab X @tab Used in many Sega Saturn console games. diff --git a/libavformat/Makefile b/libavformat/Makefile index 8d2dbb3c91..48b8f80a74 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -210,6 +210,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_h264.o \ avc.o OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o +OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o \ rdt.o \ rtp.o \ diff --git a/libavformat/allformats.c b/libavformat/allformats.c index e91325b530..090d134d73 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -172,7 +172,7 @@ void av_register_all(void) REGISTER_MUXDEMUX (ROQ, roq); REGISTER_DEMUXER (RPL, rpl); REGISTER_MUXER (RTP, rtp); - REGISTER_DEMUXER (RTSP, rtsp); + REGISTER_MUXDEMUX (RTSP, rtsp); REGISTER_DEMUXER (SDP, sdp); #if CONFIG_SDP_DEMUXER av_register_rtp_dynamic_payload_handlers(); diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 2e8770a0a3..4b0aa67ef6 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -22,7 +22,7 @@ #define AVFORMAT_AVFORMAT_H #define LIBAVFORMAT_VERSION_MAJOR 52 -#define LIBAVFORMAT_VERSION_MINOR 52 +#define LIBAVFORMAT_VERSION_MINOR 53 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 26b9e9312b..23d56b6c0a 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -691,7 +691,7 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) return 0; } -#if CONFIG_RTSP_DEMUXER +#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER static int rtsp_probe(AVProbeData *p) { if (av_strstart(p->filename, "rtsp:", NULL)) @@ -1533,7 +1533,9 @@ redirect: } return err; } +#endif +#if CONFIG_RTSP_DEMUXER static int rtsp_read_header(AVFormatContext *s, AVFormatParameters *ap) { diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c new file mode 100644 index 0000000000..c918b3e8c0 --- /dev/null +++ b/libavformat/rtspenc.c @@ -0,0 +1,131 @@ +/* + * RTSP muxer + * Copyright (c) 2010 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avformat.h" + +#include <sys/time.h> +#if HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#include "network.h" +#include "rtsp.h" + +static int rtsp_write_record(AVFormatContext *s) +{ + RTSPState *rt = s->priv_data; + RTSPMessageHeader reply1, *reply = &reply1; + char cmd[1024]; + + snprintf(cmd, sizeof(cmd), + "RECORD %s RTSP/1.0\r\n" + "Range: npt=%0.3f-\r\n", + s->filename, + (double) 0); + rtsp_send_cmd(s, cmd, reply, NULL); + if (reply->status_code != RTSP_STATUS_OK) + return -1; + rt->state = RTSP_STATE_STREAMING; + return 0; +} + +static int rtsp_write_header(AVFormatContext *s) +{ + RTSPState *rt = s->priv_data; + int ret; + + ret = rtsp_connect(s); + if (ret) + return ret; + + if (rtsp_write_record(s) < 0) { + rtsp_close_streams(s); + url_close(rt->rtsp_hd); + return AVERROR_INVALIDDATA; + } + return 0; +} + +static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + RTSPState *rt = s->priv_data; + RTSPStream *rtsp_st; + fd_set rfds; + int n, tcp_fd; + struct timeval tv; + AVFormatContext *rtpctx; + + FD_ZERO(&rfds); + tcp_fd = url_get_file_handle(rt->rtsp_hd); + FD_SET(tcp_fd, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = 0; + n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv); + if (n > 0) { + if (FD_ISSET(tcp_fd, &rfds)) { + RTSPMessageHeader reply; + + if (rtsp_read_reply(s, &reply, NULL, 0) < 0) + return AVERROR(EPIPE); + /* XXX: parse message */ + if (rt->state != RTSP_STATE_STREAMING) + return AVERROR(EPIPE); + } + } + + if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams) + return AVERROR_INVALIDDATA; + rtsp_st = rt->rtsp_streams[pkt->stream_index]; + rtpctx = rtsp_st->transport_priv; + + pkt->stream_index = 0; + return av_write_frame(rtpctx, pkt); +} + +static int rtsp_write_close(AVFormatContext *s) +{ + RTSPState *rt = s->priv_data; + char cmd[1024]; + + snprintf(cmd, sizeof(cmd), + "TEARDOWN %s RTSP/1.0\r\n", + s->filename); + rtsp_send_cmd_async(s, cmd); + + rtsp_close_streams(s); + url_close(rt->rtsp_hd); + return 0; +} + +AVOutputFormat rtsp_muxer = { + "rtsp", + NULL_IF_CONFIG_SMALL("RTSP output format"), + NULL, + NULL, + sizeof(RTSPState), + CODEC_ID_PCM_MULAW, + CODEC_ID_NONE, + rtsp_write_header, + rtsp_write_packet, + rtsp_write_close, + .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, +}; + |