diff --git a/libavformat/Makefile b/libavformat/Makefile index 1f1c576a08..0436ccf602 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -243,7 +243,8 @@ OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o \ rtpdec_qt.o \ rtpdec_svq3.o \ rtpdec_vp8.o \ - rtpdec_xiph.o + rtpdec_xiph.o \ + rtpenc_chain.o OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c new file mode 100644 index 0000000000..10d9df2065 --- /dev/null +++ b/libavformat/rtpenc_chain.c @@ -0,0 +1,82 @@ +/* + * RTP muxer chaining code + * 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 "rtpenc_chain.h" + +AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, + URLContext *handle, int packet_size) +{ + AVFormatContext *rtpctx; + int ret; + AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); + + if (!rtp_format) + return NULL; + + /* Allocate an AVFormatContext for each output stream */ + rtpctx = avformat_alloc_context(); + if (!rtpctx) + return NULL; + + rtpctx->oformat = rtp_format; + if (!av_new_stream(rtpctx, 0)) { + av_free(rtpctx); + return NULL; + } + /* Copy the max delay setting; the rtp muxer reads this. */ + rtpctx->max_delay = s->max_delay; + /* Copy other stream parameters. */ + rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; + + /* Set the synchronized start time. */ + rtpctx->start_time_realtime = s->start_time_realtime; + + /* Remove the local codec, link to the original codec + * context instead, to give the rtp muxer access to + * codec parameters. */ + av_free(rtpctx->streams[0]->codec); + rtpctx->streams[0]->codec = st->codec; + + if (handle) { + url_fdopen(&rtpctx->pb, handle); + } else + url_open_dyn_packet_buf(&rtpctx->pb, packet_size); + ret = av_write_header(rtpctx); + + if (ret) { + if (handle) { + url_fclose(rtpctx->pb); + } else { + uint8_t *ptr; + url_close_dyn_buf(rtpctx->pb, &ptr); + av_free(ptr); + } + av_free(rtpctx->streams[0]); + av_free(rtpctx); + return NULL; + } + + /* Copy the RTP AVStream timebase back to the original AVStream */ + st->time_base = rtpctx->streams[0]->time_base; + return rtpctx; +} + diff --git a/libavformat/rtpenc_chain.h b/libavformat/rtpenc_chain.h new file mode 100644 index 0000000000..9e19b64d67 --- /dev/null +++ b/libavformat/rtpenc_chain.h @@ -0,0 +1,30 @@ +/* + * RTP muxer chaining code + * 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 + */ + +#ifndef AVFORMAT_RTPENC_CHAIN_H +#define AVFORMAT_RTPENC_CHAIN_H + +#include "avformat.h" + +AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, + URLContext *handle, int packet_size); + +#endif /* AVFORMAT_RTPENC_CHAIN_H */ diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 094ad79923..6570c3880b 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -39,6 +39,7 @@ #include "rtpdec.h" #include "rdt.h" #include "rtpdec_formats.h" +#include "rtpenc_chain.h" //#define DEBUG //#define DEBUG_RTP_TCP @@ -502,64 +503,6 @@ void ff_rtsp_close_streams(AVFormatContext *s) av_free(rt->recvbuf); } -static AVFormatContext *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st, - URLContext *handle, int packet_size) -{ - AVFormatContext *rtpctx; - int ret; - AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); - - if (!rtp_format) - return NULL; - - /* Allocate an AVFormatContext for each output stream */ - rtpctx = avformat_alloc_context(); - if (!rtpctx) - return NULL; - - rtpctx->oformat = rtp_format; - if (!av_new_stream(rtpctx, 0)) { - av_free(rtpctx); - return NULL; - } - /* Copy the max delay setting; the rtp muxer reads this. */ - rtpctx->max_delay = s->max_delay; - /* Copy other stream parameters. */ - rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; - - /* Set the synchronized start time. */ - rtpctx->start_time_realtime = s->start_time_realtime; - - /* Remove the local codec, link to the original codec - * context instead, to give the rtp muxer access to - * codec parameters. */ - av_free(rtpctx->streams[0]->codec); - rtpctx->streams[0]->codec = st->codec; - - if (handle) { - url_fdopen(&rtpctx->pb, handle); - } else - url_open_dyn_packet_buf(&rtpctx->pb, packet_size); - ret = av_write_header(rtpctx); - - if (ret) { - if (handle) { - url_fclose(rtpctx->pb); - } else { - uint8_t *ptr; - url_close_dyn_buf(rtpctx->pb, &ptr); - av_free(ptr); - } - av_free(rtpctx->streams[0]); - av_free(rtpctx); - return NULL; - } - - /* Copy the RTP AVStream timebase back to the original AVStream */ - st->time_base = rtpctx->streams[0]->time_base; - return rtpctx; -} - static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) { RTSPState *rt = s->priv_data; @@ -572,8 +515,9 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) s->ctx_flags |= AVFMTCTX_NOHEADER; if (s->oformat) { - rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle, - RTSP_TCP_MAX_PACKET_SIZE); + rtsp_st->transport_priv = ff_rtp_chain_mux_open(s, st, + rtsp_st->rtp_handle, + RTSP_TCP_MAX_PACKET_SIZE); /* Ownership of rtp_handle is passed to the rtp mux context */ rtsp_st->rtp_handle = NULL; } else if (rt->transport == RTSP_TRANSPORT_RDT)