The demuxer inspects the payload type of a received RTP packet and
handles the cases where the content is fully described by the payload type.
Originally committed as revision 25527 to svn://svn.ffmpeg.org/ffmpeg/trunk
... | ... |
@@ -1361,6 +1361,7 @@ mpegtsraw_demuxer_select="mpegts_demuxer" |
1361 | 1361 |
mxf_d10_muxer_select="mxf_muxer" |
1362 | 1362 |
ogg_demuxer_select="golomb" |
1363 | 1363 |
psp_muxer_select="mov_muxer" |
1364 |
+rtp_demuxer_select="sdp_demuxer" |
|
1364 | 1365 |
rtsp_demuxer_select="http_protocol sdp_demuxer" |
1365 | 1366 |
rtsp_muxer_select="rtp_muxer http_protocol sdp_demuxer" |
1366 | 1367 |
sap_demuxer_select="sdp_demuxer" |
... | ... |
@@ -215,7 +215,7 @@ library: |
215 | 215 |
@item Lego Mindstorms RSO @tab X @tab X |
216 | 216 |
@item RTMP @tab X @tab X |
217 | 217 |
@tab Output is performed by publishing stream to RTMP server |
218 |
-@item RTP @tab X @tab |
|
218 |
+@item RTP @tab X @tab X |
|
219 | 219 |
@item RTSP @tab X @tab X |
220 | 220 |
@item SAP @tab X @tab X |
221 | 221 |
@item SDP @tab @tab X |
... | ... |
@@ -179,7 +179,7 @@ void av_register_all(void) |
179 | 179 |
REGISTER_MUXDEMUX (ROQ, roq); |
180 | 180 |
REGISTER_DEMUXER (RPL, rpl); |
181 | 181 |
REGISTER_MUXDEMUX (RSO, rso); |
182 |
- REGISTER_MUXER (RTP, rtp); |
|
182 |
+ REGISTER_MUXDEMUX (RTP, rtp); |
|
183 | 183 |
REGISTER_MUXDEMUX (RTSP, rtsp); |
184 | 184 |
REGISTER_MUXDEMUX (SAP, sap); |
185 | 185 |
REGISTER_DEMUXER (SDP, sdp); |
... | ... |
@@ -22,7 +22,7 @@ |
22 | 22 |
#define AVFORMAT_AVFORMAT_H |
23 | 23 |
|
24 | 24 |
#define LIBAVFORMAT_VERSION_MAJOR 52 |
25 |
-#define LIBAVFORMAT_VERSION_MINOR 83 |
|
25 |
+#define LIBAVFORMAT_VERSION_MINOR 84 |
|
26 | 26 |
#define LIBAVFORMAT_VERSION_MICRO 0 |
27 | 27 |
|
28 | 28 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
... | ... |
@@ -2104,3 +2104,107 @@ AVInputFormat sdp_demuxer = { |
2104 | 2104 |
rtsp_fetch_packet, |
2105 | 2105 |
sdp_read_close, |
2106 | 2106 |
}; |
2107 |
+ |
|
2108 |
+static int rtp_probe(AVProbeData *p) |
|
2109 |
+{ |
|
2110 |
+ if (av_strstart(p->filename, "rtp:", NULL)) |
|
2111 |
+ return AVPROBE_SCORE_MAX; |
|
2112 |
+ return 0; |
|
2113 |
+} |
|
2114 |
+ |
|
2115 |
+static int rtp_read_header(AVFormatContext *s, |
|
2116 |
+ AVFormatParameters *ap) |
|
2117 |
+{ |
|
2118 |
+ uint8_t recvbuf[1500]; |
|
2119 |
+ char host[500], sdp[500]; |
|
2120 |
+ int ret, port; |
|
2121 |
+ URLContext* in = NULL; |
|
2122 |
+ int payload_type; |
|
2123 |
+ AVCodecContext codec; |
|
2124 |
+ struct sockaddr_storage addr; |
|
2125 |
+ ByteIOContext pb; |
|
2126 |
+ socklen_t addrlen = sizeof(addr); |
|
2127 |
+ |
|
2128 |
+ if (!ff_network_init()) |
|
2129 |
+ return AVERROR(EIO); |
|
2130 |
+ |
|
2131 |
+ ret = url_open(&in, s->filename, URL_RDONLY); |
|
2132 |
+ if (ret) |
|
2133 |
+ goto fail; |
|
2134 |
+ |
|
2135 |
+ while (1) { |
|
2136 |
+ ret = url_read(in, recvbuf, sizeof(recvbuf)); |
|
2137 |
+ if (ret == AVERROR(EAGAIN)) |
|
2138 |
+ continue; |
|
2139 |
+ if (ret < 0) |
|
2140 |
+ goto fail; |
|
2141 |
+ if (ret < 12) { |
|
2142 |
+ av_log(s, AV_LOG_WARNING, "Received too short packet\n"); |
|
2143 |
+ continue; |
|
2144 |
+ } |
|
2145 |
+ |
|
2146 |
+ if ((recvbuf[0] & 0xc0) != 0x80) { |
|
2147 |
+ av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet " |
|
2148 |
+ "received\n"); |
|
2149 |
+ continue; |
|
2150 |
+ } |
|
2151 |
+ |
|
2152 |
+ payload_type = recvbuf[1] & 0x7f; |
|
2153 |
+ break; |
|
2154 |
+ } |
|
2155 |
+ getsockname(url_get_file_handle(in), (struct sockaddr*) &addr, &addrlen); |
|
2156 |
+ url_close(in); |
|
2157 |
+ in = NULL; |
|
2158 |
+ |
|
2159 |
+ memset(&codec, 0, sizeof(codec)); |
|
2160 |
+ if (ff_rtp_get_codec_info(&codec, payload_type)) { |
|
2161 |
+ av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d " |
|
2162 |
+ "without an SDP file describing it\n", |
|
2163 |
+ payload_type); |
|
2164 |
+ goto fail; |
|
2165 |
+ } |
|
2166 |
+ if (codec.codec_type != AVMEDIA_TYPE_DATA) { |
|
2167 |
+ av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received " |
|
2168 |
+ "properly you need an SDP file " |
|
2169 |
+ "describing it\n"); |
|
2170 |
+ } |
|
2171 |
+ |
|
2172 |
+ av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, |
|
2173 |
+ NULL, 0, s->filename); |
|
2174 |
+ |
|
2175 |
+ snprintf(sdp, sizeof(sdp), |
|
2176 |
+ "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n", |
|
2177 |
+ addr.ss_family == AF_INET ? 4 : 6, host, |
|
2178 |
+ codec.codec_type == AVMEDIA_TYPE_DATA ? "application" : |
|
2179 |
+ codec.codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio", |
|
2180 |
+ port, payload_type); |
|
2181 |
+ av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp); |
|
2182 |
+ |
|
2183 |
+ init_put_byte(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL); |
|
2184 |
+ s->pb = &pb; |
|
2185 |
+ |
|
2186 |
+ /* sdp_read_header initializes this again */ |
|
2187 |
+ ff_network_close(); |
|
2188 |
+ |
|
2189 |
+ ret = sdp_read_header(s, ap); |
|
2190 |
+ s->pb = NULL; |
|
2191 |
+ return ret; |
|
2192 |
+ |
|
2193 |
+fail: |
|
2194 |
+ if (in) |
|
2195 |
+ url_close(in); |
|
2196 |
+ ff_network_close(); |
|
2197 |
+ return ret; |
|
2198 |
+} |
|
2199 |
+ |
|
2200 |
+AVInputFormat rtp_demuxer = { |
|
2201 |
+ "rtp", |
|
2202 |
+ NULL_IF_CONFIG_SMALL("RTP input format"), |
|
2203 |
+ sizeof(RTSPState), |
|
2204 |
+ rtp_probe, |
|
2205 |
+ rtp_read_header, |
|
2206 |
+ rtsp_fetch_packet, |
|
2207 |
+ sdp_read_close, |
|
2208 |
+ .flags = AVFMT_NOFILE, |
|
2209 |
+}; |
|
2210 |
+ |