summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2010-02-22 15:46:56 +0000
committerMartin Storsjö <martin@martin.st>2010-02-22 15:46:56 +0000
commitfd450a51774bbf66ca67d2e9afdf8611a3ea4362 (patch)
tree21d3611ed962c96288c54b1548ffd1b5b79e7cc6 /libavformat
parent1d6065ad089741626711853ee1ed07f5b439e5ad (diff)
Create AVFormatContext objects as private transport for output RTSP sessions
Originally committed as revision 21964 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/rtsp.c58
-rw-r--r--libavformat/rtsp.h2
2 files changed, 57 insertions, 3 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index ae56396490..1f36974ae1 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -582,7 +582,13 @@ static void rtsp_close_streams(AVFormatContext *s)
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st) {
if (rtsp_st->transport_priv) {
- if (rt->transport == RTSP_TRANSPORT_RDT)
+ if (s->oformat) {
+ AVFormatContext *rtpctx = rtsp_st->transport_priv;
+ av_write_trailer(rtpctx);
+ url_fclose(rtpctx->pb);
+ av_free(rtpctx->streams[0]);
+ av_free(rtpctx);
+ } else if (rt->transport == RTSP_TRANSPORT_RDT)
ff_rdt_parse_close(rtsp_st->transport_priv);
else
rtp_parse_close(rtsp_st->transport_priv);
@@ -602,6 +608,50 @@ static void rtsp_close_streams(AVFormatContext *s)
av_freep(&rt->auth_b64);
}
+static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st, URLContext *handle) {
+ 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;
+
+ /* 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;
+
+ url_fdopen(&rtpctx->pb, handle);
+ ret = av_write_header(rtpctx);
+
+ if (ret) {
+ url_fclose(rtpctx->pb);
+ 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;
@@ -613,7 +663,11 @@ static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
if (!st)
s->ctx_flags |= AVFMTCTX_NOHEADER;
- if (rt->transport == RTSP_TRANSPORT_RDT)
+ if (s->oformat) {
+ rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle);
+ /* Ownage of rtp_handle is passed to the rtp mux context */
+ rtsp_st->rtp_handle = NULL;
+ } else if (rt->transport == RTSP_TRANSPORT_RDT)
rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 6f441209ac..b115fdae31 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -281,7 +281,7 @@ typedef struct RTSPState {
*/
typedef struct RTSPStream {
URLContext *rtp_handle; /**< RTP stream handle (if UDP) */
- void *transport_priv; /**< RTP/RDT parse context */
+ void *transport_priv; /**< RTP/RDT parse context if input, RTP AVFormatContext if output */
/** corresponding stream index, if any. -1 if none (MPEG2TS case) */
int stream_index;