* commit '8a70ef94b9c377293b3dfa7d92cdc81a4fe1543a':
libavformat: Add a muxer wrapping mpegts encoding into RTP
Conflicts:
Changelog
libavformat/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -363,6 +363,7 @@ OBJS-$(CONFIG_RSD_DEMUXER) += rsd.o |
363 | 363 |
OBJS-$(CONFIG_RSO_DEMUXER) += rsodec.o rso.o pcm.o |
364 | 364 |
OBJS-$(CONFIG_RSO_MUXER) += rsoenc.o rso.o |
365 | 365 |
OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o |
366 |
+OBJS-$(CONFIG_RTP_MPEGTS_MUXER) += rtpenc_mpegts.o |
|
366 | 367 |
OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ |
367 | 368 |
rtpenc_aac.o \ |
368 | 369 |
rtpenc_latm.o \ |
... | ... |
@@ -254,6 +254,7 @@ void av_register_all(void) |
254 | 254 |
REGISTER_DEMUXER (RSD, rsd); |
255 | 255 |
REGISTER_MUXDEMUX(RSO, rso); |
256 | 256 |
REGISTER_MUXDEMUX(RTP, rtp); |
257 |
+ REGISTER_MUXER (RTP_MPEGTS, rtp_mpegts); |
|
257 | 258 |
REGISTER_MUXDEMUX(RTSP, rtsp); |
258 | 259 |
REGISTER_DEMUXER (SAMI, sami); |
259 | 260 |
REGISTER_MUXDEMUX(SAP, sap); |
260 | 261 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,165 @@ |
0 |
+/* |
|
1 |
+ * RTP/mpegts muxer |
|
2 |
+ * Copyright (c) 2011 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 "libavutil/mathematics.h" |
|
22 |
+#include "avformat.h" |
|
23 |
+ |
|
24 |
+struct MuxChain { |
|
25 |
+ AVFormatContext *mpegts_ctx; |
|
26 |
+ AVFormatContext *rtp_ctx; |
|
27 |
+}; |
|
28 |
+ |
|
29 |
+static int rtp_mpegts_write_close(AVFormatContext *s) |
|
30 |
+{ |
|
31 |
+ struct MuxChain *chain = s->priv_data; |
|
32 |
+ |
|
33 |
+ if (chain->mpegts_ctx) { |
|
34 |
+ if (!chain->mpegts_ctx->pb) |
|
35 |
+ avio_open_dyn_buf(&chain->mpegts_ctx->pb); |
|
36 |
+ if (chain->mpegts_ctx->pb) { |
|
37 |
+ uint8_t *buf; |
|
38 |
+ av_write_trailer(chain->mpegts_ctx); |
|
39 |
+ avio_close_dyn_buf(chain->mpegts_ctx->pb, &buf); |
|
40 |
+ av_free(buf); |
|
41 |
+ } |
|
42 |
+ avformat_free_context(chain->mpegts_ctx); |
|
43 |
+ } |
|
44 |
+ if (chain->rtp_ctx) { |
|
45 |
+ av_write_trailer(chain->rtp_ctx); |
|
46 |
+ avformat_free_context(chain->rtp_ctx); |
|
47 |
+ } |
|
48 |
+ return 0; |
|
49 |
+} |
|
50 |
+ |
|
51 |
+static int rtp_mpegts_write_header(AVFormatContext *s) |
|
52 |
+{ |
|
53 |
+ struct MuxChain *chain = s->priv_data; |
|
54 |
+ AVFormatContext *mpegts_ctx = NULL, *rtp_ctx = NULL; |
|
55 |
+ AVOutputFormat *mpegts_format = av_guess_format("mpegts", NULL, NULL); |
|
56 |
+ AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); |
|
57 |
+ int i, ret = AVERROR(ENOMEM); |
|
58 |
+ AVStream *st; |
|
59 |
+ |
|
60 |
+ if (!mpegts_format || !rtp_format) |
|
61 |
+ return AVERROR(ENOSYS); |
|
62 |
+ mpegts_ctx = avformat_alloc_context(); |
|
63 |
+ if (!mpegts_ctx) |
|
64 |
+ return AVERROR(ENOMEM); |
|
65 |
+ mpegts_ctx->oformat = mpegts_format; |
|
66 |
+ mpegts_ctx->max_delay = s->max_delay; |
|
67 |
+ for (i = 0; i < s->nb_streams; i++) { |
|
68 |
+ AVStream* st = avformat_new_stream(mpegts_ctx, NULL); |
|
69 |
+ if (!st) |
|
70 |
+ goto fail; |
|
71 |
+ st->time_base = s->streams[i]->time_base; |
|
72 |
+ st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; |
|
73 |
+ avcodec_copy_context(st->codec, s->streams[i]->codec); |
|
74 |
+ } |
|
75 |
+ if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0) |
|
76 |
+ goto fail; |
|
77 |
+ if ((ret = avformat_write_header(mpegts_ctx, NULL)) < 0) |
|
78 |
+ goto fail; |
|
79 |
+ for (i = 0; i < s->nb_streams; i++) |
|
80 |
+ s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base; |
|
81 |
+ |
|
82 |
+ chain->mpegts_ctx = mpegts_ctx; |
|
83 |
+ mpegts_ctx = NULL; |
|
84 |
+ |
|
85 |
+ rtp_ctx = avformat_alloc_context(); |
|
86 |
+ if (!rtp_ctx) { |
|
87 |
+ ret = AVERROR(ENOMEM); |
|
88 |
+ goto fail; |
|
89 |
+ } |
|
90 |
+ rtp_ctx->oformat = rtp_format; |
|
91 |
+ st = avformat_new_stream(rtp_ctx, NULL); |
|
92 |
+ st->time_base.num = 1; |
|
93 |
+ st->time_base.den = 90000; |
|
94 |
+ st->codec->codec_id = AV_CODEC_ID_MPEG2TS; |
|
95 |
+ chain->rtp_ctx = rtp_ctx; |
|
96 |
+ rtp_ctx->pb = s->pb; |
|
97 |
+ if ((ret = avformat_write_header(rtp_ctx, NULL)) < 0) |
|
98 |
+ goto fail; |
|
99 |
+ rtp_ctx = NULL; |
|
100 |
+ |
|
101 |
+ return 0; |
|
102 |
+ |
|
103 |
+fail: |
|
104 |
+ if (mpegts_ctx) { |
|
105 |
+ if (mpegts_ctx->pb) { |
|
106 |
+ uint8_t *buf; |
|
107 |
+ avio_close_dyn_buf(mpegts_ctx->pb, &buf); |
|
108 |
+ av_free(buf); |
|
109 |
+ } |
|
110 |
+ avformat_free_context(mpegts_ctx); |
|
111 |
+ } |
|
112 |
+ if (rtp_ctx) |
|
113 |
+ avformat_free_context(rtp_ctx); |
|
114 |
+ rtp_mpegts_write_close(s); |
|
115 |
+ return ret; |
|
116 |
+} |
|
117 |
+ |
|
118 |
+static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) |
|
119 |
+{ |
|
120 |
+ struct MuxChain *chain = s->priv_data; |
|
121 |
+ int ret = 0, size; |
|
122 |
+ uint8_t *buf; |
|
123 |
+ AVPacket local_pkt; |
|
124 |
+ |
|
125 |
+ if (!chain->mpegts_ctx->pb) { |
|
126 |
+ if ((ret = avio_open_dyn_buf(&chain->mpegts_ctx->pb)) < 0) |
|
127 |
+ return ret; |
|
128 |
+ } |
|
129 |
+ if ((ret = av_write_frame(chain->mpegts_ctx, pkt)) < 0) |
|
130 |
+ return ret; |
|
131 |
+ size = avio_close_dyn_buf(chain->mpegts_ctx->pb, &buf); |
|
132 |
+ chain->mpegts_ctx->pb = NULL; |
|
133 |
+ if (size == 0) { |
|
134 |
+ av_free(buf); |
|
135 |
+ return 0; |
|
136 |
+ } |
|
137 |
+ av_init_packet(&local_pkt); |
|
138 |
+ local_pkt.data = buf; |
|
139 |
+ local_pkt.size = size; |
|
140 |
+ local_pkt.stream_index = 0; |
|
141 |
+ if (pkt->pts != AV_NOPTS_VALUE) |
|
142 |
+ local_pkt.pts = av_rescale_q(pkt->pts, |
|
143 |
+ s->streams[pkt->stream_index]->time_base, |
|
144 |
+ chain->rtp_ctx->streams[0]->time_base); |
|
145 |
+ if (pkt->dts != AV_NOPTS_VALUE) |
|
146 |
+ local_pkt.dts = av_rescale_q(pkt->dts, |
|
147 |
+ s->streams[pkt->stream_index]->time_base, |
|
148 |
+ chain->rtp_ctx->streams[0]->time_base); |
|
149 |
+ ret = av_write_frame(chain->rtp_ctx, &local_pkt); |
|
150 |
+ av_free(buf); |
|
151 |
+ |
|
152 |
+ return ret; |
|
153 |
+} |
|
154 |
+ |
|
155 |
+AVOutputFormat ff_rtp_mpegts_muxer = { |
|
156 |
+ .name = "rtp_mpegts", |
|
157 |
+ .long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"), |
|
158 |
+ .priv_data_size = sizeof(struct MuxChain), |
|
159 |
+ .audio_codec = AV_CODEC_ID_AAC, |
|
160 |
+ .video_codec = AV_CODEC_ID_MPEG4, |
|
161 |
+ .write_header = rtp_mpegts_write_header, |
|
162 |
+ .write_packet = rtp_mpegts_write_packet, |
|
163 |
+ .write_trailer = rtp_mpegts_write_close, |
|
164 |
+}; |
... | ... |
@@ -30,8 +30,8 @@ |
30 | 30 |
#include "libavutil/version.h" |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 56 |
33 |
-#define LIBAVFORMAT_VERSION_MINOR 15 |
|
34 |
-#define LIBAVFORMAT_VERSION_MICRO 107 |
|
33 |
+#define LIBAVFORMAT_VERSION_MINOR 16 |
|
34 |
+#define LIBAVFORMAT_VERSION_MICRO 100 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFORMAT_VERSION_MINOR, \ |