]> git.sesse.net Git - ffmpeg/blob - libavformat/rtpenc.c
add out of bound stream index checks
[ffmpeg] / libavformat / rtpenc.c
1 /*
2  * RTP output format
3  * Copyright (c) 2002 Fabrice Bellard.
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 #include "avformat.h"
22 #include "mpegts.h"
23 #include "bitstream.h"
24
25 #include <unistd.h>
26 #include "network.h"
27
28 #include "rtp_internal.h"
29 #include "rtp_mpv.h"
30 #include "rtp_aac.h"
31 #include "rtp_h264.h"
32
33 //#define DEBUG
34
35 #define RTCP_SR_SIZE 28
36 #define NTP_OFFSET 2208988800ULL
37 #define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL)
38
39 static uint64_t ntp_time(void)
40 {
41   return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
42 }
43
44 static int rtp_write_header(AVFormatContext *s1)
45 {
46     RTPDemuxContext *s = s1->priv_data;
47     int payload_type, max_packet_size, n;
48     AVStream *st;
49
50     if (s1->nb_streams != 1)
51         return -1;
52     st = s1->streams[0];
53
54     payload_type = rtp_get_payload_type(st->codec);
55     if (payload_type < 0)
56         payload_type = RTP_PT_PRIVATE; /* private payload type */
57     s->payload_type = payload_type;
58
59 // following 2 FIXMEs could be set based on the current time, there is normally no info leak, as RTP will likely be transmitted immediately
60     s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
61     s->timestamp = s->base_timestamp;
62     s->cur_timestamp = 0;
63     s->ssrc = 0; /* FIXME: was random(), what should this be? */
64     s->first_packet = 1;
65     s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
66
67     max_packet_size = url_fget_max_packet_size(s1->pb);
68     if (max_packet_size <= 12)
69         return AVERROR(EIO);
70     s->max_payload_size = max_packet_size - 12;
71
72     s->max_frames_per_packet = 0;
73     if (s1->max_delay) {
74         if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
75             if (st->codec->frame_size == 0) {
76                 av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
77             } else {
78                 s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN);
79             }
80         }
81         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
82             /* FIXME: We should round down here... */
83             s->max_frames_per_packet = av_rescale_q(s1->max_delay, AV_TIME_BASE_Q, st->codec->time_base);
84         }
85     }
86
87     av_set_pts_info(st, 32, 1, 90000);
88     switch(st->codec->codec_id) {
89     case CODEC_ID_MP2:
90     case CODEC_ID_MP3:
91         s->buf_ptr = s->buf + 4;
92         break;
93     case CODEC_ID_MPEG1VIDEO:
94     case CODEC_ID_MPEG2VIDEO:
95         break;
96     case CODEC_ID_MPEG2TS:
97         n = s->max_payload_size / TS_PACKET_SIZE;
98         if (n < 1)
99             n = 1;
100         s->max_payload_size = n * TS_PACKET_SIZE;
101         s->buf_ptr = s->buf;
102         break;
103     case CODEC_ID_AAC:
104         s->read_buf_index = 0;
105     default:
106         if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
107             av_set_pts_info(st, 32, 1, st->codec->sample_rate);
108         }
109         s->buf_ptr = s->buf;
110         break;
111     }
112
113     return 0;
114 }
115
116 /* send an rtcp sender report packet */
117 static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
118 {
119     RTPDemuxContext *s = s1->priv_data;
120     uint32_t rtp_ts;
121
122 #if defined(DEBUG)
123     printf("RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
124 #endif
125
126     if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) s->first_rtcp_ntp_time = ntp_time;
127     s->last_rtcp_ntp_time = ntp_time;
128     rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, AV_TIME_BASE_Q,
129                           s1->streams[0]->time_base) + s->base_timestamp;
130     put_byte(s1->pb, (RTP_VERSION << 6));
131     put_byte(s1->pb, 200);
132     put_be16(s1->pb, 6); /* length in words - 1 */
133     put_be32(s1->pb, s->ssrc);
134     put_be32(s1->pb, ntp_time / 1000000);
135     put_be32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
136     put_be32(s1->pb, rtp_ts);
137     put_be32(s1->pb, s->packet_count);
138     put_be32(s1->pb, s->octet_count);
139     put_flush_packet(s1->pb);
140 }
141
142 /* send an rtp packet. sequence number is incremented, but the caller
143    must update the timestamp itself */
144 void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
145 {
146     RTPDemuxContext *s = s1->priv_data;
147
148 #ifdef DEBUG
149     printf("rtp_send_data size=%d\n", len);
150 #endif
151
152     /* build the RTP header */
153     put_byte(s1->pb, (RTP_VERSION << 6));
154     put_byte(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
155     put_be16(s1->pb, s->seq);
156     put_be32(s1->pb, s->timestamp);
157     put_be32(s1->pb, s->ssrc);
158
159     put_buffer(s1->pb, buf1, len);
160     put_flush_packet(s1->pb);
161
162     s->seq++;
163     s->octet_count += len;
164     s->packet_count++;
165 }
166
167 /* send an integer number of samples and compute time stamp and fill
168    the rtp send buffer before sending. */
169 static void rtp_send_samples(AVFormatContext *s1,
170                              const uint8_t *buf1, int size, int sample_size)
171 {
172     RTPDemuxContext *s = s1->priv_data;
173     int len, max_packet_size, n;
174
175     max_packet_size = (s->max_payload_size / sample_size) * sample_size;
176     /* not needed, but who nows */
177     if ((size % sample_size) != 0)
178         av_abort();
179     n = 0;
180     while (size > 0) {
181         s->buf_ptr = s->buf;
182         len = FFMIN(max_packet_size, size);
183
184         /* copy data */
185         memcpy(s->buf_ptr, buf1, len);
186         s->buf_ptr += len;
187         buf1 += len;
188         size -= len;
189         s->timestamp = s->cur_timestamp + n / sample_size;
190         ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
191         n += (s->buf_ptr - s->buf);
192     }
193 }
194
195 /* NOTE: we suppose that exactly one frame is given as argument here */
196 /* XXX: test it */
197 static void rtp_send_mpegaudio(AVFormatContext *s1,
198                                const uint8_t *buf1, int size)
199 {
200     RTPDemuxContext *s = s1->priv_data;
201     int len, count, max_packet_size;
202
203     max_packet_size = s->max_payload_size;
204
205     /* test if we must flush because not enough space */
206     len = (s->buf_ptr - s->buf);
207     if ((len + size) > max_packet_size) {
208         if (len > 4) {
209             ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
210             s->buf_ptr = s->buf + 4;
211         }
212     }
213     if (s->buf_ptr == s->buf + 4) {
214         s->timestamp = s->cur_timestamp;
215     }
216
217     /* add the packet */
218     if (size > max_packet_size) {
219         /* big packet: fragment */
220         count = 0;
221         while (size > 0) {
222             len = max_packet_size - 4;
223             if (len > size)
224                 len = size;
225             /* build fragmented packet */
226             s->buf[0] = 0;
227             s->buf[1] = 0;
228             s->buf[2] = count >> 8;
229             s->buf[3] = count;
230             memcpy(s->buf + 4, buf1, len);
231             ff_rtp_send_data(s1, s->buf, len + 4, 0);
232             size -= len;
233             buf1 += len;
234             count += len;
235         }
236     } else {
237         if (s->buf_ptr == s->buf + 4) {
238             /* no fragmentation possible */
239             s->buf[0] = 0;
240             s->buf[1] = 0;
241             s->buf[2] = 0;
242             s->buf[3] = 0;
243         }
244         memcpy(s->buf_ptr, buf1, size);
245         s->buf_ptr += size;
246     }
247 }
248
249 static void rtp_send_raw(AVFormatContext *s1,
250                          const uint8_t *buf1, int size)
251 {
252     RTPDemuxContext *s = s1->priv_data;
253     int len, max_packet_size;
254
255     max_packet_size = s->max_payload_size;
256
257     while (size > 0) {
258         len = max_packet_size;
259         if (len > size)
260             len = size;
261
262         s->timestamp = s->cur_timestamp;
263         ff_rtp_send_data(s1, buf1, len, (len == size));
264
265         buf1 += len;
266         size -= len;
267     }
268 }
269
270 /* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
271 static void rtp_send_mpegts_raw(AVFormatContext *s1,
272                                 const uint8_t *buf1, int size)
273 {
274     RTPDemuxContext *s = s1->priv_data;
275     int len, out_len;
276
277     while (size >= TS_PACKET_SIZE) {
278         len = s->max_payload_size - (s->buf_ptr - s->buf);
279         if (len > size)
280             len = size;
281         memcpy(s->buf_ptr, buf1, len);
282         buf1 += len;
283         size -= len;
284         s->buf_ptr += len;
285
286         out_len = s->buf_ptr - s->buf;
287         if (out_len >= s->max_payload_size) {
288             ff_rtp_send_data(s1, s->buf, out_len, 0);
289             s->buf_ptr = s->buf;
290         }
291     }
292 }
293
294 /* write an RTP packet. 'buf1' must contain a single specific frame. */
295 static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
296 {
297     RTPDemuxContext *s = s1->priv_data;
298     AVStream *st = s1->streams[0];
299     int rtcp_bytes;
300     int size= pkt->size;
301     uint8_t *buf1= pkt->data;
302
303 #ifdef DEBUG
304     printf("%d: write len=%d\n", pkt->stream_index, size);
305 #endif
306
307     /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
308     rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
309         RTCP_TX_RATIO_DEN;
310     if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
311                            (ntp_time() - s->last_rtcp_ntp_time > 5000000))) {
312         rtcp_send_sr(s1, ntp_time());
313         s->last_octet_count = s->octet_count;
314         s->first_packet = 0;
315     }
316     s->cur_timestamp = s->base_timestamp + pkt->pts;
317
318     switch(st->codec->codec_id) {
319     case CODEC_ID_PCM_MULAW:
320     case CODEC_ID_PCM_ALAW:
321     case CODEC_ID_PCM_U8:
322     case CODEC_ID_PCM_S8:
323         rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
324         break;
325     case CODEC_ID_PCM_U16BE:
326     case CODEC_ID_PCM_U16LE:
327     case CODEC_ID_PCM_S16BE:
328     case CODEC_ID_PCM_S16LE:
329         rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
330         break;
331     case CODEC_ID_MP2:
332     case CODEC_ID_MP3:
333         rtp_send_mpegaudio(s1, buf1, size);
334         break;
335     case CODEC_ID_MPEG1VIDEO:
336     case CODEC_ID_MPEG2VIDEO:
337         ff_rtp_send_mpegvideo(s1, buf1, size);
338         break;
339     case CODEC_ID_AAC:
340         ff_rtp_send_aac(s1, buf1, size);
341         break;
342     case CODEC_ID_MPEG2TS:
343         rtp_send_mpegts_raw(s1, buf1, size);
344         break;
345     case CODEC_ID_H264:
346         ff_rtp_send_h264(s1, buf1, size);
347         break;
348     default:
349         /* better than nothing : send the codec raw data */
350         rtp_send_raw(s1, buf1, size);
351         break;
352     }
353     return 0;
354 }
355
356 AVOutputFormat rtp_muxer = {
357     "rtp",
358     "RTP output format",
359     NULL,
360     NULL,
361     sizeof(RTPDemuxContext),
362     CODEC_ID_PCM_MULAW,
363     CODEC_ID_NONE,
364     rtp_write_header,
365     rtp_write_packet,
366 };