Mercurial > libavformat.hg
annotate rtspenc.c @ 5854:3dc78fb78b2a libavformat
Fix erroneous behaviour when format probe hits end of file
If the format probe hits end of file, do not add the error code
to the buffer position. This is obviously wrong, and with a
small input file would cause a negative buffer overflow.
Fixes issue 1818.
author | mru |
---|---|
date | Tue, 16 Mar 2010 21:45:30 +0000 |
parents | d04ce2be0081 |
children | 0ff0826b6c3d |
rev | line source |
---|---|
5695 | 1 /* |
2 * RTSP muxer | |
3 * Copyright (c) 2010 Martin Storsjo | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 #include "avformat.h" | |
23 | |
24 #include <sys/time.h> | |
25 #if HAVE_SYS_SELECT_H | |
26 #include <sys/select.h> | |
27 #endif | |
28 #include "network.h" | |
29 #include "rtsp.h" | |
30 | |
31 static int rtsp_write_record(AVFormatContext *s) | |
32 { | |
33 RTSPState *rt = s->priv_data; | |
34 RTSPMessageHeader reply1, *reply = &reply1; | |
35 char cmd[1024]; | |
36 | |
37 snprintf(cmd, sizeof(cmd), | |
38 "RECORD %s RTSP/1.0\r\n" | |
39 "Range: npt=%0.3f-\r\n", | |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5756
diff
changeset
|
40 rt->control_uri, |
5695 | 41 (double) 0); |
5697 | 42 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
5695 | 43 if (reply->status_code != RTSP_STATUS_OK) |
44 return -1; | |
45 rt->state = RTSP_STATE_STREAMING; | |
46 return 0; | |
47 } | |
48 | |
49 static int rtsp_write_header(AVFormatContext *s) | |
50 { | |
51 RTSPState *rt = s->priv_data; | |
52 int ret; | |
53 | |
5697 | 54 ret = ff_rtsp_connect(s); |
5695 | 55 if (ret) |
56 return ret; | |
57 | |
58 if (rtsp_write_record(s) < 0) { | |
5697 | 59 ff_rtsp_close_streams(s); |
5695 | 60 url_close(rt->rtsp_hd); |
61 return AVERROR_INVALIDDATA; | |
62 } | |
63 return 0; | |
64 } | |
65 | |
66 static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) | |
67 { | |
68 RTSPState *rt = s->priv_data; | |
69 RTSPStream *rtsp_st; | |
70 fd_set rfds; | |
71 int n, tcp_fd; | |
72 struct timeval tv; | |
73 AVFormatContext *rtpctx; | |
5721
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
74 AVPacket local_pkt; |
5846
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
75 int ret; |
5695 | 76 |
77 tcp_fd = url_get_file_handle(rt->rtsp_hd); | |
78 | |
5846
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
79 while (1) { |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
80 FD_ZERO(&rfds); |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
81 FD_SET(tcp_fd, &rfds); |
5847 | 82 tv.tv_sec = 0; |
83 tv.tv_usec = 0; | |
84 n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv); | |
5846
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
85 if (n <= 0) |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
86 break; |
5695 | 87 if (FD_ISSET(tcp_fd, &rfds)) { |
88 RTSPMessageHeader reply; | |
89 | |
5846
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
90 /* Don't let ff_rtsp_read_reply handle interleaved packets, |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
91 * since it would block and wait for an RTSP reply on the socket |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
92 * (which may not be coming any time soon) if it handles |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
93 * interleaved packets internally. */ |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
94 ret = ff_rtsp_read_reply(s, &reply, NULL, 1); |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
95 if (ret < 0) |
5695 | 96 return AVERROR(EPIPE); |
5846
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
97 if (ret == 1) |
6821f3887d0e
Don't let ff_rtsp_read_reply skip interleaved RTP/TCP packets in rtsp_write_packet.
mstorsjo
parents:
5800
diff
changeset
|
98 ff_rtsp_skip_packet(s); |
5695 | 99 /* XXX: parse message */ |
100 if (rt->state != RTSP_STATE_STREAMING) | |
101 return AVERROR(EPIPE); | |
102 } | |
103 } | |
104 | |
105 if (pkt->stream_index < 0 || pkt->stream_index >= rt->nb_rtsp_streams) | |
106 return AVERROR_INVALIDDATA; | |
107 rtsp_st = rt->rtsp_streams[pkt->stream_index]; | |
108 rtpctx = rtsp_st->transport_priv; | |
109 | |
5721
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
110 /* Use a local packet for writing to the chained muxer, otherwise |
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
111 * the internal stream_index = 0 becomes visible to the muxer user. */ |
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
112 local_pkt = *pkt; |
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
113 local_pkt.stream_index = 0; |
82b0dc4f052a
RTSP muxer: Use a local copy of the AVPacket for sending to the chained muxer
mstorsjo
parents:
5697
diff
changeset
|
114 return av_write_frame(rtpctx, &local_pkt); |
5695 | 115 } |
116 | |
117 static int rtsp_write_close(AVFormatContext *s) | |
118 { | |
119 RTSPState *rt = s->priv_data; | |
120 char cmd[1024]; | |
121 | |
122 snprintf(cmd, sizeof(cmd), | |
123 "TEARDOWN %s RTSP/1.0\r\n", | |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5756
diff
changeset
|
124 rt->control_uri); |
5697 | 125 ff_rtsp_send_cmd_async(s, cmd); |
5695 | 126 |
5697 | 127 ff_rtsp_close_streams(s); |
5695 | 128 url_close(rt->rtsp_hd); |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5721
diff
changeset
|
129 ff_network_close(); |
5695 | 130 return 0; |
131 } | |
132 | |
133 AVOutputFormat rtsp_muxer = { | |
134 "rtsp", | |
135 NULL_IF_CONFIG_SMALL("RTSP output format"), | |
136 NULL, | |
137 NULL, | |
138 sizeof(RTSPState), | |
139 CODEC_ID_PCM_MULAW, | |
140 CODEC_ID_NONE, | |
141 rtsp_write_header, | |
142 rtsp_write_packet, | |
143 rtsp_write_close, | |
144 .flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER, | |
145 }; | |
146 |